1 19 20 package org.netbeans.modules.projectapi; 21 22 import java.io.IOException ; 23 import java.lang.ref.Reference ; 24 import java.lang.ref.WeakReference ; 25 import java.net.MalformedURLException ; 26 import java.net.URI ; 27 import java.net.URISyntaxException ; 28 import java.net.URL ; 29 import java.util.Collection ; 30 import java.util.Collections ; 31 import java.util.LinkedList ; 32 import java.util.Map ; 33 import java.util.Set ; 34 import java.util.WeakHashMap ; 35 import org.netbeans.api.project.Project; 36 import org.netbeans.api.project.ProjectManager; 37 import org.netbeans.spi.project.FileOwnerQueryImplementation; 38 import org.openide.ErrorManager; 39 import org.openide.filesystems.FileObject; 40 import org.openide.filesystems.FileStateInvalidException; 41 import org.openide.filesystems.URLMapper; 42 import org.openide.util.Utilities; 43 import org.openide.util.WeakSet; 44 45 49 public class SimpleFileOwnerQueryImplementation implements FileOwnerQueryImplementation { 50 51 52 public SimpleFileOwnerQueryImplementation() {} 53 54 public Project getOwner(URI fileURI) { 55 URI test = fileURI; 57 FileObject file; 58 do { 59 file = uri2FileObject(test); 60 test = goUp(test); 61 } while (file == null && test != null); 62 if (file == null) { 63 return null; 64 } 65 return getOwner(file); 66 } 67 68 private final Set <FileObject> warnedAboutBrokenProjects = new WeakSet<FileObject>(); 69 70 public Project getOwner(FileObject f) { 71 while (f != null) { 72 if (f.isFolder()) { 73 Project p; 74 try { 75 p = ProjectManager.getDefault().findProject(f); 76 } catch (IOException e) { 77 if (warnedAboutBrokenProjects.add(f)) { ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 80 } 81 return null; 82 } 83 if (p != null) { 84 return p; 85 } 86 } 87 88 if (!externalOwners.isEmpty()) { 89 Reference <FileObject> externalOwnersReference = externalOwners.get(fileObject2URI(f)); 90 91 if (externalOwnersReference != null) { 92 FileObject externalOwner = externalOwnersReference.get(); 93 94 if (externalOwner != null) { 95 try { 96 return ProjectManager.getDefault().findProject(externalOwner); 98 } catch (IOException e) { 99 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 101 return null; 102 } 103 } 104 } 105 } 106 f = f.getParent(); 107 } 108 return null; 109 } 110 111 114 private static final Map <URI ,Reference <FileObject>> externalOwners = 115 Collections.synchronizedMap(new WeakHashMap <URI ,Reference <FileObject>>()); 116 private static final Map <FileObject,Collection <URI >> project2External = 117 Collections.synchronizedMap(new WeakHashMap <FileObject,Collection <URI >>()); 118 119 120 public static void reset() { 121 externalOwners.clear(); 122 } 123 124 private static URI fileObject2URI(FileObject f) { 125 try { 126 return URI.create(f.getURL().toString()); 127 } catch (FileStateInvalidException e) { 128 throw (IllegalArgumentException ) new IllegalArgumentException (e.toString()).initCause(e); 129 } 130 } 131 132 133 public static void markExternalOwnerTransient(FileObject root, Project owner) { 134 markExternalOwnerTransient(fileObject2URI(root), owner); 135 } 136 137 138 public static void markExternalOwnerTransient(URI root, Project owner) { 139 if (owner != null) { 140 externalOwners.put(root, new WeakReference <FileObject>(owner.getProjectDirectory())); 141 synchronized (project2External) { 142 FileObject prjDir = owner.getProjectDirectory(); 143 Collection <URI > roots = project2External.get (prjDir); 144 if (roots == null) { 145 roots = new LinkedList <URI >(); 146 project2External.put(prjDir, roots); 147 } 148 roots.add (root); 149 } 150 } else { 151 Reference <FileObject> ownerReference = externalOwners.remove(root); 152 153 if (ownerReference != null) { 154 FileObject ownerFO = ownerReference.get(); 155 156 if (ownerFO != null) { 157 synchronized (project2External) { 158 Collection <URI > roots = project2External.get(ownerFO); 159 if (roots != null) { 160 roots.remove(root); 161 if (roots.size() == 0) { 162 project2External.remove(ownerFO); 163 } 164 } 165 } 166 } 167 } 168 } 169 } 170 171 private static FileObject uri2FileObject(URI u) { 172 URL url; 173 try { 174 url = u.toURL(); 175 } catch (MalformedURLException e) { 176 e.printStackTrace(); 177 assert false : u; 178 return null; 179 } 180 return URLMapper.findFileObject(url); 181 } 182 183 private static URI goUp(URI u) { 184 assert u.isAbsolute() : u; 185 assert u.getFragment() == null : u; 186 assert u.getQuery() == null : u; 187 String path = u.getPath(); 191 if (path == null || path.equals("/")) { return null; 193 } 194 String us = u.toString(); 195 if (us.endsWith("/")) { us = us.substring(0, us.length() - 1); 197 assert path.endsWith("/"); path = path.substring(0, path.length() - 1); 199 } 200 int idx = us.lastIndexOf('/'); 201 assert idx != -1 : path; 202 if (path.lastIndexOf('/') == 0) { 203 us = us.substring(0, idx + 1); 204 } else { 205 us = us.substring(0, idx); 206 } 207 URI nue; 208 try { 209 nue = new URI (us); 210 } catch (URISyntaxException e) { 211 throw new AssertionError (e); 212 } 213 if (Utilities.isWindows()) { 214 String pth = nue.getPath(); 215 if ((pth.length() == 3 && pth.endsWith(":")) || 217 (pth.length() == 1 && pth.endsWith("/"))) { 218 return null; 219 } 220 } 221 assert nue.isAbsolute() : nue; 222 assert u.toString().startsWith(nue.toString()) : "not a parent: " + nue + " of " + u; 223 return nue; 224 } 225 226 } 227 | Popular Tags |