001    /*
002     * $Id: ClassWalker.java,v 1.4 2011/06/29 19:16:43 oboehm Exp $
003     *
004     * Copyright (c) 2009 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     *
018     * (c)reated 14.04.2009 by oliver (ob@aosd.de)
019     */
020    package patterntesting.runtime.monitor;
021    
022    import java.io.*;
023    import java.util.*;
024    
025    import org.apache.commons.io.*;
026    import org.apache.commons.io.filefilter.*;
027    
028    import patterntesting.runtime.util.Converter;
029    
030    /**
031     * The Class ClassWalker.
032     *
033     * @author <a href="boehm@javatux.de">oliver</a>
034     * @since 14.04.2009
035     * @version $Revision: 1.4 $
036     */
037    public final class ClassWalker extends DirectoryWalker {
038    
039        private final File startDir;
040        private final int startDirnameLength;
041    
042        /**
043         * Instantiates a new class walker.
044         *
045         * @param dir the dir
046         */
047        public ClassWalker(final File dir) {
048            super(getFileFilter(), -1);
049            this.startDir = dir;
050            this.startDirnameLength = FilenameUtils
051                    .normalizeNoEndSeparator(dir.getAbsolutePath()).length();
052        }
053    
054        /**
055         * Use all directories which are not hidden and files which end in
056         * ".class".
057         *
058         * @return FileFilter for the walk method
059         * @{link "http://commons.apache.org/io/api-release/org/apache/commons/io/DirectoryWalker.html"}
060         */
061        private static FileFilter getFileFilter() {
062            IOFileFilter dirFilter = FileFilterUtils.andFileFilter(FileFilterUtils
063                    .directoryFileFilter(), HiddenFileFilter.VISIBLE);
064            IOFileFilter fileFilter =
065            FileFilterUtils.andFileFilter(FileFilterUtils.fileFileFilter(),
066                                          FileFilterUtils.suffixFileFilter(".class"));
067            return FileFilterUtils.orFileFilter(dirFilter, fileFilter);
068        }
069    
070        /**
071         * Walk thru the directories and return all class files as classname,
072         * e.g. a file java/lang/String.class should be returned as
073         * "java.lang.String".
074         *
075         * @return a collection of classnames
076         *
077         * @throws IOException Signals that an I/O exception has occurred.
078         *
079         * @{link "http://commons.apache.org/io/api-release/org/apache/commons/io/DirectoryWalker.html"}
080         */
081        public Collection<String> getClasses() throws IOException {
082            Collection<String> classes = new TreeSet<String>();
083            walk(startDir, classes);
084            return classes;
085        }
086    
087        /**
088         * @see org.apache.commons.io.DirectoryWalker#handleFile(java.io.File, int, java.util.Collection)
089         */
090        @SuppressWarnings({"unchecked", "rawtypes"})
091        @Override
092        protected void handleFile(final File file, final int depth, final Collection results)
093                throws IOException {
094            String absFilename = FilenameUtils.normalize(file.getAbsolutePath());
095            String relFilename = absFilename.substring(startDirnameLength+1);
096            String classname = Converter.resourceToClass(relFilename);
097            results.add(classname);
098        }
099    
100    }