// see ScanDirConfigMXBean public DirectoryScannerConfig addDirectoryScanner( String name, String dir, String filePattern, long sizeExceedsMaxBytes, long sinceLastModified) { final DirectoryScannerConfig scanner = new DirectoryScannerConfig(name); scanner.setRootDirectory(dir); if (filePattern != null || sizeExceedsMaxBytes > 0 || sinceLastModified > 0) { final FileMatch filter = new FileMatch(); filter.setFilePattern(filePattern); filter.setSizeExceedsMaxBytes(sizeExceedsMaxBytes); if (sinceLastModified > 0) filter.setLastModifiedBefore(new Date(new Date().getTime() - sinceLastModified)); scanner.addIncludeFiles(filter); } synchronized (this) { config.putScan(scanner); status = MODIFIED; } LOG.fine("config: " + config); sendNotification(NOTIFICATION_MODIFIED); return scanner; }
/** * Constructs a new {@code DirectoryScanner}. * * <p>This constructor is package protected, and this MBean cannot be created by a remote client, * because it needs a reference to the {@link ResultLogManager}, which cannot be provided from * remote. * * <p>This is a conscious design choice: {@code DirectoryScanner} MBeans are expected to be * completely managed (created, registered, unregistered) by the {@link ScanManager} which does * provide this reference. * * @param config This {@code DirectoryScanner} configuration. * @param logManager The info log manager with which to log the info records. * @throws IllegalArgumentException if one of the parameter is null, or if the provided {@code * config} doesn't have its {@code name} set, or if the {@link * DirectoryScannerConfig#getRootDirectory root directory} provided in the {@code config} is * not acceptable (not provided or not found or not readable, etc...). */ public DirectoryScanner(DirectoryScannerConfig config, ResultLogManager logManager) throws IllegalArgumentException { if (logManager == null) throw new IllegalArgumentException("log=null"); if (config == null) throw new IllegalArgumentException("config=null"); if (config.getName() == null) throw new IllegalArgumentException("config.name=null"); broadcaster = new NotificationBroadcasterSupport(); // Clone the config: ensure data encapsulation. // this.config = XmlConfigUtils.xmlClone(config); // Checks that the provided root directory is valid. // Throws IllegalArgumentException if it isn't. // rootFile = validateRoot(config.getRootDirectory()); // Initialize the Set<Action> for which this DirectoryScanner // is configured. // if (config.getActions() == null) actions = Collections.emptySet(); else actions = EnumSet.copyOf(Arrays.asList(config.getActions())); this.logManager = logManager; }
// The actual scan logic. Switches state to RUNNING, // and scan the list of given dirs. // The list is a live object which is updated by this method. // This would allow us to implement methods like "pause" and "resume", // since all the info needed to resume would be in the list. // private void scan(ScanTask task, LinkedList<File> list) { setStateAndNotify(RUNNING); task.info = "In Progress"; try { // The FileFilter will tell us which files match and which don't. // final FileFilter filter = config.buildFileFilter(); // We have two condition to end the loop: either the list is // empty, meaning there's nothing more to scan, or the state of // the DirectoryScanner was asynchronously switched to STOPPED by // another thread, e.g. because someone called "stop" on the // ScanManagerMXBean // while (!list.isEmpty() && state == RUNNING) { // Get and remove the first element in the list. // final File current = list.poll(); // Increment number of file scanned. task.scanned++; // If 'current' is a file, it's already been matched by our // file filter (see below): act on it. // Note that for the first iteration of this loop, there will // be one single file in the list: the root directory for this // scanner. // if (current.isFile()) { task.matching++; actOn(current); } // If 'current' is a directory, then // find files and directories that match the file filter // in this directory // if (current.isDirectory()) { // Gets matching files and directories final File[] content = current.listFiles(filter); if (content == null) continue; // Adds all matching file to the list. list.addAll(0, Arrays.asList(content)); } } // The loop terminated. If the list is empty, then we have // completed our task. If not, then somebody must have called // stop() on this directory scanner. // if (list.isEmpty()) { task.info = "Successfully Completed"; setStateAndNotify(COMPLETED); } } catch (Exception x) { // We got an exception: stop the scan // task.info = "Failed: " + x; if (LOG.isLoggable(Level.FINEST)) LOG.log(Level.FINEST, "scan task failed: " + x, x); else if (LOG.isLoggable(Level.FINE)) LOG.log(Level.FINE, "scan task failed: " + x); setStateAndNotify(STOPPED); } catch (Error e) { // We got an Error: // Should not happen unless we ran out of memory or // whatever - don't even try to notify, but // stop the scan anyway! // state = STOPPED; task.info = "Error: " + e; // rethrow error. // throw e; } }