1 19 20 package org.netbeans.modules.web.project.classpath; 21 22 import java.io.File ; 23 import java.net.URI ; 24 import java.util.ArrayList ; 25 import java.util.Arrays ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.LinkedHashMap ; 29 import java.util.LinkedList ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Set ; 33 34 import org.w3c.dom.Document ; 35 import org.w3c.dom.Element ; 36 import org.w3c.dom.Node ; 37 import org.w3c.dom.NodeList ; 38 import org.w3c.dom.Text ; 39 40 import org.netbeans.api.project.ant.AntArtifact; 41 import org.netbeans.api.project.libraries.Library; 42 import org.netbeans.api.project.libraries.LibraryManager; 43 import org.netbeans.spi.project.support.ant.AntProjectHelper; 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 48 import org.netbeans.modules.web.project.WebProjectType; 49 import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties; 50 51 55 public class ClassPathSupport { 56 57 private PropertyEvaluator evaluator; 58 private ReferenceHelper referenceHelper; 59 private AntProjectHelper antProjectHelper; 60 private Set wellKnownPaths; 61 private String libraryPrefix; 62 private String librarySuffix; 63 private String antArtifactPrefix; 64 65 public final static String TAG_WEB_MODULE_LIBRARIES = "web-module-libraries"; public final static String TAG_WEB_MODULE__ADDITIONAL_LIBRARIES = "web-module-additional-libraries"; 68 69 public ClassPathSupport( PropertyEvaluator evaluator, 70 ReferenceHelper referenceHelper, 71 AntProjectHelper antProjectHelper, 72 String wellKnownPaths[], 73 String libraryPrefix, 74 String librarySuffix, 75 String antArtifactPrefix) { 76 this.evaluator = evaluator; 77 this.referenceHelper = referenceHelper; 78 this.antProjectHelper = antProjectHelper; 79 this.wellKnownPaths = wellKnownPaths == null ? null : new HashSet ( Arrays.asList( wellKnownPaths ) ); 80 this.libraryPrefix = libraryPrefix; 81 this.librarySuffix = librarySuffix; 82 this.antArtifactPrefix = antArtifactPrefix; 83 } 84 85 87 public Iterator itemsIterator( String propertyValue, String webModuleLibraries ) { 88 return itemsList( propertyValue, webModuleLibraries ).iterator(); 90 } 91 92 public List itemsList( String propertyValue, String webModuleLibraries ) { 93 94 Map warMap = ( webModuleLibraries != null ) ? createWarIncludesMap( antProjectHelper, webModuleLibraries) : new LinkedHashMap (); 96 97 String pe[] = PropertyUtils.tokenizePath( propertyValue == null ? "": propertyValue ); List items = new ArrayList ( pe.length ); 99 for( int i = 0; i < pe.length; i++ ) { 100 String property = WebProjectProperties.getAntPropertyName( pe[i] ); 101 102 Item item; 103 104 if ( isWellKnownPath( pe[i] ) ) { 106 item = Item.create( pe[i], Item.PATH_IN_WAR_NONE); 108 } 109 else if ( isLibrary( pe[i] ) ) { 110 String libraryName = pe[i].substring( libraryPrefix.length(), pe[i].lastIndexOf('.') ); Library library = LibraryManager.getDefault().getLibrary( libraryName ); 113 if ( library == null ) { 114 item = Item.createBroken( Item.TYPE_LIBRARY, pe[i], (String ) warMap.get(property)); 115 } 116 else { 117 item = Item.create( library, pe[i], (String ) warMap.get(property)); 118 } 119 } 120 else if ( isAntArtifact( pe[i] ) ) { 121 Object [] ret = referenceHelper.findArtifactAndLocation(pe[i]); 123 if ( ret[0] == null || ret[1] == null ) { 124 item = Item.createBroken( Item.TYPE_ARTIFACT, pe[i], (String ) warMap.get(property)); 125 } 126 else { 127 AntArtifact artifact = (AntArtifact)ret[0]; 130 URI uri = (URI )ret[1]; 131 File usedFile = antProjectHelper.resolveFile(evaluator.evaluate(pe[i])); 132 File artifactFile = new File (artifact.getScriptLocation().toURI().resolve(uri).normalize()); 133 if (usedFile.equals(artifactFile)) { 134 item = Item.create( artifact, uri, pe[i], (String ) warMap.get(property) ); 135 } 136 else { 137 item = Item.createBroken( Item.TYPE_ARTIFACT, pe[i], (String ) warMap.get(property) ); 138 } 139 } 140 } else { 141 String eval = evaluator.evaluate( pe[i] ); 143 File f = null; 144 if (eval != null) { 145 f = antProjectHelper.resolveFile( eval ); 146 } 147 148 if ( f == null || !f.exists() ) { 149 item = Item.createBroken( Item.TYPE_JAR, pe[i], (String ) warMap.get(property)); 150 } 151 else { 152 item = Item.create( f, pe[i], (String ) warMap.get(property)); 153 } 154 } 155 156 items.add( item ); 157 } 158 159 return items; 160 } 161 162 166 public String [] encodeToStrings( Iterator classpath, String webModuleLibraries ) { 167 168 ArrayList result = new ArrayList (); 169 ArrayList includedLibraries = new ArrayList (); 170 171 List cp = new LinkedList (); 172 173 while( classpath.hasNext() ) { 174 175 Item item = (Item)classpath.next(); 176 cp.add(item); 177 String reference = null; 178 179 switch( item.getType() ) { 180 181 case Item.TYPE_JAR: 182 reference = item.getReference(); 183 if ( item.isBroken() ) { 184 break; 185 } 186 if (reference == null) { 187 File file = item.getFile(); 189 reference = referenceHelper.createForeignFileReference(file, null); 191 item.setReference(reference); 192 } 193 break; 194 case Item.TYPE_LIBRARY: 195 reference = item.getReference(); 196 if ( item.isBroken() ) { 197 break; 198 } 199 Library library = item.getLibrary(); 200 if (reference == null) { 201 if ( library == null ) { 202 break; 203 } 204 reference = getLibraryReference( item ); 205 item.setReference(reference); 206 } 207 break; 208 case Item.TYPE_ARTIFACT: 209 reference = item.getReference(); 210 if ( item.isBroken() ) { 211 break; 212 } 213 AntArtifact artifact = (AntArtifact)item.getArtifact(); 214 if ( reference == null) { 215 if ( artifact == null ) { 216 break; 217 } 218 reference = referenceHelper.addReference( item.getArtifact(), item.getArtifactURI()); 219 item.setReference(reference); 220 } 221 break; 222 case Item.TYPE_CLASSPATH: 223 reference = item.getReference(); 224 break; 225 } 226 227 if ( reference != null ) { 228 result.add( reference ); 229 230 if (webModuleLibraries != null) { 231 includedLibraries.add( WebProjectProperties.getAntPropertyName( reference ) ); 232 } 233 } 234 235 } 236 237 if ( webModuleLibraries != null ) 238 putIncludedLibraries( includedLibraries, cp, antProjectHelper, webModuleLibraries ); 239 240 String [] items = new String [ result.size() ]; 241 for( int i = 0; i < result.size(); i++) { 242 if ( i < result.size() - 1 ) { 243 items[i] = result.get( i ) + ":"; 244 } 245 else { 246 items[i] = (String )result.get( i ); } 248 } 249 250 return items; 251 } 252 253 public String getLibraryReference( Item item ) { 254 if ( item.getType() != Item.TYPE_LIBRARY ) { 255 throw new IllegalArgumentException ( "Item must be of type LIBRARY" ); 256 } 257 return libraryPrefix + item.getLibrary().getName() + librarySuffix; 258 } 259 260 262 private boolean isWellKnownPath( String property ) { 263 return wellKnownPaths == null ? false : wellKnownPaths.contains( property ); 264 } 265 266 private boolean isAntArtifact( String property ) { 267 return antArtifactPrefix == null ? false : property.startsWith( antArtifactPrefix ); 268 } 269 270 private boolean isLibrary( String property ) { 271 if ( libraryPrefix != null && property.startsWith( libraryPrefix ) ) { 272 return librarySuffix == null ? true : property.endsWith( librarySuffix ); 273 } 274 else { 275 return false; 276 } 277 278 } 279 280 282 private static final String TAG_PATH_IN_WAR = "path-in-war"; private static final String TAG_FILE = "file"; private static final String TAG_LIBRARY = "library"; private static final String ATTR_FILES = "files"; private static final String ATTR_DIRS = "dirs"; 288 private static Map createWarIncludesMap(AntProjectHelper uh, String webModuleLibraries) { 289 Map warIncludesMap = new LinkedHashMap (); 290 for(int idx = WebProjectType.PROJECT_CONFIGURATION_NAMESPACE_LIST.length - 1; idx >= 0; idx--) { 292 String ns = WebProjectType.PROJECT_CONFIGURATION_NAMESPACE_LIST[idx]; 293 Element data = uh.createAuxiliaryConfiguration().getConfigurationFragment("data",ns,true); 294 if(data != null) { 295 Element webModuleLibs = (Element ) data.getElementsByTagNameNS(ns, webModuleLibraries).item(0); 296 if (webModuleLibs != null) { 297 NodeList ch = webModuleLibs.getChildNodes(); 298 for (int i = 0; i < ch.getLength(); i++) { 299 if (ch.item(i).getNodeType() == Node.ELEMENT_NODE) { 300 Element library = (Element ) ch.item(i); 301 Node webFile = library.getElementsByTagNameNS(ns, TAG_FILE).item(0); 302 NodeList pathInWarElements = library.getElementsByTagNameNS(ns, TAG_PATH_IN_WAR); 303 String webFileText = findText(webFile); 305 webFileText = webFileText.substring(2, webFileText.length() - 1); 306 307 if (webModuleLibraries.equals(TAG_WEB_MODULE__ADDITIONAL_LIBRARIES)) { 309 String pathInWar = Item.PATH_IN_WAR_NONE; 310 if (pathInWarElements.getLength() > 0) { 311 pathInWar = findText((Element ) pathInWarElements.item(0)); 312 if (pathInWar == null) 313 pathInWar = Item.PATH_IN_WAR_APPLET; 314 } 315 warIncludesMap.put(webFileText, pathInWar); 316 } else 317 warIncludesMap.put(webFileText, pathInWarElements.getLength() > 0 ? findText((Element ) pathInWarElements.item(0)) : Item.PATH_IN_WAR_NONE); 318 } 319 } 320 return warIncludesMap; 321 } 322 } 323 } 324 return warIncludesMap; } 326 327 331 private static void putIncludedLibraries( List libraries, List classpath, AntProjectHelper antProjectHelper, String webModuleLibraries ) { 332 assert libraries != null; 333 assert antProjectHelper != null; 334 assert webModuleLibraries != null; 335 336 Element data = antProjectHelper.getPrimaryConfigurationData( true ); 337 Document doc = data.getOwnerDocument(); 338 Element webModuleLibs = (Element ) data.getElementsByTagNameNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, webModuleLibraries).item(0); 339 if (webModuleLibs == null) { 340 webModuleLibs = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, webModuleLibraries); data.appendChild(webModuleLibs); 342 } 343 while (webModuleLibs.hasChildNodes()) { 344 webModuleLibs.removeChild(webModuleLibs.getChildNodes().item(0)); 345 } 346 347 Iterator cp = classpath.iterator(); 348 for (Iterator i = libraries.iterator(); i.hasNext();) 349 webModuleLibs.appendChild(createLibraryElement(doc, (String )i.next(), (Item) cp.next())); 350 351 antProjectHelper.putPrimaryConfigurationData( data, true ); 352 } 353 354 private static Element createLibraryElement(Document doc, String pathItem, Item item) { 355 Element libraryElement = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, TAG_LIBRARY); 356 ArrayList files = new ArrayList (); 357 ArrayList dirs = new ArrayList (); 358 WebProjectProperties.getFilesForItem(item, files, dirs); 359 if (files.size() > 0) { 360 libraryElement.setAttribute(ATTR_FILES, "" + files.size()); 361 } 362 if (dirs.size() > 0) { 363 libraryElement.setAttribute(ATTR_DIRS, "" + dirs.size()); 364 } 365 Element webFile = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, TAG_FILE); 366 libraryElement.appendChild(webFile); 367 webFile.appendChild(doc.createTextNode("${" + pathItem + "}")); 368 if (item.getPathInWAR() != null) { 369 Element pathInWar = doc.createElementNS(WebProjectType.PROJECT_CONFIGURATION_NAMESPACE, TAG_PATH_IN_WAR); 370 pathInWar.appendChild(doc.createTextNode(item.getPathInWAR())); 371 libraryElement.appendChild(pathInWar); 372 } 373 return libraryElement; 374 } 375 376 382 private static String findText( Element parent ) { 383 NodeList l = parent.getChildNodes(); 384 for ( int i = 0; i < l.getLength(); i++ ) { 385 if ( l.item(i).getNodeType() == Node.TEXT_NODE ) { 386 Text text = (Text )l.item( i ); 387 return text.getNodeValue(); 388 } 389 } 390 return null; 391 } 392 393 399 private static String findText(Node parent) { 400 NodeList l = parent.getChildNodes(); 401 for (int i = 0; i < l.getLength(); i++) { 402 if (l.item(i).getNodeType() == Node.TEXT_NODE) { 403 Text text = (Text )l.item(i); 404 return text.getNodeValue(); 405 } 406 } 407 return null; 408 } 409 410 412 414 public static class Item { 415 416 public static final int TYPE_JAR = 0; 418 public static final int TYPE_LIBRARY = 1; 419 public static final int TYPE_ARTIFACT = 2; 420 public static final int TYPE_CLASSPATH = 3; 421 422 public static final String PATH_IN_WAR_LIB = "WEB-INF/lib"; public static final String PATH_IN_WAR_DIR = "WEB-INF/classes"; public static final String PATH_IN_WAR_APPLET = ""; public static final String PATH_IN_WAR_NONE = null; 426 427 private static final String BROKEN = "BrokenReference"; 430 private Object object; 431 private URI artifactURI; 432 private int type; 433 private String property; 434 private String pathInWar; 435 private String raw; 436 private String eval; 437 438 private Item( int type, Object object, String raw, String eval, String property, String pathInWar) { 439 this.type = type; 440 this.object = object; 441 if (object == null || type == TYPE_CLASSPATH || object == BROKEN || 442 (type == TYPE_JAR && object instanceof File ) || 443 (type == TYPE_ARTIFACT && (object instanceof AntArtifact)) || 444 (type == TYPE_LIBRARY && (object instanceof Library))) { 445 this.raw = raw; 446 this.eval = eval; 447 this.property = property; 448 this.pathInWar = pathInWar; 449 } else { 450 throw new IllegalArgumentException ("invalid classpath item, type=" + type + " object type:" + object.getClass().getName()); 451 } 452 } 453 454 private Item( int type, Object object, String raw, String eval, URI artifactURI, String property, String pathInWar) { 455 this( type, object, raw, eval, property, pathInWar); 456 this.artifactURI = artifactURI; 457 } 458 459 public String getPathInWAR () { 460 return pathInWar; 461 } 462 463 public void setPathInWAR (String pathInWar) { 464 this.pathInWar = pathInWar; 465 } 466 467 public void setRaw(String raw) { 468 this.raw = raw; 469 } 470 471 public String getRaw() { 472 return raw; 473 } 474 475 public String getEvaluated() { 476 return eval == null ? getRaw() : eval; 477 } 478 479 481 482 public static Item create( Library library, String property, String pathInWar) { 483 if ( library == null ) { 484 throw new IllegalArgumentException ( "library must not be null" ); } 486 487 String libraryName = library.getName(); 488 return new Item( TYPE_LIBRARY, library, "${libs."+libraryName+".classpath}", libraryName, property, pathInWar); } 490 491 public static Item create( AntArtifact artifact, URI artifactURI, String property, String pathInWar) { 492 if ( artifactURI == null ) { 493 throw new IllegalArgumentException ( "artifactURI must not be null" ); } 495 if ( artifact == null ) { 496 throw new IllegalArgumentException ( "artifact must not be null" ); } 498 return new Item( TYPE_ARTIFACT, artifact, null, artifact.getArtifactLocations()[0].toString(), artifactURI, property, pathInWar); 499 } 500 501 public static Item create( File file, String property, String pathInWar) { 502 if ( file == null ) { 503 throw new IllegalArgumentException ( "file must not be null" ); } 505 return new Item( TYPE_JAR, file, null, file.getPath(), property, pathInWar); 506 } 507 508 public static Item create( String property, String pathInWar) { 509 if ( property == null ) { 510 throw new IllegalArgumentException ( "property must not be null" ); } 512 return new Item ( TYPE_CLASSPATH, null, null, null, property, pathInWar); 513 } 514 515 public static Item createBroken( int type, String property, String pathInWar) { 516 if ( property == null ) { 517 throw new IllegalArgumentException ( "property must not be null in broken items" ); } 519 return new Item( type, BROKEN, null, null, property, pathInWar); 520 } 521 522 524 public int getType() { 525 return type; 526 } 527 528 public Library getLibrary() { 529 if ( getType() != TYPE_LIBRARY ) { 530 throw new IllegalArgumentException ( "Item is not of required type - LIBRARY" ); } 532 if (isBroken()) { 533 return null; 534 } 535 return (Library)object; 536 } 537 538 public File getFile() { 539 if ( getType() != TYPE_JAR ) { 540 throw new IllegalArgumentException ( "Item is not of required type - JAR" ); } 542 if (isBroken()) { 543 return null; 544 } 545 return (File )object; 546 } 547 548 public AntArtifact getArtifact() { 549 if ( getType() != TYPE_ARTIFACT ) { 550 throw new IllegalArgumentException ( "Item is not of required type - ARTIFACT" ); } 552 if (isBroken()) { 553 return null; 554 } 555 return (AntArtifact)object; 556 } 557 558 public URI getArtifactURI() { 559 if ( getType() != TYPE_ARTIFACT ) { 560 throw new IllegalArgumentException ( "Item is not of required type - ARTIFACT" ); } 562 return artifactURI; 563 } 564 565 public Object getObject() { 566 return object; 567 } 568 569 public boolean canDelete() { 570 return getType() != TYPE_CLASSPATH; 571 } 572 573 public String getReference() { 574 return property; 575 } 576 577 public void setReference(String property) { 578 this.property = property; 579 } 580 581 public boolean isBroken() { 582 return object == BROKEN; 583 } 584 585 public int hashCode() { 586 587 int hash = getType(); 588 589 if ( object == BROKEN ) { 590 return BROKEN.hashCode(); 591 } 592 593 switch ( getType() ) { 594 case TYPE_ARTIFACT: 595 hash += getArtifact().getType().hashCode(); 596 hash += getArtifact().getScriptLocation().hashCode(); 597 hash += getArtifactURI().hashCode(); 598 break; 599 case TYPE_CLASSPATH: 600 hash += property.hashCode(); 601 break; 602 default: 603 hash += object.hashCode(); 604 } 605 606 return hash; 607 } 608 609 public boolean equals( Object itemObject ) { 610 611 if ( !( itemObject instanceof Item ) ) { 612 return false; 613 } 614 615 Item item = (Item)itemObject; 616 617 if ( getType() != item.getType() ) { 618 return false; 619 } 620 621 if ( isBroken() != item.isBroken() ) { 622 return false; 623 } 624 625 if ( isBroken() ) { 626 return getReference().equals( item.getReference() ); 627 } 628 629 switch ( getType() ) { 630 case TYPE_ARTIFACT: 631 if (!(getArtifact().getType()).equals(item.getArtifact().getType())) { 632 return false; 633 } 634 635 if ( !getArtifact().getScriptLocation().equals( item.getArtifact().getScriptLocation() ) ) { 636 return false; 637 } 638 639 if ( !getArtifactURI().equals( item.getArtifactURI() ) ) { 640 return false; 641 } 642 return true; 643 case TYPE_CLASSPATH: 644 return property.equals( item.property ); 645 default: 646 return object.equals( item.object ); 647 } 648 649 } 650 651 public String toString() { 652 return "artifactURI=" + artifactURI 653 + ", type=" + type 654 + ", property=" + property 655 + ", pathInWar=" + pathInWar 656 + ", raw=" + raw 657 + ", eval=" + eval 658 + ", object=" + object; 659 } 660 661 } 662 663 } 664 | Popular Tags |