~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to j2ee/clientproject/src/org/netbeans/modules/j2ee/clientproject/classpath/ClassPathSupport.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.j2ee.clientproject.classpath;
 
43
 
 
44
import java.io.File;
 
45
import java.net.URI;
 
46
import java.util.ArrayList;
 
47
import java.util.Arrays;
 
48
import java.util.Collections;
 
49
import java.util.HashSet;
 
50
import java.util.Iterator;
 
51
import java.util.LinkedList;
 
52
import java.util.List;
 
53
import java.util.Set;
 
54
import org.netbeans.api.project.ant.AntArtifact;
 
55
import org.netbeans.api.project.libraries.Library;
 
56
import org.netbeans.api.project.libraries.LibraryManager;
 
57
import org.netbeans.api.queries.CollocationQuery;
 
58
import org.netbeans.modules.j2ee.clientproject.AppClientProjectType;
 
59
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
 
60
import org.netbeans.spi.project.support.ant.AntProjectHelper;
 
61
import org.netbeans.spi.project.support.ant.EditableProperties;
 
62
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
 
63
import org.netbeans.spi.project.support.ant.PropertyUtils;
 
64
import org.netbeans.spi.project.support.ant.ReferenceHelper;
 
65
import org.openide.filesystems.FileUtil;
 
66
import org.w3c.dom.Document;
 
67
import org.w3c.dom.Element;
 
68
import org.w3c.dom.Node;
 
69
import org.w3c.dom.NodeList;
 
70
import org.w3c.dom.Text;
 
71
 
 
72
/**
 
73
 *
 
74
 * @author Petr Hrebejk
 
75
 */
 
76
public class ClassPathSupport {
 
77
     
 
78
    public final static String ELEMENT_INCLUDED_LIBRARIES = "included-library"; // NOI18N
 
79
    
 
80
    private static final String ATTR_FILES = "files"; //NOI18N
 
81
    private static final String ATTR_DIRS = "dirs"; //NOI18N
 
82
    
 
83
    private PropertyEvaluator evaluator;
 
84
    private ReferenceHelper referenceHelper;
 
85
    private AntProjectHelper antProjectHelper;
 
86
    private Set<String> wellKnownPaths;
 
87
    private String libraryPrefix;
 
88
    private String librarySuffix;
 
89
    private String antArtifactPrefix;
 
90
        
 
91
    /** Creates a new instance of ClassPathSupport */
 
92
    public  ClassPathSupport( PropertyEvaluator evaluator, 
 
93
                              ReferenceHelper referenceHelper,
 
94
                              AntProjectHelper antProjectHelper,
 
95
                              String wellKnownPaths[],
 
96
                              String libraryPrefix,
 
97
                              String librarySuffix,
 
98
                              String antArtifactPrefix ) {
 
99
        this.evaluator = evaluator;
 
100
        this.referenceHelper = referenceHelper;
 
101
        this.antProjectHelper = antProjectHelper;
 
102
        this.wellKnownPaths = wellKnownPaths == null ? null : new HashSet<String>( Arrays.asList( wellKnownPaths ) );
 
103
        this.libraryPrefix = libraryPrefix;
 
104
        this.librarySuffix = librarySuffix;
 
105
        this.antArtifactPrefix = antArtifactPrefix;
 
106
    }
 
107
    
 
108
    /** Creates list of <CODE>Items</CODE> from given property.
 
109
     */    
 
110
    public Iterator<Item> itemsIterator( String propertyValue, String includedLibrariesElement ) {
 
111
        // XXX More performance frendly impl. would retrun a lazzy iterator.
 
112
        return itemsList( propertyValue, includedLibrariesElement ).iterator();
 
113
    }
 
114
    
 
115
    public List<Item> itemsList( String propertyValue, String includedLibrariesElement ) {
 
116
        
 
117
        // Get the list of items which are included in deployment
 
118
        List<String> includedItems = (includedLibrariesElement != null) ?
 
119
            getIncludedLibraries( antProjectHelper, includedLibrariesElement ) : 
 
120
            Collections.<String>emptyList();
 
121
        
 
122
        String pe[] = PropertyUtils.tokenizePath( propertyValue == null ? "": propertyValue ); // NOI18N        
 
123
        List<Item> items = new ArrayList<Item>( pe.length );
 
124
        for( int i = 0; i < pe.length; i++ ) {
 
125
            String property = getAntPropertyName( pe[i] );
 
126
            Item item;
 
127
 
 
128
            // First try to find out whether the item is well known classpath
 
129
            if ( isWellKnownPath( pe[i] ) ) {
 
130
                // Some well know classpath
 
131
                item = Item.create( pe[i], false );
 
132
            } 
 
133
            else if ( isLibrary( pe[i] ) ) {
 
134
                //Library from library manager
 
135
                String libraryName = pe[i].substring( libraryPrefix.length(), pe[i].lastIndexOf('.') ); //NOI18N
 
136
                Library library = LibraryManager.getDefault().getLibrary( libraryName );
 
137
                if ( library == null ) {
 
138
                    item = Item.createBroken( Item.TYPE_LIBRARY, pe[i], includedItems.contains( property ) );
 
139
                }
 
140
                else {
 
141
                    item = Item.create( library, pe[i], includedItems.contains( property ) );
 
142
                }               
 
143
            } 
 
144
            else if ( isAntArtifact( pe[i] ) ) {
 
145
                // Ant artifact from another project
 
146
                Object[] ret = referenceHelper.findArtifactAndLocation(pe[i]);
 
147
                if ( ret[0] == null || ret[1] == null ) {
 
148
                    item = Item.createBroken( Item.TYPE_ARTIFACT, pe[i], includedItems.contains ( property ) );
 
149
                }
 
150
                else {
 
151
                    //fix of issue #55391
 
152
                    AntArtifact artifact = (AntArtifact)ret[0];
 
153
                    URI uri = (URI)ret[1];
 
154
                    File usedFile = antProjectHelper.resolveFile(evaluator.evaluate(pe[i]));
 
155
                    File artifactFile = new File (artifact.getScriptLocation().toURI().resolve(uri).normalize());
 
156
                    if (usedFile.equals(artifactFile)) {
 
157
                        item = Item.create( artifact, uri, pe[i], includedItems.contains ( property ) );
 
158
                    }
 
159
                    else {
 
160
                        item = Item.createBroken( Item.TYPE_ARTIFACT, pe[i], includedItems.contains ( property ) );
 
161
                    }
 
162
                }
 
163
            } else {
 
164
                // Standalone jar or property
 
165
                String eval = evaluator.evaluate( pe[i] );
 
166
                File f = null;
 
167
                if (eval != null) {
 
168
                    f = antProjectHelper.resolveFile( eval );
 
169
                }                    
 
170
                
 
171
                if ( f == null || !f.exists() ) {
 
172
                    item = Item.createBroken( f, pe[i], includedItems.contains ( property ) );
 
173
                }
 
174
                else {
 
175
                    item = Item.create( f, pe[i], includedItems.contains ( property ) );
 
176
                }
 
177
            }
 
178
            
 
179
            items.add( item );
 
180
           
 
181
        }
 
182
 
 
183
        return items;
 
184
        
 
185
    }
 
186
    
 
187
    /** Converts list of classpath items into array of Strings.
 
188
     * !! This method creates references in the project !!
 
189
     * !! This method may add <included-library> items to project.xml !!
 
190
     */
 
191
    public String[] encodeToStrings( Iterator /*<Item>*/ classpath, String includedLibrariesElement ) {
 
192
        
 
193
        List<String> result = new ArrayList<String>();
 
194
        List<String> includedLibraries = new ArrayList<String>();
 
195
        
 
196
        List<Item> cp = new LinkedList<Item>();
 
197
        
 
198
        while( classpath.hasNext() ) {
 
199
 
 
200
            Item item = (Item)classpath.next();
 
201
            cp.add(item);
 
202
            String reference = null;
 
203
            
 
204
            switch( item.getType() ) {
 
205
 
 
206
                case Item.TYPE_JAR:
 
207
                    reference = item.getReference();
 
208
                    if ( item.isBroken() ) {
 
209
                        break;
 
210
                    }
 
211
                    if (reference == null) {
 
212
                        // New file
 
213
                        File file = item.getFile();
 
214
                        // pass null as expected artifact type to always get file reference
 
215
                        reference = referenceHelper.createForeignFileReference(file, null);
 
216
                        item.setReference(reference);
 
217
                    }
 
218
                    break;
 
219
                case Item.TYPE_LIBRARY:
 
220
                    reference = item.getReference();
 
221
                    if ( item.isBroken() ) {
 
222
                        break;
 
223
                    }                    
 
224
                    Library library = item.getLibrary();                                       
 
225
                    if (reference == null) {
 
226
                        if ( library == null ) {
 
227
                            break;
 
228
                        }
 
229
                        reference = getLibraryReference( item );
 
230
                        item.setReference(reference);
 
231
                    }
 
232
                    break;    
 
233
                case Item.TYPE_ARTIFACT:
 
234
                    reference = item.getReference();
 
235
                    if ( item.isBroken() ) {
 
236
                        break;
 
237
                    }
 
238
                    AntArtifact artifact = item.getArtifact();                                       
 
239
                    if ( reference == null) {
 
240
                        if ( artifact == null ) {
 
241
                            break;
 
242
                        }
 
243
                        reference = referenceHelper.addReference( item.getArtifact(), item.getArtifactURI());
 
244
                        item.setReference(reference);
 
245
                    }
 
246
                    break;
 
247
                case Item.TYPE_CLASSPATH:
 
248
                    reference = item.getReference();
 
249
                    break;
 
250
            }
 
251
            
 
252
            if ( reference != null ) {
 
253
                result.add( reference );
 
254
                
 
255
                // Add the item to the list of items included in deployment
 
256
                if ( includedLibrariesElement != null && item.isIncludedInDeployment() ) {
 
257
                    includedLibraries.add( getAntPropertyName( reference ) );
 
258
                }
 
259
            }
 
260
            
 
261
        }
 
262
        
 
263
        if ( includedLibrariesElement != null ) {
 
264
            putIncludedLibraries( includedLibraries, cp, antProjectHelper, includedLibrariesElement );
 
265
        }
 
266
 
 
267
        String[] items = new String[ result.size() ];
 
268
        for( int i = 0; i < result.size(); i++) {
 
269
            if ( i < result.size() - 1 ) {
 
270
                items[i] = result.get( i ) + ":"; // NOI18N
 
271
            }
 
272
            else  {       
 
273
                items[i] = result.get( i );    //NOI18N
 
274
            }
 
275
        }
 
276
        
 
277
        return items;
 
278
    }
 
279
    
 
280
    public String getLibraryReference( Item item ) {
 
281
        if ( item.getType() != Item.TYPE_LIBRARY ) {
 
282
            throw new IllegalArgumentException( "Item must be of type LIBRARY" ); // NOI18N
 
283
        }
 
284
        return libraryPrefix + item.getLibrary().getName() + librarySuffix;        
 
285
    }
 
286
    
 
287
    // Private methods ---------------------------------------------------------
 
288
 
 
289
    private boolean isWellKnownPath( String property ) {
 
290
        return wellKnownPaths == null ? false : wellKnownPaths.contains( property );
 
291
    }
 
292
    
 
293
    private boolean isAntArtifact( String property ) {        
 
294
        return antArtifactPrefix == null ? false : property.startsWith( antArtifactPrefix );
 
295
    }
 
296
    
 
297
    private boolean isLibrary( String property ) {
 
298
        if ( libraryPrefix != null && property.startsWith( libraryPrefix ) ) {
 
299
            return librarySuffix == null ? true : property.endsWith( librarySuffix );
 
300
        }
 
301
        else {
 
302
            return false;
 
303
        }
 
304
        
 
305
    }
 
306
        
 
307
    // Private static methods --------------------------------------------------
 
308
    
 
309
    /** 
 
310
     * Returns a list with the classpath items which are to be included 
 
311
     * in deployment.
 
312
     */
 
313
    private static List<String> getIncludedLibraries( AntProjectHelper antProjectHelper, String includedLibrariesElement ) {
 
314
        assert antProjectHelper != null;
 
315
        assert includedLibrariesElement != null;
 
316
        
 
317
        Element data = antProjectHelper.getPrimaryConfigurationData( true );
 
318
        NodeList libs = data.getElementsByTagNameNS( AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, includedLibrariesElement );
 
319
        List<String> libraries = new ArrayList<String>(libs.getLength());
 
320
        for ( int i = 0; i < libs.getLength(); i++ ) {
 
321
            Element item = (Element)libs.item( i );
 
322
            libraries.add( findText( item ));
 
323
        }
 
324
        return libraries;
 
325
    }
 
326
    
 
327
    /**
 
328
     * Updates the project helper with the list of classpath items which are to be
 
329
     * included in deployment.
 
330
     */
 
331
    private static void putIncludedLibraries( List<String> libraries, List<Item> classpath,
 
332
            AntProjectHelper antProjectHelper, String includedLibrariesElement ) {
 
333
        assert libraries != null;
 
334
        assert antProjectHelper != null;
 
335
        assert includedLibrariesElement != null;
 
336
        
 
337
        Element data = antProjectHelper.getPrimaryConfigurationData( true );
 
338
        NodeList libs = data.getElementsByTagNameNS( AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, includedLibrariesElement );
 
339
        while ( libs.getLength() > 0 ) {
 
340
            Node n = libs.item( 0 );
 
341
            n.getParentNode().removeChild( n );
 
342
        }
 
343
 
 
344
        Document doc = data.getOwnerDocument();
 
345
        for (String libraryName : libraries) {
 
346
            //find a correcponding classpath item for the library
 
347
            for (ClassPathSupport.Item item : classpath) {
 
348
                String libraryPropName = "${" + libraryName + "}"; // NOI18N
 
349
                if(libraryPropName.equals(item.getReference())) {
 
350
                    data.appendChild(createLibraryElement(doc, libraryName, item, includedLibrariesElement));
 
351
                }
 
352
            }
 
353
        }
 
354
        
 
355
        antProjectHelper.putPrimaryConfigurationData( data, true );
 
356
    }
 
357
    
 
358
    private static Element createLibraryElement(Document doc, String pathItem, Item item, String includedLibrariesElement ) {
 
359
        Element libraryElement = doc.createElementNS( AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, includedLibrariesElement );
 
360
        List<File> files = new ArrayList<File>();
 
361
        List<File> dirs = new ArrayList<File>();
 
362
        AppClientProjectProperties.getFilesForItem(item, files, dirs);
 
363
        if (files.size() > 0) {
 
364
            libraryElement.setAttribute(ATTR_FILES, "" + files.size());
 
365
        }
 
366
        if (dirs.size() > 0) {
 
367
            libraryElement.setAttribute(ATTR_DIRS, "" + dirs.size());
 
368
        }
 
369
        
 
370
        libraryElement.appendChild( doc.createTextNode( pathItem ) );
 
371
        return libraryElement;
 
372
    }
 
373
       
 
374
    /**
 
375
     * Extracts <b>the first</b> nested text from an element.
 
376
     * Currently does not handle coalescing text nodes, CDATA sections, etc.
 
377
     * @param parent a parent element
 
378
     * @return the nested text, or null if none was found
 
379
     */
 
380
    private static String findText( Element parent ) {
 
381
        NodeList l = parent.getChildNodes();
 
382
        for ( int i = 0; i < l.getLength(); i++ ) {
 
383
            if ( l.item(i).getNodeType() == Node.TEXT_NODE ) {
 
384
                Text text = (Text)l.item( i );
 
385
                return text.getNodeValue();
 
386
            }
 
387
        }
 
388
        return null;
 
389
    }
 
390
 
 
391
    // Innerclasses ------------------------------------------------------------
 
392
    
 
393
    /** Item of the classpath.
 
394
     */    
 
395
    public static class Item {
 
396
        
 
397
        // Types of the classpath elements
 
398
        public static final int TYPE_JAR = 0;
 
399
        public static final int TYPE_LIBRARY = 1;
 
400
        public static final int TYPE_ARTIFACT = 2;
 
401
        public static final int TYPE_CLASSPATH = 3;
 
402
 
 
403
        private Object object;
 
404
        private URI artifactURI;
 
405
        private int type;
 
406
        private String property;
 
407
        private boolean includedInDeployment;
 
408
        private String raw;
 
409
        private final boolean broken;
 
410
        
 
411
        private Item(int type, Object object, String property, boolean included, String raw, boolean broken) {
 
412
            this.type = type;
 
413
            this.object = object;
 
414
            this.property = property;
 
415
            this.includedInDeployment = included;
 
416
            this.raw = raw;
 
417
            this.broken = broken;
 
418
        }
 
419
        
 
420
        private Item( int type, Object object, URI artifactURI, String property, boolean included ) {
 
421
            this(type, object, property, included, null, false);
 
422
            this.artifactURI = artifactURI;
 
423
        }
 
424
        
 
425
        private Item(int type, Object object, String property, boolean included, String raw) {
 
426
            this(type, object, property, included, null, false);
 
427
        }
 
428
              
 
429
        // Factory methods -----------------------------------------------------
 
430
        
 
431
        
 
432
        public static Item create( Library library, String property, boolean included ) {
 
433
            if ( library == null ) {
 
434
                throw new IllegalArgumentException( "library must not be null" ); // NOI18N
 
435
            }
 
436
            String libraryName = library.getName();
 
437
            return new Item( TYPE_LIBRARY, library, property, included, AppClientProjectProperties.LIBRARY_PREFIX + libraryName + AppClientProjectProperties.LIBRARY_SUFFIX);
 
438
        }
 
439
        
 
440
        public static Item create( AntArtifact artifact, URI artifactURI, String property, boolean included ) {
 
441
            if ( artifactURI == null ) {
 
442
                throw new IllegalArgumentException( "artifactURI must not be null" ); // NOI18N
 
443
            }
 
444
            if ( artifact == null ) {
 
445
                throw new IllegalArgumentException( "artifact must not be null" ); // NOI18N
 
446
            }
 
447
            return new Item( TYPE_ARTIFACT, artifact, artifactURI, property, included );
 
448
        }
 
449
        
 
450
        public static Item create( File file, String property, boolean included ) {
 
451
            if ( file == null ) {
 
452
                throw new IllegalArgumentException( "file must not be null" ); // NOI18N
 
453
            }
 
454
            return new Item( TYPE_JAR, file, property, included, null );
 
455
        }
 
456
        
 
457
        public static Item create( String property, boolean included ) {
 
458
            if ( property == null ) {
 
459
                throw new IllegalArgumentException( "property must not be null" ); // NOI18N
 
460
            }
 
461
            return new Item ( TYPE_CLASSPATH, null, property, included, null );
 
462
        }
 
463
        
 
464
        public static Item createBroken( int type, String property, boolean included ) {
 
465
            if ( property == null ) {
 
466
                throw new IllegalArgumentException( "property must not be null in broken items" ); // NOI18N
 
467
            }
 
468
            return new Item(type, null, property, included, null, true);
 
469
        }
 
470
        
 
471
        public static Item createBroken(File file, String property, boolean included) {
 
472
            return new Item(TYPE_JAR, file, property, included, null, true);
 
473
        }
 
474
        
 
475
        // Instance methods ----------------------------------------------------
 
476
        
 
477
        public String getRaw() {
 
478
            return raw;
 
479
        }
 
480
        
 
481
        public int getType() {
 
482
            return type;
 
483
        }
 
484
        
 
485
        public Library getLibrary() {
 
486
            if ( getType() != TYPE_LIBRARY ) {
 
487
                throw new IllegalArgumentException( "Item is not of required type - LIBRARY" ); // NOI18N
 
488
            }
 
489
            if (isBroken()) {
 
490
                return null;
 
491
            }
 
492
            return (Library)object;
 
493
        }
 
494
        
 
495
        public File getFile() {
 
496
            if ( getType() != TYPE_JAR ) {
 
497
                throw new IllegalArgumentException( "Item is not of required type - JAR" ); // NOI18N
 
498
            }
 
499
            // for broken item: one will get java.io.File or null (#113390)
 
500
            return (File)object;
 
501
        }
 
502
        
 
503
        public AntArtifact getArtifact() {
 
504
            if ( getType() != TYPE_ARTIFACT ) {
 
505
                throw new IllegalArgumentException( "Item is not of required type - ARTIFACT" ); // NOI18N
 
506
            }
 
507
            if (isBroken()) {
 
508
                return null;
 
509
            }
 
510
            return (AntArtifact)object;
 
511
        }
 
512
        
 
513
        public URI getArtifactURI() {
 
514
            if ( getType() != TYPE_ARTIFACT ) {
 
515
                throw new IllegalArgumentException( "Item is not of required type - ARTIFACT" ); // NOI18N
 
516
            }
 
517
            return artifactURI;
 
518
        }
 
519
        
 
520
        
 
521
        public String getReference() {
 
522
            return property;
 
523
        }
 
524
        
 
525
        public void setReference(String property) {
 
526
            this.property = property;
 
527
        }
 
528
 
 
529
        public boolean isIncludedInDeployment() {
 
530
//            boolean result = includedInDeployment;
 
531
//            if (getType() == TYPE_JAR) {
 
532
                // at the moment we can't include folders in deployment
 
533
//                FileObject fo = FileUtil.toFileObject(getFile());
 
534
//                if (fo == null || fo.isFolder())
 
535
//                    return false;
 
536
//            }
 
537
            return includedInDeployment;
 
538
        }
 
539
        
 
540
        public void setIncludedInDeployment(boolean includedInDeployment) {
 
541
            this.includedInDeployment = includedInDeployment;
 
542
        }
 
543
        
 
544
        public boolean isBroken() {
 
545
            return broken;
 
546
        }
 
547
        
 
548
        @Override
 
549
        public String toString() {
 
550
            return "artifactURI=" + artifactURI // NOI18N
 
551
                    + ", type=" + type // NOI18N
 
552
                    + ", property=" + property // NOI18N
 
553
                    + ", includedInDeployment=" + includedInDeployment // NOI18N
 
554
                    + ", raw=" + raw // NOI18N
 
555
                    + ", object=" + object // NOI18N
 
556
                    + ", broken=" + broken; // NOI18N
 
557
        }
 
558
        
 
559
        @Override
 
560
        public int hashCode() {
 
561
        
 
562
            int hash = getType();
 
563
 
 
564
            if (isBroken()) {
 
565
                return 42;
 
566
            }
 
567
            
 
568
            switch ( getType() ) {
 
569
                case TYPE_ARTIFACT:
 
570
                    hash += getArtifact().getType().hashCode();                
 
571
                    hash += getArtifact().getScriptLocation().hashCode();
 
572
                    hash += getArtifactURI().hashCode();
 
573
                    break;
 
574
                case TYPE_CLASSPATH:
 
575
                    hash += property.hashCode();
 
576
                    break;
 
577
                default:
 
578
                    hash += object.hashCode();
 
579
            }
 
580
 
 
581
            return hash;
 
582
        }
 
583
    
 
584
        @Override
 
585
        public boolean equals( Object itemObject ) {
 
586
 
 
587
            if ( !( itemObject instanceof Item ) ) {
 
588
                return false;
 
589
            }
 
590
            
 
591
            Item item = (Item)itemObject;
 
592
 
 
593
            if ( getType() != item.getType() ) {
 
594
                return false;
 
595
            }
 
596
            
 
597
            if ( isBroken() != item.isBroken() ) {
 
598
                return false;
 
599
            }
 
600
            
 
601
            if ( isBroken() ) {
 
602
                return getReference().equals( item.getReference() );
 
603
            }
 
604
 
 
605
            switch ( getType() ) {
 
606
                case TYPE_ARTIFACT:
 
607
                    if ( getArtifact().getType() != item.getArtifact().getType() ) {
 
608
                        return false;
 
609
                    }
 
610
 
 
611
                    if ( !getArtifact().getScriptLocation().equals( item.getArtifact().getScriptLocation() ) ) {
 
612
                        return false;
 
613
                    }
 
614
 
 
615
                    if ( !getArtifactURI().equals( item.getArtifactURI() ) ) {
 
616
                        return false;
 
617
                    }
 
618
                    return true;
 
619
                case TYPE_CLASSPATH:
 
620
                    return property.equals( item.property );
 
621
                default:
 
622
                    return this.object.equals( item.object );
 
623
            }
 
624
 
 
625
        }
 
626
                
 
627
    }
 
628
            
 
629
 
 
630
    
 
631
    /**
 
632
     * Tokenize library classpath and try to relativize all the jars.
 
633
     * @param ep the editable properties in which the result should be stored
 
634
     * @param aph AntProjectHelper used to resolve files
 
635
     * @param libCpProperty the library classpath property
 
636
     */
 
637
    public static boolean relativizeLibraryClassPath (final EditableProperties ep, final AntProjectHelper aph, final String libCpProperty) {
 
638
        String value = PropertyUtils.getGlobalProperties().getProperty(libCpProperty);
 
639
        // bugfix #42852, check if the classpath property is set, otherwise return null
 
640
        if (value == null) {
 
641
            return false;
 
642
        }
 
643
        String[] paths = PropertyUtils.tokenizePath(value);
 
644
        StringBuffer sb = new StringBuffer();
 
645
        File projectDir = FileUtil.toFile(aph.getProjectDirectory());
 
646
        for (int i=0; i<paths.length; i++) {
 
647
            File f = aph.resolveFile(paths[i]);
 
648
            if (CollocationQuery.areCollocated(f, projectDir)) {
 
649
                sb.append(PropertyUtils.relativizeFile(projectDir, f));
 
650
            } else {
 
651
                return false;
 
652
            }
 
653
            if (i+1<paths.length) {
 
654
                sb.append(File.pathSeparatorChar);
 
655
            }
 
656
        }
 
657
        if (sb.length() == 0) {
 
658
            return false;
 
659
        }            
 
660
        ep.setProperty(libCpProperty, sb.toString());
 
661
        ep.setComment(libCpProperty, new String[]{
 
662
            // XXX this should be I18N! Not least because the English is wrong...
 
663
            "# Property "+libCpProperty+" is set here just to make sharing of project simpler.", // NOI18N
 
664
            "# The library definition has always preference over this property."}, false); // NOI18N
 
665
        return true;
 
666
    }
 
667
    
 
668
    /**
 
669
     * Converts the ant reference to the name of the referenced property
 
670
     * @param ant reference
 
671
     * @param the name of the referenced property
 
672
     */ 
 
673
    public static String getAntPropertyName( String property ) {
 
674
        if ( property != null && 
 
675
             property.startsWith( "${" ) && // NOI18N
 
676
             property.endsWith( "}" ) ) { // NOI18N
 
677
            return property.substring( 2, property.length() - 1 ); 
 
678
        }
 
679
        else {
 
680
            return property;
 
681
        }
 
682
    }
 
683
            
 
684
}