1 19 20 package org.netbeans.modules.j2ee.clientproject.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.Collections ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.LinkedList ; 30 import java.util.List ; 31 import java.util.Set ; 32 import org.netbeans.api.project.ant.AntArtifact; 33 import org.netbeans.api.project.libraries.Library; 34 import org.netbeans.api.project.libraries.LibraryManager; 35 import org.netbeans.api.queries.CollocationQuery; 36 import org.netbeans.modules.j2ee.clientproject.AppClientProjectType; 37 import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties; 38 import org.netbeans.spi.project.support.ant.AntProjectHelper; 39 import org.netbeans.spi.project.support.ant.EditableProperties; 40 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 41 import org.netbeans.spi.project.support.ant.PropertyUtils; 42 import org.netbeans.spi.project.support.ant.ReferenceHelper; 43 import org.openide.filesystems.FileUtil; 44 import org.w3c.dom.Document ; 45 import org.w3c.dom.Element ; 46 import org.w3c.dom.Node ; 47 import org.w3c.dom.NodeList ; 48 import org.w3c.dom.Text ; 49 50 54 public class ClassPathSupport { 55 56 public final static String ELEMENT_INCLUDED_LIBRARIES = "included-library"; 58 private static final String ATTR_FILES = "files"; private static final String ATTR_DIRS = "dirs"; 61 private PropertyEvaluator evaluator; 62 private ReferenceHelper referenceHelper; 63 private AntProjectHelper antProjectHelper; 64 private Set <String > wellKnownPaths; 65 private String libraryPrefix; 66 private String librarySuffix; 67 private String antArtifactPrefix; 68 69 70 public ClassPathSupport( PropertyEvaluator evaluator, 71 ReferenceHelper referenceHelper, 72 AntProjectHelper antProjectHelper, 73 String wellKnownPaths[], 74 String libraryPrefix, 75 String librarySuffix, 76 String antArtifactPrefix ) { 77 this.evaluator = evaluator; 78 this.referenceHelper = referenceHelper; 79 this.antProjectHelper = antProjectHelper; 80 this.wellKnownPaths = wellKnownPaths == null ? null : new HashSet <String >( Arrays.asList( wellKnownPaths ) ); 81 this.libraryPrefix = libraryPrefix; 82 this.librarySuffix = librarySuffix; 83 this.antArtifactPrefix = antArtifactPrefix; 84 } 85 86 88 public Iterator <Item> itemsIterator( String propertyValue, String includedLibrariesElement ) { 89 return itemsList( propertyValue, includedLibrariesElement ).iterator(); 91 } 92 93 public List <Item> itemsList( String propertyValue, String includedLibrariesElement ) { 94 95 List <String > includedItems = (includedLibrariesElement != null) ? 97 getIncludedLibraries( antProjectHelper, includedLibrariesElement ) : 98 Collections.<String >emptyList(); 99 100 String pe[] = PropertyUtils.tokenizePath( propertyValue == null ? "": propertyValue ); List <Item> items = new ArrayList <Item>( pe.length ); 102 for( int i = 0; i < pe.length; i++ ) { 103 String property = getAntPropertyName( pe[i] ); 104 Item item; 105 106 if ( isWellKnownPath( pe[i] ) ) { 108 item = Item.create( pe[i], false ); 110 } 111 else if ( isLibrary( pe[i] ) ) { 112 String libraryName = pe[i].substring( libraryPrefix.length(), pe[i].lastIndexOf('.') ); Library library = LibraryManager.getDefault().getLibrary( libraryName ); 115 if ( library == null ) { 116 item = Item.createBroken( Item.TYPE_LIBRARY, pe[i], includedItems.contains( property ) ); 117 } 118 else { 119 item = Item.create( library, pe[i], includedItems.contains( property ) ); 120 } 121 } 122 else if ( isAntArtifact( pe[i] ) ) { 123 Object [] ret = referenceHelper.findArtifactAndLocation(pe[i]); 125 if ( ret[0] == null || ret[1] == null ) { 126 item = Item.createBroken( Item.TYPE_ARTIFACT, pe[i], includedItems.contains ( property ) ); 127 } 128 else { 129 AntArtifact artifact = (AntArtifact)ret[0]; 131 URI uri = (URI )ret[1]; 132 File usedFile = antProjectHelper.resolveFile(evaluator.evaluate(pe[i])); 133 File artifactFile = new File (artifact.getScriptLocation().toURI().resolve(uri).normalize()); 134 if (usedFile.equals(artifactFile)) { 135 item = Item.create( artifact, uri, pe[i], includedItems.contains ( property ) ); 136 } 137 else { 138 item = Item.createBroken( Item.TYPE_ARTIFACT, pe[i], includedItems.contains ( property ) ); 139 } 140 } 141 } else { 142 String eval = evaluator.evaluate( pe[i] ); 144 File f = null; 145 if (eval != null) { 146 f = antProjectHelper.resolveFile( eval ); 147 } 148 149 if ( f == null || !f.exists() ) { 150 item = Item.createBroken( Item.TYPE_JAR, pe[i], includedItems.contains ( property ) ); 151 } 152 else { 153 item = Item.create( f, pe[i], includedItems.contains ( property ) ); 154 } 155 } 156 157 items.add( item ); 158 159 } 160 161 return items; 162 163 } 164 165 169 public String [] encodeToStrings( Iterator classpath, String includedLibrariesElement ) { 170 171 List <String > result = new ArrayList <String >(); 172 List <String > includedLibraries = new ArrayList <String >(); 173 174 List <Item> cp = new LinkedList <Item>(); 175 176 while( classpath.hasNext() ) { 177 178 Item item = (Item)classpath.next(); 179 cp.add(item); 180 String reference = null; 181 182 switch( item.getType() ) { 183 184 case Item.TYPE_JAR: 185 reference = item.getReference(); 186 if ( item.isBroken() ) { 187 break; 188 } 189 if (reference == null) { 190 File file = item.getFile(); 192 reference = referenceHelper.createForeignFileReference(file, null); 194 item.setReference(reference); 195 } 196 break; 197 case Item.TYPE_LIBRARY: 198 reference = item.getReference(); 199 if ( item.isBroken() ) { 200 break; 201 } 202 Library library = item.getLibrary(); 203 if (reference == null) { 204 if ( library == null ) { 205 break; 206 } 207 reference = getLibraryReference( item ); 208 item.setReference(reference); 209 } 210 break; 211 case Item.TYPE_ARTIFACT: 212 reference = item.getReference(); 213 if ( item.isBroken() ) { 214 break; 215 } 216 AntArtifact artifact = (AntArtifact)item.getArtifact(); 217 if ( reference == null) { 218 if ( artifact == null ) { 219 break; 220 } 221 reference = referenceHelper.addReference( item.getArtifact(), item.getArtifactURI()); 222 item.setReference(reference); 223 } 224 break; 225 case Item.TYPE_CLASSPATH: 226 reference = item.getReference(); 227 break; 228 } 229 230 if ( reference != null ) { 231 result.add( reference ); 232 233 if ( includedLibrariesElement != null && item.isIncludedInDeployment() ) { 235 includedLibraries.add( getAntPropertyName( reference ) ); 236 } 237 } 238 239 } 240 241 if ( includedLibrariesElement != null ) { 242 putIncludedLibraries( includedLibraries, cp, antProjectHelper, includedLibrariesElement ); 243 } 244 245 String [] items = new String [ result.size() ]; 246 for( int i = 0; i < result.size(); i++) { 247 if ( i < result.size() - 1 ) { 248 items[i] = result.get( i ) + ":"; } 250 else { 251 items[i] = result.get( i ); } 253 } 254 255 return items; 256 } 257 258 public String getLibraryReference( Item item ) { 259 if ( item.getType() != Item.TYPE_LIBRARY ) { 260 throw new IllegalArgumentException ( "Item must be of type LIBRARY" ); } 262 return libraryPrefix + item.getLibrary().getName() + librarySuffix; 263 } 264 265 267 private boolean isWellKnownPath( String property ) { 268 return wellKnownPaths == null ? false : wellKnownPaths.contains( property ); 269 } 270 271 private boolean isAntArtifact( String property ) { 272 return antArtifactPrefix == null ? false : property.startsWith( antArtifactPrefix ); 273 } 274 275 private boolean isLibrary( String property ) { 276 if ( libraryPrefix != null && property.startsWith( libraryPrefix ) ) { 277 return librarySuffix == null ? true : property.endsWith( librarySuffix ); 278 } 279 else { 280 return false; 281 } 282 283 } 284 285 287 291 private static List <String > getIncludedLibraries( AntProjectHelper antProjectHelper, String includedLibrariesElement ) { 292 assert antProjectHelper != null; 293 assert includedLibrariesElement != null; 294 295 Element data = antProjectHelper.getPrimaryConfigurationData( true ); 296 NodeList libs = data.getElementsByTagNameNS( AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, includedLibrariesElement ); 297 List <String > libraries = new ArrayList <String >(libs.getLength()); 298 for ( int i = 0; i < libs.getLength(); i++ ) { 299 Element item = (Element )libs.item( i ); 300 libraries.add( findText( item )); 301 } 302 return libraries; 303 } 304 305 309 private static void putIncludedLibraries( List <String > libraries, List <Item> classpath, 310 AntProjectHelper antProjectHelper, String includedLibrariesElement ) { 311 assert libraries != null; 312 assert antProjectHelper != null; 313 assert includedLibrariesElement != null; 314 315 Element data = antProjectHelper.getPrimaryConfigurationData( true ); 316 NodeList libs = data.getElementsByTagNameNS( AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, includedLibrariesElement ); 317 while ( libs.getLength() > 0 ) { 318 Node n = libs.item( 0 ); 319 n.getParentNode().removeChild( n ); 320 } 321 322 Document doc = data.getOwnerDocument(); 323 for (String libraryName : libraries) { 324 for (ClassPathSupport.Item item : classpath) { 326 String libraryPropName = "${" + libraryName + "}"; if(libraryPropName.equals(item.getReference())) { 328 data.appendChild(createLibraryElement(doc, libraryName, item, includedLibrariesElement)); 329 } 330 } 331 } 332 333 antProjectHelper.putPrimaryConfigurationData( data, true ); 334 } 335 336 private static Element createLibraryElement(Document doc, String pathItem, Item item, String includedLibrariesElement ) { 337 Element libraryElement = doc.createElementNS( AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, includedLibrariesElement ); 338 List <File > files = new ArrayList <File >(); 339 List <File > dirs = new ArrayList <File >(); 340 AppClientProjectProperties.getFilesForItem(item, files, dirs); 341 if (files.size() > 0) { 342 libraryElement.setAttribute(ATTR_FILES, "" + files.size()); 343 } 344 if (dirs.size() > 0) { 345 libraryElement.setAttribute(ATTR_DIRS, "" + dirs.size()); 346 } 347 348 libraryElement.appendChild( doc.createTextNode( pathItem ) ); 349 return libraryElement; 350 } 351 352 358 private static String findText( Element parent ) { 359 NodeList l = parent.getChildNodes(); 360 for ( int i = 0; i < l.getLength(); i++ ) { 361 if ( l.item(i).getNodeType() == Node.TEXT_NODE ) { 362 Text text = (Text )l.item( i ); 363 return text.getNodeValue(); 364 } 365 } 366 return null; 367 } 368 369 371 373 public static class Item { 374 375 public static final int TYPE_JAR = 0; 377 public static final int TYPE_LIBRARY = 1; 378 public static final int TYPE_ARTIFACT = 2; 379 public static final int TYPE_CLASSPATH = 3; 380 381 private static final String BROKEN = "BrokenReference"; 384 private Object object; 385 private URI artifactURI; 386 private int type; 387 private String property; 388 private boolean includedInDeployment; 389 private String raw; 390 391 private Item( int type, Object object, String property, boolean included, String raw ) { 392 this.type = type; 393 this.object = object; 394 this.property = property; 395 this.includedInDeployment = included; 396 this.raw = raw; 397 } 398 399 private Item( int type, Object object, URI artifactURI, String property, boolean included ) { 400 this( type, object, property, included,null ); 401 this.artifactURI = artifactURI; 402 } 403 404 406 407 public static Item create( Library library, String property, boolean included ) { 408 if ( library == null ) { 409 throw new IllegalArgumentException ( "library must not be null" ); } 411 String libraryName = library.getName(); 412 return new Item( TYPE_LIBRARY, library, property, included, AppClientProjectProperties.LIBRARY_PREFIX + libraryName + AppClientProjectProperties.LIBRARY_SUFFIX); 413 } 414 415 public static Item create( AntArtifact artifact, URI artifactURI, String property, boolean included ) { 416 if ( artifactURI == null ) { 417 throw new IllegalArgumentException ( "artifactURI must not be null" ); } 419 if ( artifact == null ) { 420 throw new IllegalArgumentException ( "artifact must not be null" ); } 422 return new Item( TYPE_ARTIFACT, artifact, artifactURI, property, included ); 423 } 424 425 public static Item create( File file, String property, boolean included ) { 426 if ( file == null ) { 427 throw new IllegalArgumentException ( "file must not be null" ); } 429 return new Item( TYPE_JAR, file, property, included, null ); 430 } 431 432 public static Item create( String property, boolean included ) { 433 if ( property == null ) { 434 throw new IllegalArgumentException ( "property must not be null" ); } 436 return new Item ( TYPE_CLASSPATH, null, property, included, null ); 437 } 438 439 public static Item createBroken( int type, String property, boolean included ) { 440 if ( property == null ) { 441 throw new IllegalArgumentException ( "property must not be null in broken items" ); } 443 return new Item( type, BROKEN, property, included, null ); 444 } 445 446 448 public String getRaw() { 449 return raw; 450 } 451 452 public int getType() { 453 return type; 454 } 455 456 public Library getLibrary() { 457 if ( getType() != TYPE_LIBRARY ) { 458 throw new IllegalArgumentException ( "Item is not of required type - LIBRARY" ); } 460 if (isBroken()) { 461 return null; 462 } 463 return (Library)object; 464 } 465 466 public File getFile() { 467 if ( getType() != TYPE_JAR ) { 468 throw new IllegalArgumentException ( "Item is not of required type - JAR" ); } 470 if (isBroken()) { 471 return null; 472 } 473 return (File )object; 474 } 475 476 public AntArtifact getArtifact() { 477 if ( getType() != TYPE_ARTIFACT ) { 478 throw new IllegalArgumentException ( "Item is not of required type - ARTIFACT" ); } 480 if (isBroken()) { 481 return null; 482 } 483 return (AntArtifact)object; 484 } 485 486 public URI getArtifactURI() { 487 if ( getType() != TYPE_ARTIFACT ) { 488 throw new IllegalArgumentException ( "Item is not of required type - ARTIFACT" ); } 490 return artifactURI; 491 } 492 493 494 public String getReference() { 495 return property; 496 } 497 498 public void setReference(String property) { 499 this.property = property; 500 } 501 502 public boolean isIncludedInDeployment() { 503 return includedInDeployment; 511 } 512 513 public void setIncludedInDeployment(boolean includedInDeployment) { 514 this.includedInDeployment = includedInDeployment; 515 } 516 517 public boolean isBroken() { 518 return object == BROKEN; 519 } 520 521 public String toString() { 522 return "artifactURI=" + artifactURI + ", type=" + type + ", property=" + property + ", includedInDeployment=" + includedInDeployment + ", raw=" + raw + ", object=" + object; } 529 530 public int hashCode() { 531 532 int hash = getType(); 533 534 if ( object == BROKEN ) { 535 return BROKEN.hashCode(); 536 } 537 538 switch ( getType() ) { 539 case TYPE_ARTIFACT: 540 hash += getArtifact().getType().hashCode(); 541 hash += getArtifact().getScriptLocation().hashCode(); 542 hash += getArtifactURI().hashCode(); 543 break; 544 case TYPE_CLASSPATH: 545 hash += property.hashCode(); 546 break; 547 default: 548 hash += object.hashCode(); 549 } 550 551 return hash; 552 } 553 554 public boolean equals( Object itemObject ) { 555 556 if ( !( itemObject instanceof Item ) ) { 557 return false; 558 } 559 560 Item item = (Item)itemObject; 561 562 if ( getType() != item.getType() ) { 563 return false; 564 } 565 566 if ( isBroken() != item.isBroken() ) { 567 return false; 568 } 569 570 if ( isBroken() ) { 571 return getReference().equals( item.getReference() ); 572 } 573 574 switch ( getType() ) { 575 case TYPE_ARTIFACT: 576 if ( getArtifact().getType() != item.getArtifact().getType() ) { 577 return false; 578 } 579 580 if ( !getArtifact().getScriptLocation().equals( item.getArtifact().getScriptLocation() ) ) { 581 return false; 582 } 583 584 if ( !getArtifactURI().equals( item.getArtifactURI() ) ) { 585 return false; 586 } 587 return true; 588 case TYPE_CLASSPATH: 589 return property.equals( item.property ); 590 default: 591 return this.object.equals( item.object ); 592 } 593 594 } 595 596 } 597 598 599 600 606 public static boolean relativizeLibraryClassPath (final EditableProperties ep, final AntProjectHelper aph, final String libCpProperty) { 607 String value = PropertyUtils.getGlobalProperties().getProperty(libCpProperty); 608 if (value == null) { 610 return false; 611 } 612 String [] paths = PropertyUtils.tokenizePath(value); 613 StringBuffer sb = new StringBuffer (); 614 File projectDir = FileUtil.toFile(aph.getProjectDirectory()); 615 for (int i=0; i<paths.length; i++) { 616 File f = aph.resolveFile(paths[i]); 617 if (CollocationQuery.areCollocated(f, projectDir)) { 618 sb.append(PropertyUtils.relativizeFile(projectDir, f)); 619 } else { 620 return false; 621 } 622 if (i+1<paths.length) { 623 sb.append(File.pathSeparatorChar); 624 } 625 } 626 if (sb.length() == 0) { 627 return false; 628 } 629 ep.setProperty(libCpProperty, sb.toString()); 630 ep.setComment(libCpProperty, new String []{ 631 "# Property "+libCpProperty+" is set here just to make sharing of project simpler.", "# The library definition has always preference over this property."}, false); return true; 635 } 636 637 642 public static String getAntPropertyName( String property ) { 643 if ( property != null && 644 property.startsWith( "${" ) && property.endsWith( "}" ) ) { return property.substring( 2, property.length() - 1 ); 647 } 648 else { 649 return property; 650 } 651 } 652 653 } 654 | Popular Tags |