1 19 package org.netbeans.modules.retouche.source.usages; 20 21 import java.io.BufferedInputStream ; 22 import java.io.BufferedOutputStream ; 23 import java.io.BufferedWriter ; 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.FileInputStream ; 27 import java.io.FileOutputStream ; 28 import java.io.FileOutputStream ; 29 import java.io.FileWriter ; 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.io.OutputStream ; 33 import java.net.MalformedURLException ; 34 import java.net.URISyntaxException ; 35 import java.net.URL ; 36 import java.util.HashMap ; 37 import java.util.List ; 38 import java.util.Map ; 39 import java.util.Properties ; 40 import java.util.Set ; 41 import java.util.zip.ZipEntry ; 42 import java.util.zip.ZipInputStream ; 43 import java.util.zip.ZipOutputStream ; 44 import org.netbeans.api.retouche.source.ClassIndex; 45 import org.openide.ErrorManager; 46 import org.openide.filesystems.FileLock; 47 import org.openide.filesystems.FileObject; 48 import org.openide.filesystems.FileSystem; 49 import org.openide.filesystems.FileUtil; 50 import org.openide.filesystems.FileUtil; 51 import org.openide.filesystems.URLMapper; 52 import org.openide.util.Exceptions; 53 54 63 public abstract class Index extends org.netbeans.api.gsf.Index { 65 67 public enum BooleanOperator { 68 AND, 69 OR 70 }; 71 72 private static final int VERSION = 0; 73 private static final int SUBVERSION = 105; 74 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+"gsf-index"+File.separatorChar+VERSION+'.'+SUBVERSION; protected static final String PREINDEXED = "preindexed-" + VERSION + '.' + SUBVERSION; private static final String PREINDEXED_MARKER = "preindexed"; 82 84 private static Properties segments; 85 private static Map <String , String > invertedSegments; 86 private static File cacheFolder; 87 private static File segmentsFile; 88 private static int index = 0; 89 90 public abstract boolean isValid (boolean tryOpen) throws IOException ; 91 public abstract boolean isUpToDate (String resourceName, long timeStamp) throws IOException ; 92 public abstract void clear () throws IOException ; 93 public abstract void close () throws IOException ; 94 95 96 private static void loadSegments () throws IOException { 97 if (segments == null) { 98 File cacheFolder = getCacheFolder(); 99 assert cacheFolder != null; 100 segments = new Properties (); 101 invertedSegments = new HashMap <String ,String > (); 102 segmentsFile = FileUtil.normalizeFile(new File (cacheFolder, SEGMENTS_FILE)); 103 if (segmentsFile.exists()) { 104 InputStream in = new FileInputStream (segmentsFile); 105 try { 106 segments.load (in); 107 } finally { 108 in.close(); 109 } 110 } 111 for (Map.Entry entry : segments.entrySet()) { 112 String segment = (String ) entry.getKey(); 113 String root = (String ) entry.getValue(); 114 invertedSegments.put(root,segment); 115 try { 116 index = Math.max (index,Integer.parseInt(segment.substring(SLICE_PREFIX.length()))); 117 } catch (NumberFormatException nfe) { 118 ErrorManager.getDefault().notify(nfe); 119 } 120 } 121 assert segmentsFile != null; 122 } 123 } 124 125 126 private static void storeSegments () throws IOException { 127 assert segmentsFile != null; 128 OutputStream out = new FileOutputStream (segmentsFile); 129 try { 130 segments.store(out,null); 131 } finally { 132 out.close(); 133 } 134 } 135 136 137 public static URL getSourceRootForClassFolder (final URL classFolder) { 138 if ("file".equals(classFolder.getProtocol())) { try { 140 final File file = FileUtil.normalizeFile(new File (classFolder.toURI())); 141 final File segFolder = file.getParentFile(); 142 if (segFolder == null) { 143 return null; 144 } 145 final Object cFolder = segFolder.getParentFile(); 146 if (cFolder == null || !cFolder.equals(cacheFolder)) { 147 return null; 148 } 149 String source = segments.getProperty(segFolder.getName()); 150 if (source != null) { 151 try { 152 return new URL (source); 153 } catch (IOException ioe) { 154 ErrorManager.getDefault().notify(ioe); 155 } 156 } 157 } catch (URISyntaxException e) { 158 ErrorManager.getDefault().notify(e); 159 } 160 } 161 return null; 162 } 163 164 165 public static synchronized File getDataFolder (final URL root) throws IOException { 166 loadSegments (); 167 final String rootName = root.toExternalForm(); 168 String slice = invertedSegments.get (rootName); 169 FileObject extract = null; 171 if ( slice == null) { 173 slice = SLICE_PREFIX + (++index); 174 while (segments.getProperty(slice) != null) { 175 slice = SLICE_PREFIX + (++index); 176 } 177 segments.put (slice,rootName); 178 invertedSegments.put(rootName, slice); 179 180 FileObject rootFo = URLMapper.findFileObject(root); 183 if (rootFo != null) { 184 extract = rootFo.getFileObject(PREINDEXED, "zip"); } 186 188 storeSegments (); 189 } 190 File result = FileUtil.normalizeFile (new File (cacheFolder, slice)); 191 if (!result.exists()) { 192 result.mkdir(); 193 if (extract != null) { 195 File extractFile = FileUtil.toFile(extract); 196 FileObject dest = FileUtil.toFileObject(result); 197 if (dest != null) { 198 extractZip(dest, new BufferedInputStream (new FileInputStream (extractFile))); 199 } 200 } 201 } 203 return result; 204 } 205 206 static boolean isPreindexed(File dataDir) { 208 return new File (dataDir, PREINDEXED_MARKER).exists(); } 210 211 private static void extractZip(final FileObject fo, final InputStream is) 213 throws IOException { 214 FileSystem fs = fo.getFileSystem(); 215 216 fs.runAtomicAction( 217 new FileSystem.AtomicAction() { 218 public void run() throws IOException { 219 extractZipImpl(fo, is); 220 } 221 } 222 ); 223 } 224 225 227 private static void extractZipImpl(FileObject fo, InputStream is) 229 throws IOException { 230 ZipEntry je; 231 232 ZipInputStream jis = new ZipInputStream (is); 233 234 while ((je = jis.getNextEntry()) != null) { 235 String name = je.getName(); 236 237 if (name.toLowerCase().startsWith("meta-inf/")) { 238 continue; } 240 241 if (je.isDirectory()) { 242 FileUtil.createFolder(fo, name); 243 244 continue; 245 } 246 247 FileObject fd = FileUtil.createData(fo, name); 249 FileLock lock = fd.lock(); 250 251 try { 252 OutputStream os = fd.getOutputStream(lock); 253 254 try { 255 FileUtil.copy(jis, os); 256 } finally { 257 os.close(); 258 } 259 } finally { 260 lock.releaseLock(); 261 } 262 } 263 } 264 265 static void preindex(URL root) { 267 try { 268 FileObject rootFo = URLMapper.findFileObject(root); 269 File dataFile = Index.getDataFolder(root); 270 273 File output = new File (FileUtil.toFile(rootFo), PREINDEXED + ".zip"); OutputStream os = new BufferedOutputStream (new FileOutputStream (output)); 275 276 ZipEntry je; 277 278 ZipOutputStream jis = new ZipOutputStream (os); 279 280 je = new ZipEntry (PREINDEXED_MARKER); 281 jis.putNextEntry(je); 282 jis.closeEntry(); 283 284 File gsf = new File (dataFile, LuceneIndex.REFERENCES); assert gsf.exists(); 286 287 File [] files = gsf.listFiles(); 288 for (File f : files) { 289 ZipEntry ze = new ZipEntry (LuceneIndex.REFERENCES + "/" + f.getName()); jis.putNextEntry(ze); 291 292 InputStream is = new BufferedInputStream (new FileInputStream (f)); 294 FileUtil.copy(is, jis); 295 296 jis.closeEntry(); 297 } 298 299 jis.finish(); 300 jis.close(); 301 } catch (IOException ioe) { 302 Exceptions.printStackTrace(ioe); 303 } 304 } 305 307 public static File getClassFolder (final URL url) throws IOException { 308 return getClassFolderImpl(url); 309 } 310 311 public static File getClassFolder (final File root) throws IOException { 312 try { 313 return getClassFolderImpl(root.toURI().toURL()); 314 } catch (MalformedURLException mue) { 315 ErrorManager.getDefault().notify (mue); 316 return null; 317 } 318 } 319 320 private static File getClassFolderImpl (final URL url) throws IOException { 321 final File dataFolder = getDataFolder (url); 322 final File result= new File (dataFolder, CLASSES); 323 if (!result.exists()) { 324 result.mkdir(); 325 } 326 return result; 327 } 328 329 private static synchronized File getCacheFolder () { 330 if (cacheFolder == null) { 331 final String nbUserProp = System.getProperty(NB_USER_DIR); 332 assert nbUserProp != null; 333 final File nbUserDir = new File (nbUserProp); 334 cacheFolder = FileUtil.normalizeFile(new File (nbUserDir, INDEX_DIR)); 335 if (!cacheFolder.exists()) { 336 boolean created = cacheFolder.mkdirs(); 337 assert created : "Cannot create cache folder"; } 339 else { 340 assert cacheFolder.isDirectory() && cacheFolder.canRead() && cacheFolder.canWrite(); 341 } 342 } 343 return cacheFolder; 344 } 345 346 350 static synchronized void setCacheFolder (final File folder) { 351 assert folder != null && folder.exists() && folder.canRead() && folder.canWrite(); 352 cacheFolder = folder; 353 } 354 355 } 356 | Popular Tags |