All Downloads are FREE. Search and download functionalities are using the official Maven repository.

play.classloading.hash.ClassStateHashCreator Maven / Gradle / Ivy

There is a newer version: 1.5.0
Show newest version
package play.classloading.hash;

import play.vfs.VirtualFile;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ClassStateHashCreator {

    private final Pattern classDefFinderPattern = Pattern.compile("\\s+class\\s([a-zA-Z0-9_]+)\\s+");

    private static class FileWithClassDefs {
        private final File file;
        private final long size;
        private final long lastModified;
        private final String classDefs;

        private FileWithClassDefs(File file, String classDefs) {
            this.file = file;
            this.classDefs = classDefs;

            // store size and time for this file..
            size = file.length();
            lastModified = file.lastModified();
        }

        /**
         * @return true if file has changed on disk
         */
        public boolean fileNotChanges( ) {
            return size == file.length() && lastModified == file.lastModified();
        }

        public String getClassDefs() {
            return classDefs;
        }
    }

    private final Map classDefsInFileCache = new HashMap();

    public synchronized int computePathHash(List paths) {
        StringBuffer buf = new StringBuffer();
        for (VirtualFile virtualFile : paths) {
            scan(buf, virtualFile);
        }
        // TODO: should use better hashing-algorithm.. MD5? SHA1?
        // I think hashCode() has too many collisions..
        return buf.toString().hashCode();
    }

    private void scan(StringBuffer buf, VirtualFile current) {
        if (!current.isDirectory()) {
            if (current.getName().endsWith(".java")) {
                buf.append( getClassDefsForFile(current));
            }
        } else if (!current.getName().startsWith(".")) {
            // TODO: we could later optimizie it further if we check if the entire folder is unchanged
            for (VirtualFile virtualFile : current.list()) {
                scan(buf, virtualFile);
            }
        }
    }

    private String getClassDefsForFile( VirtualFile current ) {

        File realFile = current.getRealFile();
        // first we look in cache

        FileWithClassDefs fileWithClassDefs = classDefsInFileCache.get( realFile );
        if( fileWithClassDefs != null && fileWithClassDefs.fileNotChanges() ) {
            // found the file in cache and it has not changed on disk
            return fileWithClassDefs.getClassDefs();
        }

        // didn't find it or it has changed on disk
        // we must re-parse it

        StringBuilder buf = new StringBuilder();
        Matcher matcher = classDefFinderPattern.matcher(current.contentAsString());
        buf.append(current.getName());
        buf.append("(");
        while (matcher.find()) {
            buf.append(matcher.group(1));
            buf.append(",");
        }
        buf.append(")");
        String classDefs = buf.toString();

        // store it in cache
        classDefsInFileCache.put( realFile, new FileWithClassDefs(realFile, classDefs));
        return classDefs;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy