1 19 package org.netbeans.modules.java.source.usages; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.OutputStream ; 27 import java.net.MalformedURLException ; 28 import java.net.URISyntaxException ; 29 import java.net.URL ; 30 import java.util.HashMap ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.Properties ; 34 import java.util.Set ; 35 import org.netbeans.api.java.source.ClassIndex; 36 import org.openide.ErrorManager; 37 import org.openide.filesystems.FileUtil; 38 39 43 public abstract class Index { 44 45 public enum BooleanOperator { 46 AND, 47 OR 48 }; 49 50 private static final int VERSION = 0; 51 private static final int SUBVERSION = 1; 52 private static final String NB_USER_DIR = "netbeans.user"; private static final String SEGMENTS_FILE = "segments"; private static final String CLASSES = "classes"; private static final String SLICE_PREFIX = "s"; private static final String INDEX_DIR = "var"+File.separatorChar+"cache"+File.separatorChar+"index"+File.separatorChar+VERSION+'.'+SUBVERSION; 58 private static Properties segments; 59 private static Map <String , String > invertedSegments; 60 private static File cacheFolder; 61 private static File segmentsFile; 62 private static int index = 0; 63 64 public abstract boolean isValid (boolean tryOpen) throws IOException ; 65 public abstract List <String > getUsagesData (String resourceName, Set <ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException ; 66 public abstract List <String > getUsagesFQN (String resourceName, Set <ClassIndexImpl.UsageType> mask, BooleanOperator operator) throws IOException ; 67 public abstract List <String > getReferencesData (String resourceName) throws IOException ; 68 public abstract <T> void getDeclaredTypes (String simpleName, ClassIndex.NameKind kind, ResultConvertor<T> convertor, Set <? super T> result) throws IOException ; 69 public abstract void getPackageNames (String prefix, boolean directOnly, Set <String > result) throws IOException ; 70 public abstract void store (Map <String ,List <String >> refs, Set <String > toDelete) throws IOException ; 71 public abstract void store (Map <String ,List <String >> refs, List <String > topLevels) throws IOException ; 72 public abstract boolean isUpToDate (String resourceName, long timeStamp) throws IOException ; 73 public abstract void clear () throws IOException ; 74 public abstract void close () throws IOException ; 75 76 77 private static void loadSegments () throws IOException { 78 if (segments == null) { 79 File cacheFolder = getCacheFolder(); 80 assert cacheFolder != null; 81 segments = new Properties (); 82 invertedSegments = new HashMap <String ,String > (); 83 segmentsFile = FileUtil.normalizeFile(new File (cacheFolder, SEGMENTS_FILE)); 84 if (segmentsFile.exists()) { 85 InputStream in = new FileInputStream (segmentsFile); 86 try { 87 segments.load (in); 88 } finally { 89 in.close(); 90 } 91 } 92 for (Map.Entry entry : segments.entrySet()) { 93 String segment = (String ) entry.getKey(); 94 String root = (String ) entry.getValue(); 95 invertedSegments.put(root,segment); 96 try { 97 index = Math.max (index,Integer.parseInt(segment.substring(SLICE_PREFIX.length()))); 98 } catch (NumberFormatException nfe) { 99 ErrorManager.getDefault().notify(nfe); 100 } 101 } 102 assert segmentsFile != null; 103 } 104 } 105 106 107 private static void storeSegments () throws IOException { 108 assert segmentsFile != null; 109 OutputStream out = new FileOutputStream (segmentsFile); 110 try { 111 segments.store(out,null); 112 } finally { 113 out.close(); 114 } 115 } 116 117 118 public static URL getSourceRootForClassFolder (final URL classFolder) { 119 if ("file".equals(classFolder.getProtocol())) { try { 121 final File file = FileUtil.normalizeFile(new File (classFolder.toURI())); 122 final File segFolder = file.getParentFile(); 123 if (segFolder == null) { 124 return null; 125 } 126 final Object cFolder = segFolder.getParentFile(); 127 if (cFolder == null || !cFolder.equals(cacheFolder)) { 128 return null; 129 } 130 String source = segments.getProperty(segFolder.getName()); 131 if (source != null) { 132 try { 133 return new URL (source); 134 } catch (IOException ioe) { 135 ErrorManager.getDefault().notify(ioe); 136 } 137 } 138 } catch (URISyntaxException e) { 139 ErrorManager.getDefault().notify(e); 140 } 141 } 142 return null; 143 } 144 145 146 public static synchronized File getDataFolder (final URL root) throws IOException { 147 loadSegments (); 148 final String rootName = root.toExternalForm(); 149 String slice = invertedSegments.get (rootName); 150 if ( slice == null) { 151 slice = SLICE_PREFIX + (++index); 152 while (segments.getProperty(slice) != null) { 153 slice = SLICE_PREFIX + (++index); 154 } 155 segments.put (slice,rootName); 156 invertedSegments.put(rootName, slice); 157 storeSegments (); 158 } 159 File result = FileUtil.normalizeFile (new File (cacheFolder, slice)); 160 if (!result.exists()) { 161 result.mkdir(); 162 } 163 return result; 164 } 165 166 public static File getClassFolder (final URL url) throws IOException { 167 return getClassFolderImpl(url); 168 } 169 170 public static File getClassFolder (final File root) throws IOException { 171 try { 172 return getClassFolderImpl(root.toURI().toURL()); 173 } catch (MalformedURLException mue) { 174 ErrorManager.getDefault().notify (mue); 175 return null; 176 } 177 } 178 179 private static File getClassFolderImpl (final URL url) throws IOException { 180 final File dataFolder = getDataFolder (url); 181 final File result= new File (dataFolder, CLASSES); 182 if (!result.exists()) { 183 result.mkdir(); 184 } 185 return result; 186 } 187 188 private static synchronized File getCacheFolder () { 189 if (cacheFolder == null) { 190 final String nbUserProp = System.getProperty(NB_USER_DIR); 191 assert nbUserProp != null; 192 final File nbUserDir = new File (nbUserProp); 193 cacheFolder = FileUtil.normalizeFile(new File (nbUserDir, INDEX_DIR)); 194 if (!cacheFolder.exists()) { 195 boolean created = cacheFolder.mkdirs(); 196 assert created : "Cannot create cache folder"; } 198 else { 199 assert cacheFolder.isDirectory() && cacheFolder.canRead() && cacheFolder.canWrite(); 200 } 201 } 202 return cacheFolder; 203 } 204 205 209 static synchronized void setCacheFolder (final File folder) { 210 assert folder != null && folder.exists() && folder.canRead() && folder.canWrite(); 211 cacheFolder = folder; 212 } 213 214 } 215 | Popular Tags |