org.hyperic.util.file.match.MatcherScanner.java Source code

Java tutorial

Introduction

Here is the source code for org.hyperic.util.file.match.MatcherScanner.java

Source

/*
 * NOTE: This copyright does *not* cover user programs that use HQ
 * program services by normal system calls through the application
 * program interfaces provided as part of the Hyperic Plug-in Development
 * Kit or the Hyperic Client Development Kit - this is merely considered
 * normal use of the program, and does *not* fall under the heading of
 * "derived work".
 * 
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of HQ.
 * 
 * HQ is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

package org.hyperic.util.file.match;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.Map;

import org.apache.commons.logging.Log;

import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.selectors.FileSelector;
import org.apache.tools.ant.util.FileUtils;

class MatcherScanner extends DirectoryScanner {

    private int maxDepth;
    private Log log;
    private MatcherInterruptCallback interruptCB = null;
    private MatcherProgressCallback progressCB = null;
    private Map matches;
    private List errors;
    private boolean myFollowSymlinks = false;
    private static final FileUtils myFileUtils = FileUtils.newFileUtils();
    private int pauseCounter = 0;

    public MatcherScanner() {
        super();
        errors = new ArrayList();
    }

    public void initMatches(Map matches) {
        this.matches = matches;
    }

    public List getErrors() {
        return errors;
    }

    public void addError(Exception e) {
        errors.add(e);
    }

    public void setMaxDepth(int max) {
        maxDepth = max;
    }

    public Log getLog() {
        return this.log;
    }

    public void setLog(Log log) {
        this.log = log;
    }

    public void setMatcherInterruptCB(MatcherInterruptCallback icb) {
        interruptCB = icb;
    }

    public void setMatcherProgressCB(MatcherProgressCallback pcb) {
        progressCB = pcb;
    }

    protected void addMatch(Object key, String fullpath) {
        // System.err.println("MS--->addMatch(" + key + ", " + fullpath + ")");
        List existingList = (List) matches.get(key);
        if (existingList == null) {
            existingList = new ArrayList();
            matches.put(key, existingList);
        }
        existingList.add(fullpath);
    }

    public Map getMatches() {
        return matches;
    }

    public void setSelectors(FileSelector[] selectors) {
        super.setSelectors(selectors);
        for (int i = 0; i < selectors.length; i++) {
            if (selectors[i] instanceof MatchSelector) {
                ((MatchSelector) selectors[i]).setMatcherScanner(this);
            }
        }
    }

    public void setFollowSymlinks(boolean followSymlinks) {
        this.myFollowSymlinks = followSymlinks;
        super.setFollowSymlinks(followSymlinks);
    }

    public void doScan() throws MatcherInterruptedException {
        checkInterrupted();
        for (int i = 0; i < selectors.length; i++) {
            if (selectors[i] instanceof MasterMatchSelector) {
                ((MasterMatchSelector) selectors[i]).setScanner(this);
            }
        }
        super.scan();
    }

    private void checkInterrupted() throws MatcherInterruptedException {
        if (interruptCB != null) {
            if (interruptCB.getIsInterrupted()) {
                throw new MatcherInterruptedException();
            }
        } else {
            // Just check for thread interruption
            if (Thread.currentThread().isInterrupted()) {
                throw new MatcherInterruptedException();
            }
        }
    }

    /** Override default implementation to track dir depth */
    protected void scandir(File dir, String vpath, boolean fast) {
        pauseCounter = 0;
        scandir(dir, vpath, 0);
    }

    private void pause() {
        if (++pauseCounter % 25 == 0) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException ie) {
                throw new MatcherInterruptedException();
            }
        }
    }

    protected void scandir(File dir, String vpath, int depth) {

        // This is just here to ensure that our scanning doesn't spin-up
        // the CPU.  We sleep briefly every few directories to give other
        // processes a chance to run.
        pause();

        if (depth > maxDepth && maxDepth != -1) {
            if (log != null) {
                //log.info("scandir: Skipping dir " + dir.getAbsolutePath() 
                //         + " and all subdirs because they are below our "
                //         + "maxDepth of " + maxDepth);
            }
            return;

        } else {
            checkInterrupted();
            if (isExcluded(dir.getAbsolutePath())) {
                //log.info("scandir: Skipping: " + dir.getAbsolutePath() 
                //         + " because it is explicitly excluded from scan.");
                return;
            }
        }

        if (!dir.canRead()) {
            errors.add(new MatcherException(
                    "Don't have permissions to read " + "directory: " + dir.getAbsolutePath()));
            return;
        }
        String[] newfiles = dir.list();

        if (newfiles == null) {
            /*
             * two reasons are mentioned in the API docs for File.list
             * (1) dir is not a directory. This is impossible as
             *     we wouldn't get here in this case.
             * (2) an IO error occurred (why doesn't it throw an exception
             *     then???)
             */
            errors.add(new MatcherException("IO error scanning directory " + dir.getAbsolutePath()));
            return;
        }

        // log.debug("scandir: Scanning: " + dir.getAbsolutePath());

        // Tell someone how our scan is progressing...
        if (progressCB != null)
            progressCB.notifyScanDir(dir);

        if (!myFollowSymlinks) {
            Vector noLinks = new Vector();
            for (int i = 0; i < newfiles.length; i++) {
                checkInterrupted();
                try {
                    if (myFileUtils.isSymbolicLink(dir, newfiles[i])) {
                        String name = vpath + newfiles[i];
                        File file = new File(dir, newfiles[i]);
                        if (file.isDirectory()) {
                            dirsExcluded.addElement(name);
                        } else {
                            filesExcluded.addElement(name);
                        }
                    } else {
                        noLinks.addElement(newfiles[i]);
                    }
                } catch (IOException ioe) {
                    String msg = "IOException caught while checking " + "for links, couldn't get canonical path!";
                    // will be caught and redirected to Ant's logging system
                    errors.add(new MatcherException(msg, ioe));
                }
            }
            newfiles = new String[noLinks.size()];
            noLinks.copyInto(newfiles);
        }

        for (int i = 0; i < newfiles.length; i++) {
            checkInterrupted();
            pause();
            String name = vpath + newfiles[i];
            File file = new File(dir, newfiles[i]);
            if (file.isDirectory()) {
                if (isIncluded(name)) {
                    if (!isExcluded(name)) {
                        // log.info("scandir: checking isSelected(" + name + "," + file.getAbsolutePath() + ")");
                        if (isSelected(name, file)) {
                            continue;
                        } else {
                            if (/*fast &&*/ couldHoldIncluded(name)) {
                                scandir(file, name + File.separator, depth + 1);
                            }
                        }

                    } else {
                        if (/*fast &&*/ couldHoldIncluded(name)) {
                            scandir(file, name + File.separator, depth + 1);
                        }
                    }
                } else {
                    if (/*fast &&*/ couldHoldIncluded(name)) {
                        scandir(file, name + File.separator, depth + 1);
                    }
                }
                // if (!fast) {
                //     scandir(file, name + File.separator, fast);
                // }
            } else if (file.isFile()) {
                if (isIncluded(name)) {
                    if (!isExcluded(name)) {
                        if (isSelected(name, file)) {
                            continue;
                        } else {
                            // everythingIncluded = false;
                            // filesDeselected.addElement(name);
                        }
                    } else {
                        // everythingIncluded = false;
                        // filesExcluded.addElement(name);
                    }
                } else {
                    // everythingIncluded = false;
                    // filesNotIncluded.addElement(name);
                }
            }
        }
    }
}