1 19 package org.netbeans.api.retouche.source; 20 21 import java.beans.PropertyChangeEvent ; 22 import java.beans.PropertyChangeListener ; 23 import java.io.File ; 24 import java.net.URL ; 25 import javax.swing.event.ChangeEvent ; 26 import javax.swing.event.ChangeListener ; 27 import javax.swing.event.EventListenerList ; 28 import org.netbeans.api.java.classpath.ClassPath; 29 import org.netbeans.api.java.platform.JavaPlatformManager; 30 import org.netbeans.api.retouche.source.ClassIndex; 31 import org.netbeans.modules.retouche.source.CacheClassPath; 32 import org.netbeans.modules.retouche.source.usages.ClasspathInfoAccessor; 33 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 34 import org.openide.ErrorManager; 35 import org.openide.filesystems.FileObject; 36 import org.openide.filesystems.FileUtil; 37 import org.openide.util.WeakListeners; 38 39 49 public final class ClasspathInfo { 50 51 private static final ClassPath EMPTY_PATH = ClassPathSupport.createClassPath(new URL [0]); 52 53 static { 54 ClasspathInfoAccessor.INSTANCE = new ClasspathInfoAccessorImpl (); 55 try { 56 Class.forName(ClassIndex.class.getName(), true, CompilationInfo.class.getClassLoader()); 57 } catch (ClassNotFoundException ex) { 58 ErrorManager.getDefault().notify (ex); 59 } 60 } 61 62 64 private final ClassPath srcClassPath; 65 private final ClassPath bootClassPath; 66 private final ClassPath compileClassPath; 67 private ClassPath outputClassPath; 68 69 private final ClassPathListener cpListener; 70 private final boolean backgroundCompilation; 71 private EventListenerList listenerList = null; 72 private ClassIndex usagesQuery; 73 74 75 private ClasspathInfo( ClassPath bootCp, ClassPath compileCp, ClassPath srcCp, 76 Object filter, boolean backgroundCompilation) { 77 assert bootCp != null && compileCp != null; 78 this.cpListener = new ClassPathListener (); 79 this.bootClassPath = CacheClassPath.forBootPath(bootCp); 81 this.compileClassPath = CacheClassPath.forClassPath(compileCp); 82 this.bootClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.bootClassPath)); 83 this.compileClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.compileClassPath)); 84 if ( srcCp != null ) { 85 this.srcClassPath = srcCp; 86 this.outputClassPath = CacheClassPath.forSourcePath (this.srcClassPath); 87 this.srcClassPath.addPropertyChangeListener(WeakListeners.propertyChange(this.cpListener,this.srcClassPath)); 88 } 89 else { 90 this.srcClassPath = ClassPathSupport.createClassPath(new URL [0]); 91 this.outputClassPath = ClassPathSupport.createClassPath(new URL [0]); 92 } 93 this.backgroundCompilation = backgroundCompilation; 94 } 96 97 public String toString() { 98 return "ClasspathInfo boot:[" + bootClassPath + "],compile:[" + compileClassPath + "],src:[" + srcClassPath + "]"; } 100 101 103 104 109 public static ClasspathInfo create (final File file) { 110 if (file == null) { 111 throw new IllegalArgumentException ("Cannot pass null as parameter of ClasspathInfo.create(java.io.File)"); } 113 final FileObject fo = FileUtil.toFileObject(file); 114 if (fo == null) { 115 return null; 116 } 117 else { 118 return create (fo); 119 } 120 } 121 122 123 private static ClasspathInfo create (FileObject fo, Object filter, boolean backgroundCompilation) { 124 ClassPath bootPath = ClassPath.getClassPath(fo, ClassPath.BOOT); 125 if (bootPath == null) { 126 bootPath = JavaPlatformManager.getDefault().getDefaultPlatform().getBootstrapLibraries(); 128 } 129 ClassPath compilePath = ClassPath.getClassPath(fo, ClassPath.COMPILE); 130 if (compilePath == null) { 131 compilePath = EMPTY_PATH; 132 } 133 ClassPath srcPath = ClassPath.getClassPath(fo, ClassPath.SOURCE); 134 if (srcPath == null) { 135 srcPath = EMPTY_PATH; 136 } 137 return create (bootPath, compilePath, srcPath, filter, backgroundCompilation); 138 } 139 140 143 public static ClasspathInfo create(FileObject fo) { 144 return create (fo, null, false); 145 } 146 147 private static ClasspathInfo create(ClassPath bootPath, ClassPath classPath, ClassPath sourcePath, Object filter, boolean backgroundCompilation) { 148 return new ClasspathInfo( bootPath, classPath, sourcePath, filter, backgroundCompilation); 149 } 150 151 public static ClasspathInfo create(ClassPath bootPath, ClassPath classPath, ClassPath sourcePath) { 152 return new ClasspathInfo( bootPath, classPath, sourcePath, null, false); 153 } 154 155 157 160 public synchronized void addChangeListener(ChangeListener listener) { 161 if (listenerList == null ) { 162 listenerList = new EventListenerList (); 163 } 164 listenerList.add (ChangeListener .class, listener); 165 } 166 167 170 public synchronized void removeChangeListener(ChangeListener listener) { 171 listenerList.remove (ChangeListener .class, listener); 172 } 173 174 public ClassPath getClassPath (PathKind pathKind) { 175 switch( pathKind ) { 176 case BOOT: 177 return this.bootClassPath; 178 case COMPILE: 179 return this.compileClassPath; 180 case SOURCE: 181 return this.srcClassPath; 182 case OUTPUT: 183 return this.outputClassPath; 184 default: 185 assert false : "Unknown path type"; return null; 187 } 188 } 189 190 191 public synchronized ClassIndex getClassIndex () { 192 if ( usagesQuery == null ) { 193 usagesQuery = new ClassIndex ( 194 this.bootClassPath, 195 this.compileClassPath, 196 this.srcClassPath); 197 } 198 return usagesQuery; 199 } 200 201 217 219 private void fireChangeListenerStateChanged() { 220 ChangeEvent e = null; 221 if (listenerList == null) return; 222 Object [] listeners = listenerList.getListenerList (); 223 for (int i = listeners.length - 2; i >= 0; i -= 2) { 224 if (listeners[i]==ChangeListener .class) { 225 if (e == null) 226 e = new ChangeEvent (this); 227 ((ChangeListener )listeners[i+1]).stateChanged (e); 228 } 229 } 230 } 231 232 233 235 public static enum PathKind { 236 BOOT, 237 COMPILE, 238 SOURCE, 239 OUTPUT, 240 241 } 242 243 private class ClassPathListener implements PropertyChangeListener { 244 245 public void propertyChange (PropertyChangeEvent event) { 246 if (ClassPath.PROP_ROOTS.equals(event.getPropertyName())) { 247 synchronized (this) { 248 usagesQuery = null; 252 } 253 fireChangeListenerStateChanged(); 254 } 255 } 256 } 257 258 private static class ClasspathInfoAccessorImpl extends ClasspathInfoAccessor { 259 260 265 @Override 266 public ClasspathInfo create (ClassPath bootPath, ClassPath classPath, ClassPath sourcePath, Object filter, boolean backgroundCompilation) { 267 return ClasspathInfo.create(bootPath, classPath, sourcePath, filter, backgroundCompilation); 268 } 269 270 @Override 271 public ClasspathInfo create (FileObject fo, Object filter, boolean backgroundCompilation) { 272 return ClasspathInfo.create(fo, filter, backgroundCompilation); 273 } 274 } 275 } 276 | Popular Tags |