1 19 package org.netbeans.modules.refactoring.java.classpath; 20 import java.beans.PropertyChangeEvent ; 21 import java.beans.PropertyChangeListener ; 22 import java.beans.PropertyChangeSupport ; 23 import java.net.URL ; 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.Set ; 27 import java.util.HashSet ; 28 import java.util.List ; 29 import java.util.ArrayList ; 30 import java.util.Iterator ; 31 import java.util.Collections ; 32 import org.netbeans.api.java.project.JavaProjectConstants; 33 import org.netbeans.api.project.FileOwnerQuery; 34 import org.netbeans.api.project.Project; 35 import org.netbeans.api.project.ProjectUtils; 36 import org.netbeans.api.project.SourceGroup; 37 import org.netbeans.api.project.Sources; 38 import org.netbeans.api.project.ui.OpenProjects; 39 import org.netbeans.spi.java.classpath.ClassPathFactory; 40 import org.openide.ErrorManager; 41 import org.openide.filesystems.FileObject; 42 import org.openide.filesystems.FileStateInvalidException; 43 import org.netbeans.api.java.classpath.ClassPath; 44 import org.netbeans.api.java.classpath.GlobalPathRegistry; 45 import org.netbeans.api.java.classpath.GlobalPathRegistryEvent; 46 47 import org.netbeans.api.java.classpath.GlobalPathRegistryListener; 48 49 import org.netbeans.api.java.queries.SourceForBinaryQuery; 50 import org.netbeans.spi.java.classpath.ClassPathImplementation; 51 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 52 53 import org.openide.util.WeakListeners; 54 55 56 57 58 public class RefactoringClassPathImplementation implements ClassPathImplementation, GlobalPathRegistryListener, PropertyChangeListener { 59 60 private List resourceCache; 61 private PropertyChangeSupport support; 62 private Collection fileSet; 63 64 private RefactoringClassPathImplementation(Collection set) { 65 this.support = new PropertyChangeSupport (this); 66 this.fileSet = set; 67 } 68 69 public synchronized List getResources() { 70 if (this.resourceCache == null) { 71 this.resourceCache = Collections.unmodifiableList(this.createResources()); 72 } 73 return this.resourceCache; 74 } 75 76 public void addPropertyChangeListener(PropertyChangeListener listener) { 77 this.support.addPropertyChangeListener (listener); 78 } 79 80 public void removePropertyChangeListener(PropertyChangeListener listener) { 81 this.support.removePropertyChangeListener(listener); 82 } 83 84 public void pathsAdded(GlobalPathRegistryEvent event) { 85 resetCache(); 86 } 87 88 89 public void pathsRemoved(GlobalPathRegistryEvent event) { 90 resetCache(); 91 } 92 93 public void propertyChange (PropertyChangeEvent event) { 94 resetCache(); 95 } 96 97 private List createResources () { 98 List result = new ArrayList (); 99 Set covered = new HashSet (); 100 GlobalPathRegistry regs = GlobalPathRegistry.getDefault(); 101 regs.addGlobalPathRegistryListener((GlobalPathRegistryListener)WeakListeners.create(GlobalPathRegistryListener.class, this, regs)); 102 assert regs != null : "GlobalPathRegistry.getDefault() returned null"; 104 computeDependencies(); 105 106 for (Iterator it = sources.iterator(); it.hasNext();) { 107 ClassPath cp = (ClassPath) it.next (); 108 for (Iterator et = cp.entries().iterator(); et.hasNext();) { 109 ClassPath.Entry entry = (ClassPath.Entry) et.next(); 110 URL url = entry.getURL(); 111 assert url != null : "ClassPath.Entry.getURL() returned null"; if (covered.add (url)) 113 result.add (ClassPathSupport.createResource(url)); 114 } 115 cp.addPropertyChangeListener((PropertyChangeListener )WeakListeners.create(PropertyChangeListener .class,this,cp)); 116 } 117 addResources(boot,covered,result); 118 addResources(compile,covered,result); 119 return result; 120 } 121 122 private Set sources; 123 private Set compile; 124 private Set boot; 125 126 private void computeDependencies() { 127 if (fileSet.isEmpty()) { 128 GlobalPathRegistry regs = GlobalPathRegistry.getDefault(); 129 sources = regs.getPaths(ClassPath.SOURCE); 130 assert sources != null : "GlobalPathRegistry.getPath() for SOURCES returned null"; compile = regs.getPaths(ClassPath.COMPILE); 132 assert compile != null : "GlobalPathRegistry.getPath() for COMPILE returned null"; boot = regs.getPaths(ClassPath.BOOT); 134 assert boot != null : "GlobalPathRegistry.getPath() for BOOT returned null"; } else { 136 OpenProjects.getDefault().addPropertyChangeListener((PropertyChangeListener )WeakListeners.create(PropertyChangeListener .class,this,OpenProjects.getDefault())); 137 138 sources = new HashSet (); 139 compile = new HashSet (); 140 boot = new HashSet (); 141 for (Iterator it = getRelevantProjects().iterator();it.hasNext();) { 142 Project p = (Project) it.next(); 143 Sources src = ProjectUtils.getSources(p); 144 SourceGroup[] groups = src.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); 145 for(int i=0; i<groups.length; i++) { 146 ClassPath cp = ClassPath.getClassPath(groups[i].getRootFolder(), ClassPath.SOURCE); 147 sources.add(cp); 148 cp = ClassPath.getClassPath(groups[i].getRootFolder(), ClassPath.COMPILE); 149 compile.add(cp); 150 cp = ClassPath.getClassPath(groups[i].getRootFolder(), ClassPath.BOOT); 151 boot.add(cp); 152 } 153 } 154 } 155 } 156 157 private Collection getRelevantProjects() { 158 Collection relevantProjects = new HashSet (); 159 for (Iterator i = fileSet.iterator(); i.hasNext();) { 160 FileObject fo = (FileObject) i.next(); 161 Project p = FileOwnerQuery.getOwner(fo); 162 if (p == null) { 163 return Arrays.asList(OpenProjects.getDefault().getOpenProjects()); 164 } 165 relevantProjects.addAll(Util.getSuperprojects(p)); 166 relevantProjects.add(p); 167 } 168 return relevantProjects; 169 } 170 171 private void addResources (Set classPaths, Set coveredResources, List addTo) { 172 for (Iterator it = classPaths.iterator(); it.hasNext();) { 173 ClassPath cp = (ClassPath) it.next (); 174 for (Iterator et = cp.entries().iterator(); et.hasNext();) { 175 ClassPath.Entry entry = (ClassPath.Entry) et.next(); 176 URL url = entry.getURL(); 177 assert url != null : "ClassPath.Entry.getURL() returned null"; if (!isCovered (coveredResources, url)) { 179 addTo.add (ClassPathSupport.createResource(url)); 180 coveredResources.add(url); 181 } 182 } 183 cp.addPropertyChangeListener((PropertyChangeListener )WeakListeners.create(PropertyChangeListener .class,this,cp)); 184 } 185 } 186 187 private static boolean isCovered (Set coveredResources, URL url) { 188 if (coveredResources.contains(url)) 189 return true; 190 FileObject[] fos = SourceForBinaryQuery.findSourceRoots(url).getRoots(); 191 assert fos != null : "SourceForBinaryQuery.findSourceRoot() returned null."; for (int i=0; i< fos.length; i++) { 193 try { 194 if (coveredResources.contains(fos[i].getURL())) { 195 return true; 196 } 197 } catch (FileStateInvalidException e) { 198 ErrorManager.getDefault().notify(e); 199 } 200 } 201 return false; 202 } 203 204 private void firePropertyChange () { 205 this.support.firePropertyChange(PROP_RESOURCES,null,null); 206 } 207 208 209 public synchronized static ClassPath getDefault () { 210 if (defaultInstance == null) { 211 defaultInstance = ClassPathFactory.createClassPath( 212 new RefactoringClassPathImplementation(Collections.EMPTY_SET)); 213 } 214 return defaultInstance; 215 } 216 217 public synchronized static ClassPath getCustom(Collection <FileObject> set) { 218 assert set != null; 219 if (customInstance == null || !theSameProjects(set, customInstanceSPI.fileSet)) { 220 customInstanceSPI = new RefactoringClassPathImplementation (set); 221 customInstance = ClassPathFactory.createClassPath (customInstanceSPI); 222 } 223 return customInstance; 224 } 225 226 private static boolean theSameProjects(Collection <FileObject> set1, Collection <FileObject> set2) { 227 if (set1.equals(set2)) 228 return true; 229 HashSet projects1 = getProjects(set1); 230 HashSet projects2 = getProjects(set2); 231 232 return projects1.equals(projects2); 233 } 234 235 private static HashSet getProjects(Collection <FileObject> files) { 236 HashSet projects = new HashSet (2); 237 for (FileObject fo:files) { 238 if (fo!=null) { 239 Project p = FileOwnerQuery.getOwner(fo); 240 projects.add(p); 241 } 242 } 243 return projects; 244 } 245 246 private synchronized static void resetCache () { 247 defaultInstance = null; 248 customInstance = null; 249 Util.resetCache(); 250 } 251 252 private static ClassPath defaultInstance; 253 private static ClassPath customInstance; 254 private static RefactoringClassPathImplementation customInstanceSPI; 255 256 } 257 | Popular Tags |