1 19 20 package org.netbeans.modules.java.project; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.net.URL ; 25 import java.util.ArrayList ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.LinkedHashSet ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import java.util.regex.Matcher ; 33 import java.util.regex.Pattern ; 34 import javax.swing.AbstractListModel ; 35 import org.netbeans.api.java.platform.JavaPlatform; 36 import org.netbeans.api.java.platform.JavaPlatformManager; 37 import org.netbeans.api.project.Project; 38 import org.netbeans.api.project.ProjectManager; 39 import org.netbeans.api.project.libraries.Library; 40 import org.netbeans.api.project.libraries.LibraryManager; 41 import org.netbeans.api.queries.CollocationQuery; 42 import org.netbeans.spi.project.support.ant.AntProjectHelper; 43 import org.netbeans.spi.project.support.ant.EditableProperties; 44 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 45 import org.netbeans.spi.project.support.ant.PropertyUtils; 46 import org.netbeans.spi.project.support.ant.ReferenceHelper; 47 import org.openide.ErrorManager; 48 import org.openide.filesystems.FileObject; 49 import org.openide.filesystems.FileUtil; 50 import org.openide.filesystems.URLMapper; 51 import org.openide.util.NbBundle; 52 53 public class BrokenReferencesModel extends AbstractListModel { 54 55 private String [] props; 56 private String [] platformsProps; 57 private AntProjectHelper helper; 58 private ReferenceHelper resolver; 59 private List <OneReference> references; 60 61 public BrokenReferencesModel(AntProjectHelper helper, 62 ReferenceHelper resolver, String [] props, String [] platformsProps) { 63 this.props = props; 64 this.platformsProps = platformsProps; 65 this.resolver = resolver; 66 this.helper = helper; 67 references = new ArrayList <OneReference>(); 68 refresh(); 69 } 70 71 public void refresh() { 72 Set <OneReference> all = new LinkedHashSet <OneReference>(); 73 Set <OneReference> s = getReferences(helper, helper.getStandardPropertyEvaluator(), props, false); 74 all.addAll(s); 75 s = getPlatforms(helper.getStandardPropertyEvaluator(), platformsProps, false); 76 all.addAll(s); 77 updateReferencesList(references, all); 78 this.fireContentsChanged(this, 0, getSize()); 79 } 80 81 public Object getElementAt(int index) { 82 OneReference or = getOneReference(index); 83 String bundleID; 84 switch (or.type) { 85 case REF_TYPE_LIBRARY: 86 case REF_TYPE_LIBRARY_CONTENT: 87 bundleID = "LBL_BrokenLinksCustomizer_BrokenLibrary"; break; 89 case REF_TYPE_PROJECT: 90 bundleID = "LBL_BrokenLinksCustomizer_BrokenProjectReference"; break; 92 case REF_TYPE_FILE: 93 bundleID = "LBL_BrokenLinksCustomizer_BrokenFileReference"; 94 break; 95 case REF_TYPE_PLATFORM: 96 bundleID = "LBL_BrokenLinksCustomizer_BrokenPlatform"; 97 break; 98 default: 99 assert false; 100 return null; 101 } 102 return NbBundle.getMessage(BrokenReferencesCustomizer.class, bundleID, or.getDisplayID()); 103 } 104 105 public String getDesciption(int index) { 106 OneReference or = getOneReference(index); 107 String bundleID; 108 switch (or.type) { 109 case REF_TYPE_LIBRARY: 110 bundleID = "LBL_BrokenLinksCustomizer_BrokenLibraryDesc"; break; 112 case REF_TYPE_LIBRARY_CONTENT: 113 bundleID = "LBL_BrokenLinksCustomizer_BrokenLibraryContentDesc"; break; 115 case REF_TYPE_PROJECT: 116 bundleID = "LBL_BrokenLinksCustomizer_BrokenProjectReferenceDesc"; break; 118 case REF_TYPE_FILE: 119 bundleID = "LBL_BrokenLinksCustomizer_BrokenFileReferenceDesc"; 120 break; 121 case REF_TYPE_PLATFORM: 122 bundleID = "LBL_BrokenLinksCustomizer_BrokenPlatformDesc"; 123 break; 124 default: 125 assert false; 126 return null; 127 } 128 return NbBundle.getMessage(BrokenReferencesCustomizer.class, bundleID, or.getDisplayID()); 129 } 130 131 public OneReference getOneReference(int index) { 132 assert index>=0 && index<references.size(); 133 return references.get(index); 134 } 135 136 public boolean isBroken(int index) { 137 return references.get(index).broken; 138 } 139 140 public int getSize() { 141 return references.size(); 142 } 143 144 public static boolean isBroken(AntProjectHelper helper, PropertyEvaluator evaluator, String [] props, String [] platformsProps) { 145 Set <OneReference> s = getReferences(helper, evaluator, props, true); 146 if (s.size() > 0) { 147 return true; 148 } 149 s = getPlatforms(evaluator, platformsProps, true); 150 return s.size() > 0; 151 } 152 153 private static Set <OneReference> getReferences(AntProjectHelper helper, PropertyEvaluator evaluator, String [] ps, boolean abortAfterFirstProblem) { 154 Set <OneReference> set = new LinkedHashSet <OneReference>(); 155 StringBuffer all = new StringBuffer (); 156 for (String p : ps) { 157 159 String prop = evaluator.getProperty(p); 160 if (prop == null) { 161 continue; 162 } 163 String [] vals = PropertyUtils.tokenizePath(prop); 164 165 for (String v : vals) { 168 if (!(v.startsWith("${file.reference.") || v.startsWith("${project.") || v.startsWith("${libs."))) { 170 all.append(v); 171 continue; 172 } 173 if (v.startsWith("${project.")) { 174 String val = v.substring(2, v.indexOf('}')); 176 set.add(new OneReference(REF_TYPE_PROJECT, val, true)); 177 } else { 178 int type = REF_TYPE_LIBRARY; 179 if (v.startsWith("${file.reference")) { 180 type = REF_TYPE_FILE; 181 } 182 String val = v.substring(2, v.length() - 1); 183 set.add(new OneReference(type, val, true)); 184 } 185 if (abortAfterFirstProblem) { 186 break; 187 } 188 } 189 if (set.size() > 0 && abortAfterFirstProblem) { 190 break; 191 } 192 } 193 194 for (Map.Entry <String , String > entry : evaluator.getProperties().entrySet()) { 199 String key = entry.getKey(); 200 String value = entry.getValue(); 201 if (key.startsWith("project.")) { File f = getFile(helper, evaluator, value); 203 if (f.exists()) { 204 continue; 205 } 206 if (all.indexOf(value) == -1) { 209 continue; 210 } 211 set.add(new OneReference(REF_TYPE_PROJECT, key, true)); 212 } 213 else if (key.startsWith("file.reference")) { File f = getFile(helper, evaluator, value); 215 if (f.exists() || all.indexOf(value) == -1) { 216 continue; 217 } 218 set.add(new OneReference(REF_TYPE_FILE, key, true)); 219 } 220 } 221 222 Set <String > usedLibraries = new HashSet <String >(); 224 Pattern libPattern = Pattern.compile("\\$\\{(lib.[-._a-zA-Z0-9]+.classpath)\\}"); EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); 226 for (String p : ps) { 227 String propertyValue = ep.getProperty(p); 228 if (propertyValue != null) { 229 for (String v : PropertyUtils.tokenizePath(propertyValue)) { 230 Matcher m = libPattern.matcher(v); 231 if (m.matches()) { 232 usedLibraries.add (m.group(1)); 233 } 234 } 235 } 236 } 237 for (String libraryRef : usedLibraries) { 238 String libraryName = libraryRef.substring(5,libraryRef.length()-10); 239 Library lib = LibraryManager.getDefault().getLibrary (libraryName); 240 if (lib == null) { 241 set.add(new OneReference(REF_TYPE_LIBRARY, libraryRef, true)); 242 } 243 else { 244 for (URL url : lib.getContent("classpath")) { if ("jar".equals(url.getProtocol())) { url = FileUtil.getArchiveFile (url); 248 } 249 if (URLMapper.findFileObject (url) == null) { 250 set.add(new OneReference(REF_TYPE_LIBRARY_CONTENT, libraryRef, true)); 251 } 252 } 253 } 254 } 255 256 return set; 257 } 258 259 private static File getFile (AntProjectHelper helper, PropertyEvaluator evaluator, String name) { 260 if (helper != null) { 261 return new File (helper.resolvePath(name)); 262 } else { 263 File f = new File (name); 264 if (!f.exists()) { 265 String basedir = evaluator.getProperty("basedir"); 267 assert basedir != null; 268 f = new File (new File (basedir), name); 269 } 270 return f; 271 } 272 } 273 274 private static Set <OneReference> getPlatforms(PropertyEvaluator evaluator, String [] platformsProps, boolean abortAfterFirstProblem) { 275 Set <OneReference> set = new LinkedHashSet <OneReference>(); 276 for (String pprop : platformsProps) { 277 String prop = evaluator.getProperty(pprop); 278 if (prop == null) { 279 continue; 280 } 281 if (!existPlatform(prop)) { 282 283 if (evaluator.getProperty(pprop + ".description") != null) { 287 prop = evaluator.getProperty(pprop + ".description"); 288 } 289 290 set.add(new OneReference(REF_TYPE_PLATFORM, prop, true)); 291 } 292 if (set.size() > 0 && abortAfterFirstProblem) { 293 break; 294 } 295 } 296 return set; 297 } 298 299 private static void updateReferencesList(List <OneReference> oldBroken, Set <OneReference> newBroken) { 300 for (OneReference or : oldBroken) { 301 if (newBroken.contains(or)) { 302 or.broken = true; 303 } else { 304 or.broken = false; 305 } 306 } 307 for (OneReference or : newBroken) { 308 if (!oldBroken.contains(or)) { 309 oldBroken.add(or); 310 } 311 } 312 } 313 314 private static boolean existPlatform(String platform) { 315 if (platform.equals("default_platform")) { return true; 317 } 318 for (JavaPlatform plat : JavaPlatformManager.getDefault().getInstalledPlatforms()) { 319 if (platform.equals(plat.getProperties().get("platform.ant.name")) && plat.getInstallFolders().size() > 0) { 322 return true; 323 } 324 } 325 return false; 326 } 327 328 void updateReference(int index, File file) { 331 updateReference0(index, file); 332 OneReference or = getOneReference(index); 335 if (or.getType() != REF_TYPE_FILE) { 336 return; 337 } 338 for (int i=0; i<getSize(); i++) { 339 if (!isBroken(i) || i == index) { 340 continue; 341 } 342 or = getOneReference(i); 343 if (or.getType() != REF_TYPE_FILE) { 344 continue; 345 } 346 File f = new File (file.getParentFile(), or.getDisplayID()); 347 if (f.exists()) { 348 updateReference0(i, f); 349 } 350 } 351 } 352 353 private void updateReference0(int index, File file) { 354 final String reference = getOneReference(index).ID; 355 FileObject myProjDirFO = helper.getProjectDirectory(); 356 File myProjDir = FileUtil.toFile(myProjDirFO); 357 final String propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH; 358 final String path = file.getAbsolutePath(); 359 Project p; 360 try { 361 p = ProjectManager.getDefault().findProject(myProjDirFO); 362 } catch (IOException ex) { 363 ErrorManager.getDefault().notify(ErrorManager.ERROR, ex); 364 p = null; 365 } 366 final Project proj = p; 367 ProjectManager.mutex().postWriteRequest(new Runnable () { 368 public void run() { 369 EditableProperties props = helper.getProperties(propertiesFile); 370 if (!path.equals(props.getProperty(reference))) { 371 props.setProperty(reference, path); 372 helper.putProperties(propertiesFile, props); 373 } 374 375 props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); 377 if (props.containsKey(reference)) { 378 props.remove(reference); 379 helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); 380 } 381 382 if (proj != null) { 383 try { 384 ProjectManager.getDefault().saveProject(proj); 385 } catch (IOException ex) { 386 ErrorManager.getDefault().notify(ErrorManager.WARNING, ex); 387 } 388 } 389 } 390 }); 391 } 392 393 public static final int REF_TYPE_PROJECT = 1; 394 public static final int REF_TYPE_FILE = 2; 395 public static final int REF_TYPE_LIBRARY = 3; 396 public static final int REF_TYPE_PLATFORM = 4; 397 public static final int REF_TYPE_LIBRARY_CONTENT = 5; 398 399 public static class OneReference { 400 401 private int type; 402 private boolean broken; 403 private String ID; 404 405 public OneReference(int type, String ID, boolean broken) { 406 this.type = type; 407 this.ID = ID; 408 this.broken = broken; 409 } 410 411 public int getType() { 412 return type; 413 } 414 415 public String getDisplayID() { 416 switch (type) { 417 418 case REF_TYPE_LIBRARY: 419 case REF_TYPE_LIBRARY_CONTENT: 420 return ID.substring(5, ID.length()-10); 422 423 case REF_TYPE_PROJECT: 424 return ID.substring(8); 426 427 case REF_TYPE_FILE: 428 return ID.substring(15); 430 431 case REF_TYPE_PLATFORM: 432 return ID; 433 434 default: 435 assert false; 436 return ID; 437 } 438 } 439 440 public boolean equals(Object o) { 441 if (o == this) { 442 return true; 443 } 444 if (!(o instanceof OneReference)) { 445 return false; 446 } 447 OneReference or = (OneReference)o; 448 return (this.type == or.type && this.ID.equals(or.ID)); 449 } 450 451 public int hashCode() { 452 int result = 7*type; 453 result = 31*result + ID.hashCode(); 454 return result; 455 } 456 457 } 458 459 } 460 | Popular Tags |