Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.util;
  
  import java.io.File;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
 import java.util.Set;
Instances of JarCache provides jar index information.

Implementation is threadsafe. Since loading index information is O(jar-entries) we cache the snapshot in a WeakHashMap. The implementation pays attention to lastModified timestamp of the jar and will invalidate the cache entry if jar has been updated since the snapshot calculation.

 
 class JarCache {
     static class JarIndex {
         private static final String ROOT_KEY = "";
 
         final Map<StringString[]> cachedDirEntries;
         final JarFile jar;
         final long snapshotCalculated;
 
         JarIndex(String jarPaththrows IOException {
             this. = new JarFile(jarPath);
             this. = new File(jarPath).lastModified();
 
             Map<StringSet<String>> mutableCache = new HashMap<StringSet<String>>();
 
             // Always have a root directory
             mutableCache.put(new HashSet<String>());
 
             Enumeration<JarEntryentries = .entries();
             while (entries.hasMoreElements()) {
                 JarEntry entry = entries.nextElement();
                 String path = entry.getName();
 
                 int lastPathSep;
                 while ((lastPathSep = path.lastIndexOf('/')) != -1) {
                     String dirPath = path.substring(0, lastPathSep); 
 
                     if (!mutableCache.containsKey(dirPath)) {
                         mutableCache.put(dirPathnew HashSet<String>());
                     }
 
                     String entryPath = path.substring(lastPathSep + 1);
 
                     // "" is not really a child path, even if we see foo/ entry
                     if (entryPath.length() > 0) {
                         mutableCache.get(dirPath).add(entryPath);
                     }
 
                     path = dirPath;
                 }
 
                 mutableCache.get().add(path);
             }
 
             Map<StringString[]> cachedDirEntries = new HashMap<StringString[]>();
             for (Map.Entry<StringSet<String>> entry : mutableCache.entrySet()) {
                 cachedDirEntries.put(entry.getKey(), entry.getValue().toArray(new String[0]));
             }
 
             this. = Collections.unmodifiableMap(cachedDirEntries);
         }
 
         public JarEntry getJarEntry(String entryPath) {
             return .getJarEntry(entryPath);
         }
 
         public void release() {
             try {
                 .close();
             } catch (IOException ioe) { }
         }
 
         public boolean isValid() {
             return new File(.getName()).lastModified() <= ;
         }
     }
 
     private final Map<StringJarIndexindexCache = new WeakHashMap<StringJarIndex>();
 
     public JarIndex getIndex(String jarPath) {
         String cacheKey = jarPath;
 
         synchronized () {
             JarIndex index = .get(cacheKey);
            // If the index is invalid (jar has changed since snapshot was loaded)
            // we can just treat it as a "new" index and cache the updated results.
            if (index != null && !index.isValid()) {
                index.release();
                index = null;
            }
            if (index == null) {
                try { 
                    index = new JarIndex(jarPath);
                    .put(cacheKeyindex);
                } catch (IOException ioe) {
                    return null;
                }
            }
            return index;
        }
    }
New to GrepCode? Check out our FAQ X