001: package org.drools.agent;
002:
003: import java.io.File;
004: import java.io.FileInputStream;
005: import java.io.FileNotFoundException;
006: import java.io.IOException;
007: import java.io.ObjectInputStream;
008: import java.util.ArrayList;
009: import java.util.HashMap;
010: import java.util.List;
011: import java.util.Map;
012: import java.util.Properties;
013:
014: import org.drools.common.DroolsObjectInputStream;
015: import org.drools.rule.Package;
016:
017: /**
018: * This will monitor a file to a binary package.
019: * @author Michael Neale
020: *
021: */
022: public class FileScanner extends PackageProvider {
023:
024: File[] files;
025: Map lastUpdated = new HashMap();
026:
027: /**
028: * This sets the list of files to be monitored.
029: * This takes a list of paths and files (not directories).
030: */
031: void configure(Properties config) {
032: List paths = RuleAgent
033: .list(config.getProperty(RuleAgent.FILES));
034: files = new File[paths.size()];
035: for (int i = 0; i < paths.size(); i++) {
036: File file = new File((String) paths.get(i));
037: if (!file.exists()) {
038: throw new IllegalArgumentException("The file "
039: + file.getName() + " does not exist.");
040: }
041: files[i] = file;
042: }
043: }
044:
045: /**
046: * An alternative way to configure.
047: */
048: void setFiles(File[] files) {
049: this .files = files;
050: }
051:
052: /**
053: * Perform the scan.
054: * If there was an error reading the packages, this will not fail, it will
055: * just do nothing (as there may be a temporary IO issue).
056: */
057: Package[] loadPackageChanges() {
058: Package[] changes = getChangeSet();
059: return changes;
060: }
061:
062: /**
063: * Calculate a change set, based on last updated times.
064: * (keep a map of files).
065: * @throws ClassNotFoundException
066: * @throws IOException
067: * @throws FileNotFoundException
068: */
069: private Package[] getChangeSet() {
070: if (this .files == null)
071: return new Package[0];
072: List list = new ArrayList();
073: for (int i = 0; i < files.length; i++) {
074: File f = files[i];
075: if (hasChanged(f.getPath(), this .lastUpdated, f
076: .lastModified())) {
077: Package p = readPackage(f);
078: if (p == null)
079: return null;
080: list.add(p);
081: }
082: }
083: return (Package[]) list.toArray(new Package[list.size()]);
084: }
085:
086: /**
087: * If an exception occurs, it is noted, but ignored.
088: * Especially IO, as generally they are temporary.
089: */
090: private Package readPackage(File pkgFile) {
091:
092: Package p1_ = null;
093: ObjectInputStream in;
094: try {
095: in = new DroolsObjectInputStream(new FileInputStream(
096: pkgFile));
097: p1_ = (Package) in.readObject();
098: in.close();
099:
100: } catch (FileNotFoundException e) {
101: this .listener.exception(e);
102: this .listener.warning("Was unable to find the file "
103: + pkgFile.getPath());
104: } catch (IOException e) {
105: this .listener.exception(e);
106: } catch (ClassNotFoundException e) {
107: this .listener.exception(e);
108: this .listener
109: .warning("Was unable to load a class when loading a package. Perhaps it is missing from this application.");
110: }
111: return p1_;
112: }
113:
114: boolean hasChanged(String path, Map updates, long fileLastModified) {
115:
116: if (!updates.containsKey(path)) {
117: updates.put(path, new Long(fileLastModified));
118: return true;
119: } else {
120: Long last = (Long) updates.get(path);
121: if (last.longValue() < fileLastModified) {
122: updates.put(path, new Long(fileLastModified));
123: return true;
124: } else {
125: return false;
126: }
127: }
128:
129: }
130:
131: public String toString() {
132: StringBuffer buf = new StringBuffer();
133: buf.append("FileScanner scanning: ");
134: for (int i = 0; i < files.length; i++) {
135: File f = files[i];
136: buf.append(f.getPath() + " ");
137: }
138: return buf.toString();
139: }
140:
141: }
|