1 19 20 package org.netbeans.modules.java.source.usages; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.lang.ref.WeakReference ; 25 import java.net.URL ; 26 import java.util.Collections ; 27 import java.util.List ; 28 import java.util.Set ; 29 import java.util.logging.Logger ; 30 import javax.lang.model.element.ElementKind; 31 import org.netbeans.api.java.queries.SourceForBinaryQuery; 32 import org.netbeans.api.java.source.CancellableTask; 33 import org.netbeans.api.java.source.ClassIndex; 34 import org.netbeans.api.java.source.CompilationController; 35 import org.netbeans.api.java.source.CompilationInfo; 36 import org.netbeans.api.java.source.JavaSource; 37 import org.netbeans.api.java.source.JavaSource.Phase; 38 import org.netbeans.modules.java.source.JavaSourceAccessor; 39 import static org.netbeans.modules.java.source.usages.ClassIndexImpl.UsageType.*; 40 import org.openide.filesystems.FileObject; 41 import org.openide.filesystems.URLMapper; 42 import org.openide.util.Exceptions; 43 import org.openide.util.Exceptions; 44 45 49 public class PersistentClassIndex extends ClassIndexImpl { 50 51 private final Index index; 52 private final URL root; 53 private final boolean isSource; 54 private WeakReference <JavaSource> dirty; 55 private static final Logger LOGGER = Logger.getLogger(PersistentClassIndex.class.getName()); 56 57 58 private PersistentClassIndex(final URL root, final File cacheRoot, final boolean source) 59 throws IOException , IllegalArgumentException { 60 assert root != null; 61 this.root = root; 62 this.index = LuceneIndex.create (cacheRoot); 63 this.isSource = source; 64 } 65 66 public BinaryAnalyser getBinaryAnalyser () { 67 return new BinaryAnalyser (this.index); 68 } 69 70 public SourceAnalyser getSourceAnalyser () { 71 return new SourceAnalyser (this.index); 72 } 73 74 public FileObject[] getSourceRoots () { 75 FileObject[] rootFos; 76 if (isSource) { 77 FileObject rootFo = URLMapper.findFileObject (this.root); 78 rootFos = rootFo == null ? new FileObject[0] : new FileObject[] {rootFo}; 79 } 80 else { 81 rootFos = SourceForBinaryQuery.findSourceRoots(this.root).getRoots(); 82 } 83 return rootFos; 84 } 85 86 87 89 public static ClassIndexImpl create(URL root, final File cacheRoot, final boolean indexNow) 90 throws IOException , IllegalArgumentException { 91 return new PersistentClassIndex(root, cacheRoot, indexNow); 92 } 93 94 public <T> void search (final String binaryName, final Set <UsageType> usageType, final ResultConvertor<T> convertor, final Set <? super T> result) { 96 updateDirty(); 97 if (BinaryAnalyser.OBJECT.equals(binaryName)) { 98 this.getDeclaredTypes("", ClassIndex.NameKind.PREFIX, convertor, result); 99 return; 100 } 101 try { 102 ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void > () { 103 public Void run () throws IOException { 104 usages(binaryName, usageType, convertor, result); 105 return null; 106 } 107 }); 108 } catch (IOException ioe) { 109 Exceptions.printStackTrace(ioe); 110 } 111 } 112 113 114 115 116 public <T> void getDeclaredTypes (final String simpleName, final ClassIndex.NameKind kind, final ResultConvertor<T> convertor, final Set <? super T> result) { 117 updateDirty(); 118 try { 119 ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void > () { 120 public Void run () throws IOException { 121 index.getDeclaredTypes (simpleName,kind, convertor, result); 122 return null; 123 } 124 }); 125 } catch (IOException ioe) { 126 Exceptions.printStackTrace(ioe); 127 } 128 } 129 130 131 public void getPackageNames (final String prefix, final boolean directOnly, final Set <String > result) { 132 try { 133 ClassIndexManager.getDefault().readLock(new ClassIndexManager.ExceptionAction<Void >() { 134 public Void run () throws IOException { 135 index.getPackageNames(prefix, directOnly, result); 136 return null; 137 } 138 }); 139 } catch (IOException ioe) { 140 Exceptions.printStackTrace(ioe); 141 } 142 } 143 144 public synchronized void setDirty (final JavaSource js) { 145 if (js == null) { 146 this.dirty = null; 147 } 148 else if (this.dirty == null || this.dirty.get() != js) { 149 this.dirty = new WeakReference (js); 150 } 151 } 152 153 public @Override String toString () { 154 return "CompromiseUQ["+this.root.toExternalForm()+"]"; } 156 157 protected final void close () throws IOException { 159 this.index.close(); 160 } 161 162 163 165 private void updateDirty () { 166 WeakReference <JavaSource> jsRef; 167 synchronized (this) { 168 jsRef = this.dirty; 169 } 170 if (jsRef != null) { 171 final JavaSource js = jsRef.get(); 172 if (js != null) { 173 final long startTime = System.currentTimeMillis(); 174 if (JavaSourceAccessor.INSTANCE.isDispatchThread()) { 175 try { 177 ClassIndexManager.getDefault().writeLock( 178 new ClassIndexManager.ExceptionAction<Void >() { 179 public Void run () throws IOException { 180 CompilationInfo compilationInfo = JavaSourceAccessor.INSTANCE.getCurrentCompilationInfo (js, JavaSource.Phase.RESOLVED); 181 if (compilationInfo != null) { 182 final SourceAnalyser sa = getSourceAnalyser(); 184 long st = System.currentTimeMillis(); 185 sa.analyseUnitAndStore(compilationInfo.getCompilationUnit(), JavaSourceAccessor.INSTANCE.getJavacTask(compilationInfo)); 186 long et = System.currentTimeMillis(); 187 } 188 return null; 189 } 190 }); 191 } catch (IOException ioe) { 192 Exceptions.printStackTrace(ioe); 193 } 194 } 195 else { 196 try { 197 js.runUserActionTask(new CancellableTask<CompilationController>() { 198 public void run (final CompilationController controller) { 199 try { 200 ClassIndexManager.getDefault().writeLock( 201 new ClassIndexManager.ExceptionAction<Void >() { 202 public Void run () throws IOException { 203 controller.toPhase(Phase.RESOLVED); 204 final SourceAnalyser sa = getSourceAnalyser(); 205 long st = System.currentTimeMillis(); 206 sa.analyseUnitAndStore(controller.getCompilationUnit(), JavaSourceAccessor.INSTANCE.getJavacTask(controller)); 207 long et = System.currentTimeMillis(); 208 return null; 209 } 210 }); 211 } catch (IOException ioe) { 212 Exceptions.printStackTrace(ioe); 213 } 214 } 215 216 public void cancel () {} 217 }, true); 218 } catch (IOException ioe) { 219 Exceptions.printStackTrace(ioe); 220 } 221 } 222 synchronized (this) { 223 this.dirty = null; 224 } 225 final long endTime = System.currentTimeMillis(); 226 LOGGER.fine("PersistentClassIndex.updateDirty took: " + (endTime-startTime)+ " ms"); } 228 } 229 } 230 231 private <T> void usages (final String binaryName, final Set <UsageType> usageType, ResultConvertor<T> convertor, Set <? super T> result) { 232 final List <String > classInternalNames = this.getUsagesFQN(binaryName,usageType, Index.BooleanOperator.OR); 233 for (String classInternalName : classInternalNames) { 234 T value = convertor.convert(ElementKind.OTHER, classInternalName); 235 if (value != null) { 236 result.add(value); 237 } 238 } 239 } 240 241 private List <String > getUsagesFQN (final String binaryName, final Set <UsageType> mask, final Index.BooleanOperator operator) { 242 List <String > result = null; 243 try { 244 result = this.index.getUsagesFQN(binaryName, mask, operator); 245 } catch (IOException ioe) { 246 Exceptions.printStackTrace(ioe); 247 } 248 if (result == null) { 249 result = Collections.emptyList(); 250 } 251 return result; 252 } 253 } 254 | Popular Tags |