This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 199253
Collapse All | Expand All

(-)a/java.j2seplatform/nbproject/project.xml (-1 / +1 lines)
Lines 124-130 Link Here
124
                    <compile-dependency/>
124
                    <compile-dependency/>
125
                    <run-dependency>
125
                    <run-dependency>
126
                        <release-version>1</release-version>
126
                        <release-version>1</release-version>
127
                        <specification-version>1.15</specification-version>
127
                        <specification-version>1.31</specification-version>
128
                    </run-dependency>
128
                    </run-dependency>
129
                </dependency>
129
                </dependency>
130
                <dependency>
130
                <dependency>
(-)a/java.j2seplatform/src/org/netbeans/modules/java/j2seplatform/libraries/J2SELibraryTypeProvider.java (-2 / +37 lines)
Lines 71-76 Link Here
71
import java.net.URI;
71
import java.net.URI;
72
import java.util.HashSet;
72
import java.util.HashSet;
73
import java.util.logging.Logger;
73
import java.util.logging.Logger;
74
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
74
import org.openide.util.Exceptions;
75
import org.openide.util.Exceptions;
75
import org.openide.util.Lookup;
76
import org.openide.util.Lookup;
76
import org.openide.util.NbBundle;
77
import org.openide.util.NbBundle;
Lines 101-127 Link Here
101
        VOLUME_TYPE_JAVADOC,
102
        VOLUME_TYPE_JAVADOC,
102
    }));
103
    }));
103
104
105
    @Override
104
    public String getLibraryType() {
106
    public String getLibraryType() {
105
        return LIBRARY_TYPE;
107
        return LIBRARY_TYPE;
106
    }
108
    }
107
    
109
    
110
    @Override
108
    public String getDisplayName () {
111
    public String getDisplayName () {
109
        return NbBundle.getMessage (J2SELibraryTypeProvider.class,"TXT_J2SELibraryType");
112
        return NbBundle.getMessage (J2SELibraryTypeProvider.class,"TXT_J2SELibraryType");
110
    }
113
    }
111
114
115
    @Override
112
    public String[] getSupportedVolumeTypes () {
116
    public String[] getSupportedVolumeTypes () {
113
        return VOLUME_TYPES;
117
        return VOLUME_TYPES;
114
    }
118
    }
115
119
120
    @Override
116
    public LibraryImplementation createLibrary() {
121
    public LibraryImplementation createLibrary() {
117
        return new J2SELibraryImpl ();
122
        return new J2SELibraryImpl ();
118
    }
123
    }
119
124
120
125
126
    @Override
121
    public void libraryCreated(final LibraryImplementation libraryImpl) {
127
    public void libraryCreated(final LibraryImplementation libraryImpl) {
122
        assert libraryImpl != null;
128
        assert libraryImpl != null;
123
        ProjectManager.mutex().postWriteRequest(
129
        ProjectManager.mutex().postWriteRequest(
124
                new Runnable () {
130
                new Runnable () {
131
                    @Override
125
                    public void run () {
132
                    public void run () {
126
                        try {
133
                        try {
127
                            EditableProperties props = PropertyUtils.getGlobalProperties();
134
                            EditableProperties props = PropertyUtils.getGlobalProperties();
Lines 137-145 Link Here
137
        );
144
        );
138
    }
145
    }
139
146
147
    @Override
140
    public void libraryDeleted(final LibraryImplementation libraryImpl) {
148
    public void libraryDeleted(final LibraryImplementation libraryImpl) {
141
        assert libraryImpl != null;
149
        assert libraryImpl != null;
142
        ProjectManager.mutex().postWriteRequest(new Runnable () {
150
        ProjectManager.mutex().postWriteRequest(new Runnable () {
151
                @Override
143
                public void run() {
152
                public void run() {
144
                    try {
153
                    try {
145
                        EditableProperties props = PropertyUtils.getGlobalProperties();
154
                        EditableProperties props = PropertyUtils.getGlobalProperties();
Lines 155-160 Link Here
155
            });
164
            });
156
    }
165
    }
157
166
167
    @Override
158
    public Customizer getCustomizer(String volumeType) {
168
    public Customizer getCustomizer(String volumeType) {
159
        if (VOLUME_TYPES[0].equals(volumeType)||
169
        if (VOLUME_TYPES[0].equals(volumeType)||
160
            VOLUME_TYPES[1].equals(volumeType)||
170
            VOLUME_TYPES[1].equals(volumeType)||
Lines 167-172 Link Here
167
    }
177
    }
168
    
178
    
169
179
180
    @Override
170
    public Lookup getLookup() {
181
    public Lookup getLookup() {
171
        return Lookup.EMPTY;
182
        return Lookup.EMPTY;
172
    }
183
    }
Lines 228-234 Link Here
228
    }
239
    }
229
    
240
    
230
    //Like DefaultLibraryTypeProvider but in addition checks '/' on the end of folder URLs.
241
    //Like DefaultLibraryTypeProvider but in addition checks '/' on the end of folder URLs.
231
    private static class J2SELibraryImpl implements LibraryImplementation {
242
    private static class J2SELibraryImpl implements NamedLibraryImplementation {
232
        private String description;
243
        private String description;
233
244
234
        private Map<String,List<URL>> contents;
245
        private Map<String,List<URL>> contents;
Lines 236-241 Link Here
236
        // library 'binding name' as given by user
247
        // library 'binding name' as given by user
237
        private String name;
248
        private String name;
238
249
250
        private String displayName;
251
239
        private String localizingBundle;
252
        private String localizingBundle;
240
253
241
        private List<PropertyChangeListener> listeners;
254
        private List<PropertyChangeListener> listeners;
Lines 251-270 Link Here
251
        }
264
        }
252
265
253
266
267
        @Override
254
        public String getType() {
268
        public String getType() {
255
            return LIBRARY_TYPE;
269
            return LIBRARY_TYPE;
256
        }
270
        }
257
271
272
        @Override
258
        public void setName(final String name) throws UnsupportedOperationException {
273
        public void setName(final String name) throws UnsupportedOperationException {
259
            String oldName = this.name;
274
            String oldName = this.name;
260
            this.name = name;
275
            this.name = name;
261
            this.firePropertyChange (PROP_NAME, oldName, this.name);
276
            this.firePropertyChange (PROP_NAME, oldName, this.name);
262
        }
277
        }
263
278
279
        @Override
264
        public String getName() {
280
        public String getName() {
265
            return name;
281
            return name;
266
        }
282
        }
267
283
284
        @Override
285
        public void setDisplayName(String displayName) {
286
            this.displayName = displayName;
287
        }
288
289
        @Override
290
        public String getDisplayName() {
291
            return this.displayName;
292
        }
293
294
        @Override
268
        public List<URL> getContent(String contentType) throws IllegalArgumentException {
295
        public List<URL> getContent(String contentType) throws IllegalArgumentException {
269
            List<URL> content = contents.get(contentType);
296
            List<URL> content = contents.get(contentType);
270
            if (content == null)
297
            if (content == null)
Lines 272-277 Link Here
272
            return Collections.unmodifiableList (content);
299
            return Collections.unmodifiableList (content);
273
        }
300
        }
274
301
302
        @Override
275
        public void setContent(final String contentType, List<URL> path) throws IllegalArgumentException {
303
        public void setContent(final String contentType, List<URL> path) throws IllegalArgumentException {
276
            if (path == null) {
304
            if (path == null) {
277
                throw new IllegalArgumentException ();
305
                throw new IllegalArgumentException ();
Lines 311-347 Link Here
311
            return checkedResources;
339
            return checkedResources;
312
        }
340
        }
313
341
342
        @Override
314
        public String getDescription () {
343
        public String getDescription () {
315
                return this.description;
344
                return this.description;
316
        }
345
        }
317
346
347
        @Override
318
        public void setDescription (String text) {
348
        public void setDescription (String text) {
319
            String oldDesc = this.description;
349
            String oldDesc = this.description;
320
            this.description = text;
350
            this.description = text;
321
            this.firePropertyChange (PROP_DESCRIPTION, oldDesc, this.description);
351
            this.firePropertyChange (PROP_DESCRIPTION, oldDesc, this.description);
322
        }
352
        }
323
353
354
        @Override
324
        public String getLocalizingBundle() {
355
        public String getLocalizingBundle() {
325
            return this.localizingBundle;
356
            return this.localizingBundle;
326
        }
357
        }
327
358
359
        @Override
328
        public void setLocalizingBundle(String resourceName) {
360
        public void setLocalizingBundle(String resourceName) {
329
            this.localizingBundle = resourceName;
361
            this.localizingBundle = resourceName;
330
        }
362
        }
331
363
364
        @Override
332
        public synchronized void addPropertyChangeListener (PropertyChangeListener l) {
365
        public synchronized void addPropertyChangeListener (PropertyChangeListener l) {
333
            if (this.listeners == null)
366
            if (this.listeners == null)
334
                this.listeners = new ArrayList<PropertyChangeListener>();
367
                this.listeners = new ArrayList<PropertyChangeListener>();
335
            this.listeners.add (l);
368
            this.listeners.add (l);
336
        }
369
        }
337
370
371
        @Override
338
        public synchronized void removePropertyChangeListener (PropertyChangeListener l) {
372
        public synchronized void removePropertyChangeListener (PropertyChangeListener l) {
339
            if (this.listeners == null)
373
            if (this.listeners == null)
340
                return;
374
                return;
341
            this.listeners.remove (l);
375
            this.listeners.remove (l);
342
        }
376
        }
343
377
344
        public @Override String toString() {
378
        @Override
379
        public String toString() {
345
            return this.getClass().getName()+"[" + name + "]"; // NOI18N
380
            return this.getClass().getName()+"[" + name + "]"; // NOI18N
346
        }
381
        }
347
382
(-)a/java.project/nbproject/project.xml (+1 lines)
Lines 125-130 Link Here
125
                    <compile-dependency/>
125
                    <compile-dependency/>
126
                    <run-dependency>
126
                    <run-dependency>
127
                        <release-version>1</release-version>
127
                        <release-version>1</release-version>
128
                        <specification-version>1.31</specification-version>
128
                    </run-dependency>
129
                    </run-dependency>
129
                </dependency>
130
                </dependency>
130
                <dependency>
131
                <dependency>
(-)a/java.project/src/org/netbeans/spi/java/project/support/ui/SharableLibrariesUtils.java (-1 / +12 lines)
Lines 512-518 Link Here
512
                    NbBundle.getMessage(SharableLibrariesUtils.class, "ERR_LibraryExists", library.getDisplayName()),
512
                    NbBundle.getMessage(SharableLibrariesUtils.class, "ERR_LibraryExists", library.getDisplayName()),
513
                    NotifyDescriptor.WARNING_MESSAGE));
513
                    NotifyDescriptor.WARNING_MESSAGE));
514
                } else {
514
                } else {
515
                    man.createURILibrary(library.getType(), library.getName(), volumes);
515
                    final String name = library.getName();
516
                    String displayName = library.getDisplayName();
517
                    if (name.equals(displayName)) {
518
                        //No need to set displayName when it's same as name
519
                        displayName = null;
520
                    }
521
                    man.createURILibrary(
522
                            library.getType(),
523
                            name,
524
                            displayName,
525
                            library.getDescription(),
526
                            volumes);
516
                }
527
                }
517
            } catch (IOException ex) {
528
            } catch (IOException ex) {
518
                Exceptions.printStackTrace(ex);
529
                Exceptions.printStackTrace(ex);
(-)a/project.ant/nbproject/project.xml (-1 / +1 lines)
Lines 72-78 Link Here
72
                    <compile-dependency/>
72
                    <compile-dependency/>
73
                    <run-dependency>
73
                    <run-dependency>
74
                        <release-version>1</release-version>
74
                        <release-version>1</release-version>
75
                        <specification-version>1.15</specification-version>
75
                        <specification-version>1.31</specification-version>
76
                    </run-dependency>
76
                    </run-dependency>
77
                </dependency>
77
                </dependency>
78
                <dependency>
78
                <dependency>
(-)a/project.ant/src/org/netbeans/modules/project/ant/ProjectLibraryProvider.java (-4 / +58 lines)
Lines 76-81 Link Here
76
import javax.swing.JFileChooser;
76
import javax.swing.JFileChooser;
77
import javax.swing.event.ChangeListener;
77
import javax.swing.event.ChangeListener;
78
import javax.swing.filechooser.FileFilter;
78
import javax.swing.filechooser.FileFilter;
79
import org.netbeans.api.annotations.common.NullAllowed;
79
import org.netbeans.api.project.Project;
80
import org.netbeans.api.project.Project;
80
import org.netbeans.api.project.ProjectManager;
81
import org.netbeans.api.project.ProjectManager;
81
import org.netbeans.api.project.libraries.Library;
82
import org.netbeans.api.project.libraries.Library;
Lines 91-96 Link Here
91
import org.netbeans.spi.project.libraries.LibraryImplementation2;
92
import org.netbeans.spi.project.libraries.LibraryImplementation2;
92
import org.netbeans.spi.project.libraries.LibraryProvider;
93
import org.netbeans.spi.project.libraries.LibraryProvider;
93
import org.netbeans.spi.project.libraries.LibraryStorageArea;
94
import org.netbeans.spi.project.libraries.LibraryStorageArea;
95
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
94
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
96
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
95
import org.netbeans.spi.project.support.ant.AntProjectEvent;
97
import org.netbeans.spi.project.support.ant.AntProjectEvent;
96
import org.netbeans.spi.project.support.ant.AntProjectHelper;
98
import org.netbeans.spi.project.support.ant.AntProjectHelper;
Lines 130-135 Link Here
130
    private static final String NAMESPACE = "http://www.netbeans.org/ns/ant-project-libraries/1"; // NOI18N
132
    private static final String NAMESPACE = "http://www.netbeans.org/ns/ant-project-libraries/1"; // NOI18N
131
    private static final String EL_LIBRARIES = "libraries"; // NOI18N
133
    private static final String EL_LIBRARIES = "libraries"; // NOI18N
132
    private static final String EL_DEFINITIONS = "definitions"; // NOI18N
134
    private static final String EL_DEFINITIONS = "definitions"; // NOI18N
135
    private static final String SFX_DISPLAY_NAME = "displayName";   //NOI18N
133
136
134
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
137
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
135
    private AntProjectListener apl;
138
    private AntProjectListener apl;
Lines 496-501 Link Here
496
            String name = entry.getKey();
499
            String name = entry.getKey();
497
            String type = "j2se"; // NOI18N
500
            String type = "j2se"; // NOI18N
498
            String description = null;
501
            String description = null;
502
            String displayName = null;
499
            Map<String,List<URI>> contents = new HashMap<String,List<URI>>();
503
            Map<String,List<URI>> contents = new HashMap<String,List<URI>>();
500
            for (Map.Entry<String,String> subentry : entry.getValue().entrySet()) {
504
            for (Map.Entry<String,String> subentry : entry.getValue().entrySet()) {
501
                String k = subentry.getKey();
505
                String k = subentry.getKey();
Lines 505-510 Link Here
505
                    // XXX currently overriding display name is not supported
509
                    // XXX currently overriding display name is not supported
506
                } else if (k.equals("description")) { // NOI18N
510
                } else if (k.equals("description")) { // NOI18N
507
                    description = subentry.getValue();
511
                    description = subentry.getValue();
512
                } else if (k.equals(SFX_DISPLAY_NAME)) {  //NOI18N
513
                    displayName = subentry.getValue();
508
                } else {
514
                } else {
509
                    final String[] path = sanitizeHttp(subentry.getKey(), PropertyUtils.tokenizePath(subentry.getValue()));
515
                    final String[] path = sanitizeHttp(subentry.getKey(), PropertyUtils.tokenizePath(subentry.getValue()));
510
                    List<URI> volume = new ArrayList<URI>(path.length);
516
                    List<URI> volume = new ArrayList<URI>(path.length);
Lines 535-541 Link Here
535
                    contents.put(k, volume);
541
                    contents.put(k, volume);
536
                }
542
                }
537
            }
543
            }
538
            libs.put(name, new ProjectLibraryImplementation(def.mainPropertiesFile, def.privatePropertiesFile, type, name, description, contents));
544
            libs.put(
545
                name,
546
                new ProjectLibraryImplementation(
547
                    def.mainPropertiesFile,
548
                    def.privatePropertiesFile,
549
                    type,
550
                    name,
551
                    description,
552
                    displayName,
553
                    contents));
539
        }
554
        }
540
        return libs;
555
        return libs;
541
    }
556
    }
Lines 642-653 Link Here
642
        return result.toArray(new String[result.size()]);
657
        return result.toArray(new String[result.size()]);
643
    }
658
    }
644
    
659
    
645
    static final class ProjectLibraryImplementation implements LibraryImplementation2 {
660
    static final class ProjectLibraryImplementation implements LibraryImplementation2, NamedLibraryImplementation {
646
661
647
        final File mainPropertiesFile, privatePropertiesFile;
662
        final File mainPropertiesFile, privatePropertiesFile;
648
        final String type;
663
        final String type;
649
        String name;
664
        String name;
650
        String description;
665
        String description;
666
        String displayName;
651
        Map<String,List<URI>> contents;
667
        Map<String,List<URI>> contents;
652
        final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
668
        final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
653
        
669
        
Lines 675-686 Link Here
675
            return null;
691
            return null;
676
        }
692
        }
677
693
678
        ProjectLibraryImplementation(File mainPropertiesFile, File privatePropertiesFile, String type, String name, String description, Map<String,List<URI>> contents) {
694
        ProjectLibraryImplementation(
695
                File mainPropertiesFile,
696
                File privatePropertiesFile,
697
                String type,
698
                String name,
699
                final @NullAllowed String description,
700
                final @NullAllowed String displayName,
701
                Map<String,List<URI>> contents) {
679
            this.mainPropertiesFile = mainPropertiesFile;
702
            this.mainPropertiesFile = mainPropertiesFile;
680
            this.privatePropertiesFile = privatePropertiesFile;
703
            this.privatePropertiesFile = privatePropertiesFile;
681
            this.type = type;
704
            this.type = type;
682
            this.name = name;
705
            this.name = name;
683
            this.description = description;
706
            this.description = description;
707
            this.displayName = displayName;
684
            this.contents = contents;
708
            this.contents = contents;
685
        }
709
        }
686
710
Lines 704-709 Link Here
704
            return null;
728
            return null;
705
        }
729
        }
706
730
731
        @Override
732
        public String getDisplayName() {
733
            return displayName;
734
        }
735
707
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
736
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
708
            List<URI> uris = getURIContent(volumeType);
737
            List<URI> uris = getURIContent(volumeType);
709
            List<URL> resolvedUrls = new ArrayList<URL>(uris.size());
738
            List<URL> resolvedUrls = new ArrayList<URL>(uris.size());
Lines 807-812 Link Here
807
            throw new UnsupportedOperationException();
836
            throw new UnsupportedOperationException();
808
        }
837
        }
809
838
839
        @Override
840
        public void setDisplayName(final @NullAllowed String displayName) {
841
            if (Utilities.compareObjects(this.displayName, displayName)) {
842
                return;
843
            }
844
            final String oldDisplayName = this.displayName;
845
            this.displayName = displayName;
846
            try {
847
                final String key = String.format("libs.%s.%s",name, SFX_DISPLAY_NAME);  //NOI18N
848
                replaceProperty(
849
                    mainPropertiesFile,
850
                    false,
851
                    key,
852
                    displayName == null ? new String[0] : new String[]{displayName});
853
            } catch (IOException x) {
854
                throw new IllegalArgumentException(x);
855
            }
856
            pcs.firePropertyChange(LibraryImplementation.PROP_CONTENT, oldDisplayName, displayName);
857
        }
858
810
        public void addPropertyChangeListener(PropertyChangeListener l) {
859
        public void addPropertyChangeListener(PropertyChangeListener l) {
811
            pcs.addPropertyChangeListener(l);
860
            pcs.addPropertyChangeListener(l);
812
        }
861
        }
Lines 1169-1175 Link Here
1169
                            index++;
1218
                            index++;
1170
                        }
1219
                        }
1171
                    }
1220
                    }
1172
                    return man.createURILibrary(lib.getType(), name, content);
1221
                    String displayName = lib.getDisplayName();
1222
                    if (name.equals(displayName)) {
1223
                        //No need to set displayName when it's same as name
1224
                        displayName = null;
1225
                    }
1226
                    return man.createURILibrary(lib.getType(), name, displayName, lib.getDescription(), content);
1173
                }
1227
                }
1174
            });
1228
            });
1175
        } catch (MutexException ex) {
1229
        } catch (MutexException ex) {
(-)a/project.libraries/apichanges.xml (+16 lines)
Lines 107-112 Link Here
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
    <changes>
108
    <changes>
109
109
110
    <change id="library-display-name">
111
        <api name="general"/>
112
        <summary>Allow user created library to provide display name</summary>
113
        <version major="1" minor="31"/>
114
        <date day="14" month="6" year="2011"/>
115
        <author login="tzezula"/>
116
        <compatibility addition="yes"/>
117
        <description>
118
            Added <code>displayName</code> property into the <code>Library</code>'s SPI
119
            allowing an implementor to provide the a display name of the <code>Library</code>
120
            which differs from the system (identifying) name.
121
        </description>
122
        <class package="org.netbeans.api.project.libraries" name="LibraryManager"/>
123
        <class package="org.netbeans.spi.project.libraries" name="NamedLibraryImplementation"/>
124
        <issue number="46863"/>
125
    </change>
110
    <change id="use-uri-for-relative-paths">
126
    <change id="use-uri-for-relative-paths">
111
        <api name="general"/>
127
        <api name="general"/>
112
        <summary>URI used for relative library entries instead of URL</summary>
128
        <summary>URI used for relative library entries instead of URL</summary>
(-)a/project.libraries/manifest.mf (-1 / +1 lines)
Lines 2-8 Link Here
2
OpenIDE-Module: org.netbeans.modules.project.libraries/1
2
OpenIDE-Module: org.netbeans.modules.project.libraries/1
3
OpenIDE-Module-Install: org/netbeans/modules/project/libraries/LibrariesModule.class
3
OpenIDE-Module-Install: org/netbeans/modules/project/libraries/LibrariesModule.class
4
OpenIDE-Module-Layer: org/netbeans/modules/project/libraries/resources/mf-layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/project/libraries/resources/mf-layer.xml
5
OpenIDE-Module-Specification-Version: 1.30
5
OpenIDE-Module-Specification-Version: 1.31
6
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/project/libraries/resources/Bundle.properties
6
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/project/libraries/resources/Bundle.properties
7
AutoUpdate-Show-In-Client: false
7
AutoUpdate-Show-In-Client: false
8
8
(-)a/project.libraries/src/org/netbeans/api/project/libraries/LibrariesCustomizer.java (-1 / +9 lines)
Lines 50-55 Link Here
50
import java.awt.Dialog;
50
import java.awt.Dialog;
51
import javax.swing.border.EmptyBorder;
51
import javax.swing.border.EmptyBorder;
52
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
52
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
53
import org.netbeans.modules.project.libraries.Util;
53
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
54
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
54
import org.netbeans.modules.project.libraries.ui.NewLibraryPanel;
55
import org.netbeans.modules.project.libraries.ui.NewLibraryPanel;
55
import org.netbeans.spi.project.libraries.LibraryImplementation;
56
import org.netbeans.spi.project.libraries.LibraryImplementation;
Lines 125-133 Link Here
125
        setAccessibleDescription(dlg, customizer.getAccessibleContext().getAccessibleDescription());
126
        setAccessibleDescription(dlg, customizer.getAccessibleContext().getAccessibleDescription());
126
        dlg.setVisible(true);
127
        dlg.setVisible(true);
127
        if (dd.getValue() == DialogDescriptor.OK_OPTION) {
128
        if (dd.getValue() == DialogDescriptor.OK_OPTION) {
129
            final String currentLibraryName = p.getLibraryName();
130
            final String antLibraryName = 
131
                org.netbeans.modules.project.libraries.ui.LibrariesCustomizer.createFreeAntLibraryName(
132
                    currentLibraryName,
133
                    customizer.getModel(),
134
                    area);
128
            LibraryImplementation impl;
135
            LibraryImplementation impl;
129
            if (area != LibrariesModel.GLOBAL_AREA) {
136
            if (area != LibrariesModel.GLOBAL_AREA) {
130
                impl = customizer.getModel().createArealLibrary(p.getLibraryType(), p.getLibraryName(), manager.getArea());
137
                impl = customizer.getModel().createArealLibrary(p.getLibraryType(), antLibraryName, manager.getArea());
131
            } else {
138
            } else {
132
                LibraryTypeProvider provider = LibraryTypeRegistry.getDefault().getLibraryTypeProvider(p.getLibraryType());
139
                LibraryTypeProvider provider = LibraryTypeRegistry.getDefault().getLibraryTypeProvider(p.getLibraryType());
133
                if (provider == null) {
140
                if (provider == null) {
Lines 136-141 Link Here
136
                impl = provider.createLibrary();
143
                impl = provider.createLibrary();
137
                impl.setName(p.getLibraryName());
144
                impl.setName(p.getLibraryName());
138
            }
145
            }
146
            Util.setDisplayName(impl, currentLibraryName);
139
            customizer.getModel().addLibrary(impl);
147
            customizer.getModel().addLibrary(impl);
140
            customizer.forceTreeRecreation();
148
            customizer.forceTreeRecreation();
141
            if (customizeLibrary(customizer, impl)) {
149
            if (customizeLibrary(customizer, impl)) {
(-)a/project.libraries/src/org/netbeans/api/project/libraries/Library.java (-1 / +2 lines)
Lines 54-59 Link Here
54
import java.util.ResourceBundle;
54
import java.util.ResourceBundle;
55
import java.util.logging.Logger;
55
import java.util.logging.Logger;
56
import org.netbeans.modules.project.libraries.LibraryAccessor;
56
import org.netbeans.modules.project.libraries.LibraryAccessor;
57
import org.netbeans.modules.project.libraries.Util;
57
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
58
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
58
import org.netbeans.spi.project.libraries.LibraryImplementation;
59
import org.netbeans.spi.project.libraries.LibraryImplementation;
59
import org.netbeans.spi.project.libraries.LibraryImplementation2;
60
import org.netbeans.spi.project.libraries.LibraryImplementation2;
Lines 176-182 Link Here
176
     * @return String the display name, never returns null.
177
     * @return String the display name, never returns null.
177
     */
178
     */
178
    public String getDisplayName () {
179
    public String getDisplayName () {
179
        return org.netbeans.modules.project.libraries.ui.LibrariesCustomizer.getLocalizedName(this.impl);
180
        return Util.getLocalizedName(this.impl);
180
    }
181
    }
181
182
182
183
(-)a/project.libraries/src/org/netbeans/api/project/libraries/LibraryManager.java (-2 / +55 lines)
Lines 58-64 Link Here
58
import java.util.List;
58
import java.util.List;
59
import java.util.Map;
59
import java.util.Map;
60
import java.util.Set;
60
import java.util.Set;
61
import org.netbeans.api.annotations.common.NonNull;
62
import org.netbeans.api.annotations.common.NullAllowed;
61
import org.netbeans.modules.project.libraries.LibraryAccessor;
63
import org.netbeans.modules.project.libraries.LibraryAccessor;
64
import org.netbeans.modules.project.libraries.Util;
62
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
65
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
63
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
66
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
64
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
67
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
Lines 286-291 Link Here
286
     * @since org.netbeans.modules.project.libraries/1 1.15
289
     * @since org.netbeans.modules.project.libraries/1 1.15
287
     */
290
     */
288
    public Library createLibrary(String type, String name, Map<String,List<URL>> contents) throws IOException {
291
    public Library createLibrary(String type, String name, Map<String,List<URL>> contents) throws IOException {
292
        return createLibrary(type, name, null, null, contents);
293
    }
294
295
    /**
296
     * Creates a new library definition and adds it to the list.
297
     * @param type the type of library, as in {@link LibraryTypeProvider#getLibraryType} or {@link LibraryImplementation#getType}
298
     * @param name the identifying name of the new library (must not duplicate a name already in use by a library in this manager)
299
     * @param displayName the display name of the library. If null the identifying name is used
300
     * @param description the library description
301
     * @param contents the initial contents of the library's volumes, as a map from volume type to volume content
302
     * @return a newly created library
303
     * @throws IOException if the new definition could not be stored
304
     * @throws IllegalArgumentException if the library type or one of the content volume types is not supported,
305
     *                                  or if a library of the same name already exists in this manager
306
     * @see ArealLibraryProvider#createLibrary
307
     * @since org.netbeans.modules.project.libraries/1 1.31
308
     */
309
    public Library createLibrary(
310
            @NonNull final  String type,
311
            @NonNull final String name,
312
            @NullAllowed final String displayName,
313
            @NullAllowed final String description,
314
            @NonNull final Map<String,List<URL>> contents) throws IOException {
289
        if (getLibrary(name) != null) {
315
        if (getLibrary(name) != null) {
290
            throw new IllegalArgumentException("Name already in use: " + name); // NOI18N
316
            throw new IllegalArgumentException("Name already in use: " + name); // NOI18N
291
        }
317
        }
Lines 297-302 Link Here
297
            }
323
            }
298
            impl = ltp.createLibrary();
324
            impl = ltp.createLibrary();
299
            impl.setName(name);
325
            impl.setName(name);
326
            Util.setDisplayName(impl, displayName);
300
            for (Map.Entry<String,List<URL>> entry : contents.entrySet()) {
327
            for (Map.Entry<String,List<URL>> entry : contents.entrySet()) {
301
                impl.setContent(entry.getKey(), entry.getValue());
328
                impl.setContent(entry.getKey(), entry.getValue());
302
            }
329
            }
Lines 307-312 Link Here
307
                cont.put(entry.getKey(), LibrariesModel.convertURLsToURIs(entry.getValue()));
334
                cont.put(entry.getKey(), LibrariesModel.convertURLsToURIs(entry.getValue()));
308
            }
335
            }
309
            impl = LibraryAccessor.createLibrary(alp, type, name, area, cont);
336
            impl = LibraryAccessor.createLibrary(alp, type, name, area, cont);
337
            Util.setDisplayName(impl, displayName);
310
        }
338
        }
311
        return new Library(impl, this);
339
        return new Library(impl, this);
312
    }
340
    }
Lines 321-329 Link Here
321
     * @throws IllegalArgumentException if the library type or one of the content volume types is not supported,
349
     * @throws IllegalArgumentException if the library type or one of the content volume types is not supported,
322
     *                                  or if a library of the same name already exists in this manager
350
     *                                  or if a library of the same name already exists in this manager
323
     * @see ArealLibraryProvider#createLibrary
351
     * @see ArealLibraryProvider#createLibrary
352
     * @since org.netbeans.modules.project.libraries/1 1.31
353
     */
354
    public Library createURILibrary(String type, String name, Map<String,List<URI>> contents) throws IOException {
355
        return createURILibrary(type, name, null, null, contents);
356
    }
357
358
    /**
359
     * Creates a new library definition and adds it to the list.
360
     * @param type the type of library, as in {@link LibraryTypeProvider#getLibraryType} or {@link LibraryImplementation#getType}
361
     * @param name the identifying name of the new library (must not duplicate a name already in use by a library in this manager)
362
     * @param displayName the display name of the library. If null the identifying name is used
363
     * @param description the library description
364
     * @param contents the initial contents of the library's volumes, as a map from volume type to volume content
365
     * @return a newly created library
366
     * @throws IOException if the new definition could not be stored
367
     * @throws IllegalArgumentException if the library type or one of the content volume types is not supported,
368
     *                                  or if a library of the same name already exists in this manager
369
     * @see ArealLibraryProvider#createLibrary
324
     * @since org.netbeans.modules.project.libraries/1 1.18
370
     * @since org.netbeans.modules.project.libraries/1 1.18
325
     */
371
     */
326
    public Library createURILibrary(String type, String name, Map<String,List<URI>> contents) throws IOException {
372
    public Library createURILibrary(
373
            @NonNull final String type,
374
            @NonNull final String name,
375
            @NullAllowed final String displayName,
376
            @NullAllowed final String description,
377
            @NonNull final Map<String,List<URI>> contents) throws IOException {
327
        if (getLibrary(name) != null) {
378
        if (getLibrary(name) != null) {
328
            throw new IllegalArgumentException("Name already in use: " + name); // NOI18N
379
            throw new IllegalArgumentException("Name already in use: " + name); // NOI18N
329
        }
380
        }
Lines 335-347 Link Here
335
            }
386
            }
336
            impl = ltp.createLibrary();
387
            impl = ltp.createLibrary();
337
            impl.setName(name);
388
            impl.setName(name);
389
            Util.setDisplayName(impl, displayName);
338
            for (Map.Entry<String,List<URI>> entry : contents.entrySet()) {
390
            for (Map.Entry<String,List<URI>> entry : contents.entrySet()) {
339
                impl.setContent(entry.getKey(), LibrariesModel.convertURIsToURLs(entry.getValue()));
391
                impl.setContent(entry.getKey(), LibrariesModel.convertURIsToURLs(entry.getValue()));
340
            }
392
            }
341
            Lookup.getDefault().lookup(WritableLibraryProvider.class).addLibrary(impl);
393
            Lookup.getDefault().lookup(WritableLibraryProvider.class).addLibrary(impl);
342
        } else {
394
        } else {
343
            impl = LibraryAccessor.createLibrary(alp, type, name, area, contents);
395
            impl = LibraryAccessor.createLibrary(alp, type, name, area, contents);
344
        }
396
            Util.setDisplayName(impl, displayName);
397
        }        
345
        return new Library(impl, this);
398
        return new Library(impl, this);
346
    }
399
    }
347
400
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/DefaultLibraryImplementation.java (-3 / +28 lines)
Lines 45-56 Link Here
45
package org.netbeans.modules.project.libraries;
45
package org.netbeans.modules.project.libraries;
46
46
47
import java.net.URL;
47
import java.net.URL;
48
import org.netbeans.spi.project.libraries.LibraryImplementation;
49
import java.util.*;
48
import java.util.*;
50
import java.beans.PropertyChangeListener;
49
import java.beans.PropertyChangeListener;
51
import java.beans.PropertyChangeEvent;
50
import java.beans.PropertyChangeEvent;
51
import org.netbeans.api.annotations.common.CheckForNull;
52
import org.netbeans.api.annotations.common.NullAllowed;
53
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
52
54
53
public final class DefaultLibraryImplementation implements LibraryImplementation {
55
public final class DefaultLibraryImplementation implements NamedLibraryImplementation {
54
56
55
    private String description;
57
    private String description;
56
58
Lines 63-68 Link Here
63
65
64
    private String localizingBundle;
66
    private String localizingBundle;
65
67
68
    private String displayName;
69
66
    private List<PropertyChangeListener> listeners;
70
    private List<PropertyChangeListener> listeners;
67
71
68
    /**
72
    /**
Lines 78-97 Link Here
78
    }
82
    }
79
83
80
84
85
    @Override
81
    public String getType() {
86
    public String getType() {
82
        return libraryType;
87
        return libraryType;
83
    }
88
    }
84
89
90
    @Override
85
    public void setName(final String name) throws UnsupportedOperationException {
91
    public void setName(final String name) throws UnsupportedOperationException {
86
        String oldName = this.name;
92
        String oldName = this.name;
87
        this.name = name;
93
        this.name = name;
88
        this.firePropertyChange (PROP_NAME, oldName, this.name);
94
        this.firePropertyChange (PROP_NAME, oldName, this.name);
89
    }
95
    }
90
96
97
    @Override
91
    public String getName() {
98
    public String getName() {
92
        return name;
99
        return name;
93
    }
100
    }
94
101
102
    @Override
95
    public List<URL> getContent(String contentType) throws IllegalArgumentException {
103
    public List<URL> getContent(String contentType) throws IllegalArgumentException {
96
        List<URL> content = contents.get(contentType);
104
        List<URL> content = contents.get(contentType);
97
        if (content == null)
105
        if (content == null)
Lines 99-104 Link Here
99
        return Collections.unmodifiableList (content);
107
        return Collections.unmodifiableList (content);
100
    }
108
    }
101
109
110
    @Override
102
    public void setContent(String contentType, List<URL> path) throws IllegalArgumentException {
111
    public void setContent(String contentType, List<URL> path) throws IllegalArgumentException {
103
        if (path == null) {
112
        if (path == null) {
104
            throw new IllegalArgumentException ();
113
            throw new IllegalArgumentException ();
Lines 112-148 Link Here
112
        }
121
        }
113
    }
122
    }
114
123
124
    @Override
115
    public String getDescription () {
125
    public String getDescription () {
116
            return this.description;
126
            return this.description;
117
    }
127
    }
118
128
129
    @Override
119
    public void setDescription (String text) {
130
    public void setDescription (String text) {
120
        String oldDesc = this.description;
131
        String oldDesc = this.description;
121
        this.description = text;
132
        this.description = text;
122
        this.firePropertyChange (PROP_DESCRIPTION, oldDesc, this.description);
133
        this.firePropertyChange (PROP_DESCRIPTION, oldDesc, this.description);
123
    }
134
    }
124
135
136
    @Override
125
    public String getLocalizingBundle() {
137
    public String getLocalizingBundle() {
126
        return this.localizingBundle;
138
        return this.localizingBundle;
127
    }
139
    }
128
140
141
    @Override
129
    public void setLocalizingBundle(String resourceName) {
142
    public void setLocalizingBundle(String resourceName) {
130
        this.localizingBundle = resourceName;
143
        this.localizingBundle = resourceName;
131
    }
144
    }
132
145
146
    @Override
147
    public @CheckForNull String getDisplayName() {
148
        return this.displayName;
149
    }
150
151
    public void setDisplayName(final @NullAllowed String displayName) {
152
        this.displayName = displayName;
153
    }
154
155
    @Override
133
    public synchronized void addPropertyChangeListener (PropertyChangeListener l) {
156
    public synchronized void addPropertyChangeListener (PropertyChangeListener l) {
134
        if (this.listeners == null)
157
        if (this.listeners == null)
135
            this.listeners = new ArrayList<PropertyChangeListener>();
158
            this.listeners = new ArrayList<PropertyChangeListener>();
136
        this.listeners.add (l);
159
        this.listeners.add (l);
137
    }
160
    }
138
161
162
    @Override
139
    public synchronized void removePropertyChangeListener (PropertyChangeListener l) {
163
    public synchronized void removePropertyChangeListener (PropertyChangeListener l) {
140
        if (this.listeners == null)
164
        if (this.listeners == null)
141
            return;
165
            return;
142
        this.listeners.remove (l);
166
        this.listeners.remove (l);
143
    }
167
    }
144
168
145
    public @Override String toString() {
169
    @Override
170
    public String toString() {
146
        return "DefaultLibraryImplementation[" + name + "]"; // NOI18N
171
        return "DefaultLibraryImplementation[" + name + "]"; // NOI18N
147
    }
172
    }
148
173
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/LibrariesStorage.java (-46 / +11 lines)
Lines 53-59 Link Here
53
import java.net.URL;
53
import java.net.URL;
54
import java.util.HashMap;
54
import java.util.HashMap;
55
import java.util.Iterator;
55
import java.util.Iterator;
56
import java.util.List;
57
import java.util.Map;
56
import java.util.Map;
58
import java.util.Properties;
57
import java.util.Properties;
59
import java.util.ResourceBundle;
58
import java.util.ResourceBundle;
Lines 64-70 Link Here
64
import javax.swing.event.ChangeEvent;
63
import javax.swing.event.ChangeEvent;
65
import javax.swing.event.ChangeListener;
64
import javax.swing.event.ChangeListener;
66
import javax.xml.parsers.ParserConfigurationException;
65
import javax.xml.parsers.ParserConfigurationException;
67
import org.netbeans.modules.project.libraries.ui.LibrariesCustomizer;
68
import org.netbeans.spi.project.libraries.LibraryImplementation;
66
import org.netbeans.spi.project.libraries.LibraryImplementation;
69
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
67
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
70
import org.openide.filesystems.FileChangeAdapter;
68
import org.openide.filesystems.FileChangeAdapter;
Lines 75-83 Link Here
75
import org.openide.filesystems.FileUtil;
73
import org.openide.filesystems.FileUtil;
76
import org.openide.util.Exceptions;
74
import org.openide.util.Exceptions;
77
import org.openide.util.NbBundle;
75
import org.openide.util.NbBundle;
78
import org.openide.xml.XMLUtil;
79
import org.w3c.dom.Document;
80
import org.w3c.dom.Element;
81
import org.xml.sax.InputSource;
76
import org.xml.sax.InputSource;
82
import org.xml.sax.SAXException;
77
import org.xml.sax.SAXException;
83
78
Lines 177-183 Link Here
177
                            }
172
                            }
178
                            librariesByFileNames.put(descriptorFile.getPath(),impl);
173
                            librariesByFileNames.put(descriptorFile.getPath(),impl);
179
                            libraries.put (impl.getName(),impl);
174
                            libraries.put (impl.getName(),impl);
180
                            LibrariesCustomizer.registerSource(impl, descriptorFile);
175
                            Util.registerSource(impl, descriptorFile);
181
                        }
176
                        }
182
                    }
177
                    }
183
                } catch (SAXException e) {
178
                } catch (SAXException e) {
Lines 235-241 Link Here
235
        final LibraryDeclarationParser parser = new LibraryDeclarationParser(handler,convertor);
230
        final LibraryDeclarationParser parser = new LibraryDeclarationParser(handler,convertor);
236
        handler.setLibrary (impl);
231
        handler.setLibrary (impl);
237
        readLibrary (descriptorFile, parser);
232
        readLibrary (descriptorFile, parser);
238
        LibrariesCustomizer.registerSource(impl, descriptorFile);
233
        Util.registerSource(impl, descriptorFile);
239
        return handler.getLibrary();
234
        return handler.getLibrary();
240
    }
235
    }
241
236
Lines 261-318 Link Here
261
                            return;
256
                            return;
262
                        }
257
                        }
263
                        FileObject fo = storage.createData (library.getName(),"xml");   //NOI18N
258
                        FileObject fo = storage.createData (library.getName(),"xml");   //NOI18N
264
                        writeLibraryDefinition (fo, library, libraryTypeProvider);
259
                        LibraryDeclarationParser.writeLibraryDefinition (fo, library, libraryTypeProvider);
265
                    }
260
                    }
266
                }
261
                }
267
        );
262
        );
268
    }
263
    }
269
264
    
270
    private static void writeLibraryDefinition (final FileObject definitionFile, final LibraryImplementation library, final LibraryTypeProvider libraryTypeProvider) throws IOException {
271
        Document doc = XMLUtil.createDocument("library", null,
272
                "-//NetBeans//DTD Library Declaration 1.0//EN",
273
                "http://www.netbeans.org/dtds/library-declaration-1_0.dtd"); // NOI18N
274
        Element libraryE = doc.getDocumentElement();
275
        libraryE.setAttribute("version", "1.0"); // NOI18N
276
        libraryE.appendChild(doc.createElement("name")).appendChild(doc.createTextNode(library.getName())); // NOI18N
277
        libraryE.appendChild(doc.createElement("type")).appendChild(doc.createTextNode(library.getType())); // NOI18N
278
        String description = library.getDescription();
279
        if (description != null && description.length() > 0) {
280
            libraryE.appendChild(doc.createElement("description")).appendChild(doc.createTextNode(description)); // NOI18N
281
        }
282
        String localizingBundle = library.getLocalizingBundle();
283
        if (localizingBundle != null && localizingBundle.length() > 0) {
284
            libraryE.appendChild(doc.createElement("localizing-bundle")).appendChild(doc.createTextNode(localizingBundle)); // NOI18N
285
        }
286
        for (String vtype : libraryTypeProvider.getSupportedVolumeTypes()) {
287
            Element volumeE = (Element) libraryE.appendChild(doc.createElement("volume")); // NOI18N
288
            volumeE.appendChild(doc.createElement("type")).appendChild(doc.createTextNode(vtype)); // NOI18N
289
            List<URL> volume = library.getContent(vtype);
290
            if (volume != null) {
291
                //If null -> broken library, repair it.
292
                for (URL url : volume) {
293
                    volumeE.appendChild(doc.createElement("resource")).appendChild(doc.createTextNode(url.toString())); // NOI18N
294
                }
295
            }
296
        }
297
        OutputStream os = definitionFile.getOutputStream();
298
        try {
299
            XMLUtil.write(doc, os, "UTF-8"); // NOI18N
300
        } finally {
301
            os.close();
302
        }
303
    }
304
305
306
    private void fireLibrariesChanged () {
265
    private void fireLibrariesChanged () {
307
        this.support.firePropertyChange(PROP_LIBRARIES,null,null);
266
        this.support.firePropertyChange(PROP_LIBRARIES,null,null);
308
    }
267
    }
309
268
310
269
270
    @Override
311
    public final void addPropertyChangeListener (PropertyChangeListener listener) {
271
    public final void addPropertyChangeListener (PropertyChangeListener listener) {
312
        this.support.addPropertyChangeListener(listener);
272
        this.support.addPropertyChangeListener(listener);
313
    }
273
    }
314
274
315
275
276
    @Override
316
    public final void removePropertyChangeListener (PropertyChangeListener listener) {
277
    public final void removePropertyChangeListener (PropertyChangeListener listener) {
317
        this.support.removePropertyChangeListener(listener);
278
        this.support.removePropertyChangeListener(listener);
318
    }
279
    }
Lines 320-325 Link Here
320
    /**
281
    /**
321
     * Return all libraries in memory.
282
     * Return all libraries in memory.
322
     */
283
     */
284
    @Override
323
    public final LibraryImplementation[] getLibraries() {
285
    public final LibraryImplementation[] getLibraries() {
324
        final Libs res = initStorage();
286
        final Libs res = initStorage();
325
        assert res != null;
287
        assert res != null;
Lines 327-338 Link Here
327
    } // end getLibraries
289
    } // end getLibraries
328
290
329
291
292
    @Override
330
    public void addLibrary (LibraryImplementation library) throws IOException {
293
    public void addLibrary (LibraryImplementation library) throws IOException {
331
        this.initStorage();
294
        this.initStorage();
332
        assert this.storage != null : "Storage is not initialized";
295
        assert this.storage != null : "Storage is not initialized";
333
        writeLibrary(this.storage,library);
296
        writeLibrary(this.storage,library);
334
    }
297
    }
335
298
299
    @Override
336
    public void removeLibrary (LibraryImplementation library) throws IOException {
300
    public void removeLibrary (LibraryImplementation library) throws IOException {
337
        final Libs data = this.initStorage();
301
        final Libs data = this.initStorage();
338
        assert this.storage != null : "Storage is not initialized";
302
        assert this.storage != null : "Storage is not initialized";
Lines 345-350 Link Here
345
        }
309
        }
346
    }
310
    }
347
311
312
    @Override
348
    public void updateLibrary(final LibraryImplementation oldLibrary, final LibraryImplementation newLibrary) throws IOException {
313
    public void updateLibrary(final LibraryImplementation oldLibrary, final LibraryImplementation newLibrary) throws IOException {
349
        final Libs data = this.initStorage();
314
        final Libs data = this.initStorage();
350
        assert this.storage != null : "Storage is not initialized";
315
        assert this.storage != null : "Storage is not initialized";
Lines 361-367 Link Here
361
                this.storage.getFileSystem().runAtomicAction(
326
                this.storage.getFileSystem().runAtomicAction(
362
                        new FileSystem.AtomicAction() {
327
                        new FileSystem.AtomicAction() {
363
                            public void run() throws IOException {
328
                            public void run() throws IOException {
364
                                writeLibraryDefinition (fo, newLibrary, libraryTypeProvider);
329
                                LibraryDeclarationParser.writeLibraryDefinition (fo, newLibrary, libraryTypeProvider);
365
                            }
330
                            }
366
                        }
331
                        }
367
                );
332
                );
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/LibraryDeclarationHandler.java (-1 / +3 lines)
Lines 91-97 Link Here
91
     * @param meta attributes
91
     * @param meta attributes
92
     *
92
     *
93
     */
93
     */
94
    public void start_library(final Attributes meta) throws SAXException;
94
    public String start_library(final String nameSpace, final Attributes meta) throws SAXException;
95
    
95
    
96
    /**
96
    /**
97
     * A container element end event handling method.
97
     * A container element end event handling method.
Lines 117-121 Link Here
117
117
118
    public void handle_localizingBundle (final String data, final Attributes meta) throws SAXException;
118
    public void handle_localizingBundle (final String data, final Attributes meta) throws SAXException;
119
119
120
    public void handle_displayName (String data, Attributes meta) throws SAXException;
121
120
}
122
}
121
123
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/LibraryDeclarationHandlerImpl.java (-12 / +22 lines)
Lines 53-60 Link Here
53
import java.util.Map;
53
import java.util.Map;
54
import java.util.concurrent.atomic.AtomicBoolean;
54
import java.util.concurrent.atomic.AtomicBoolean;
55
import java.util.logging.Level;
55
import java.util.logging.Level;
56
import java.util.regex.Pattern;
56
import org.netbeans.spi.project.libraries.LibraryImplementation;
57
import org.netbeans.spi.project.libraries.LibraryImplementation;
57
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
58
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
59
import org.openide.util.Utilities;
58
import org.xml.sax.Attributes;
60
import org.xml.sax.Attributes;
59
import org.xml.sax.SAXException;
61
import org.xml.sax.SAXException;
60
import org.xml.sax.SAXParseException;
62
import org.xml.sax.SAXParseException;
Lines 68-78 Link Here
68
70
69
71
70
    private LibraryImplementation library;
72
    private LibraryImplementation library;
71
72
    private String libraryType;
73
    private String libraryType;
73
    private String libraryDescription;
74
    private String libraryDescription;
74
    private String libraryName;
75
    private String libraryName;
75
    private String localizingBundle;
76
    private String localizingBundle;
77
    private String displayName;
76
    private Map<String,List<URL>> contentTypes = new HashMap<String,List<URL>>();
78
    private Map<String,List<URL>> contentTypes = new HashMap<String,List<URL>>();
77
79
78
    // last volume
80
    // last volume
Lines 122-129 Link Here
122
    }
124
    }
123
125
124
    @Override
126
    @Override
125
    public void start_library(final Attributes meta) throws SAXException {
127
    public String start_library(final String nameSpace, final Attributes meta) throws SAXException {
126
        if ("1.0".equals(meta.getValue("version")) == false) {  // NOI18N
128
        final String version = meta.getValue("version");
129
        if (LibraryDeclarationParser.VER_1.equals(version)) {
130
            return "";  //NOI18N
131
        } else if (LibraryDeclarationParser.VER_2.equals(version)) {
132
            return LibraryDeclarationParser.LIBRARY_NS;
133
        } else {
127
            throw new SAXException("Invalid librray descriptor version"); // NOI18N
134
            throw new SAXException("Invalid librray descriptor version"); // NOI18N
128
        }
135
        }
129
    }
136
    }
Lines 137-144 Link Here
137
                        library.getType()+" to: " + libraryType, null); //NOI18N
144
                        library.getType()+" to: " + libraryType, null); //NOI18N
138
            }
145
            }
139
            update = true;
146
            update = true;
140
        }
147
        } else {
141
        else {
142
            if (this.libraryType == null) {
148
            if (this.libraryType == null) {
143
                throw new SAXParseException("Unspecified library type for: "+this.libraryName, null); //NOI18N
149
                throw new SAXParseException("Unspecified library type for: "+this.libraryName, null); //NOI18N
144
            }
150
            }
Lines 150-164 Link Here
150
            update = false;
156
            update = false;
151
            LibrariesStorage.LOG.log(Level.FINE, "LibraryDeclarationHandlerImpl library {0} type {1} found", new Object[] { this.libraryName, this.libraryType });
157
            LibrariesStorage.LOG.log(Level.FINE, "LibraryDeclarationHandlerImpl library {0} type {1} found", new Object[] { this.libraryName, this.libraryType });
152
        }
158
        }
153
        if (!update || !safeEquals(this.library.getLocalizingBundle(), localizingBundle)) {
159
        if (!update || !Utilities.compareObjects(this.library.getLocalizingBundle(), localizingBundle)) {
154
            this.library.setLocalizingBundle (this.localizingBundle);
160
            this.library.setLocalizingBundle (this.localizingBundle);
155
        }
161
        }
156
        if (!update || !safeEquals(this.library.getName(), libraryName)) {
162
        if (!update || !Utilities.compareObjects(this.library.getName(), libraryName)) {
157
            this.library.setName (this.libraryName);
163
            this.library.setName (this.libraryName);
158
        }
164
        }
159
        if (!update || !safeEquals(this.library.getDescription(), libraryDescription)) {
165
        if (!update || !Utilities.compareObjects(this.library.getDescription(), libraryDescription)) {
160
            this.library.setDescription (this.libraryDescription);
166
            this.library.setDescription (this.libraryDescription);
161
        }
167
        }
168
        if (!update || !Utilities.compareObjects(this.library.getLocalizingBundle(), displayName)) {
169
            Util.setDisplayName(this.library,displayName);
170
        }
162
        for (Map.Entry<String,List<URL>> entry : contentTypes.entrySet()) {
171
        for (Map.Entry<String,List<URL>> entry : contentTypes.entrySet()) {
163
            String contentType = entry.getKey();
172
            String contentType = entry.getKey();
164
            List<URL> cp = entry.getValue();
173
            List<URL> cp = entry.getValue();
Lines 194-199 Link Here
194
        this.localizingBundle = data;
203
        this.localizingBundle = data;
195
    }
204
    }
196
205
206
    @Override
207
    public void handle_displayName (String data, Attributes meta) throws SAXException {
208
        this.displayName = data;
209
    }
210
197
    public void setLibrary (LibraryImplementation library) {
211
    public void setLibrary (LibraryImplementation library) {
198
        this.library = library;
212
        this.library = library;
199
    }
213
    }
Lines 203-212 Link Here
203
    }
217
    }
204
218
205
219
206
    private static boolean safeEquals (Object o1, Object o2) {
207
        return o1 == null ? o2 == null : o1.equals (o2);
208
    }
209
210
    private static boolean urlsEqual (final Collection<? extends URL> first, final Collection<? extends URL> second) {
220
    private static boolean urlsEqual (final Collection<? extends URL> first, final Collection<? extends URL> second) {
211
        assert first != null;
221
        assert first != null;
212
        assert second != null;
222
        assert second != null;
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/LibraryDeclarationParser.java (-27 / +156 lines)
Lines 47-56 Link Here
47
import java.io.ByteArrayInputStream;
47
import java.io.ByteArrayInputStream;
48
import java.io.IOException;
48
import java.io.IOException;
49
import java.io.InputStream;
49
import java.io.InputStream;
50
import java.io.OutputStream;
51
import java.net.URL;
52
import java.util.List;
50
import java.util.Stack;
53
import java.util.Stack;
51
import java.util.concurrent.atomic.AtomicBoolean;
54
import java.util.concurrent.atomic.AtomicBoolean;
52
import javax.xml.parsers.ParserConfigurationException;
55
import javax.xml.parsers.ParserConfigurationException;
56
import org.netbeans.api.annotations.common.NonNull;
57
import org.netbeans.spi.project.libraries.LibraryImplementation;
58
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
59
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
60
import org.openide.filesystems.FileObject;
53
import org.openide.xml.XMLUtil;
61
import org.openide.xml.XMLUtil;
62
import org.w3c.dom.Document;
63
import org.w3c.dom.Element;
54
import org.xml.sax.Attributes;
64
import org.xml.sax.Attributes;
55
import org.xml.sax.ContentHandler;
65
import org.xml.sax.ContentHandler;
56
import org.xml.sax.EntityResolver;
66
import org.xml.sax.EntityResolver;
Lines 75-84 Link Here
75
 */
85
 */
76
public class LibraryDeclarationParser implements ContentHandler, EntityResolver {
86
public class LibraryDeclarationParser implements ContentHandler, EntityResolver {
77
87
88
    private static final String LIBRARY_DEF_1 = "-//NetBeans//DTD Library Declaration 1.0//EN"; //NOI18N
89
    private static final String LIBRARY_DTD_1 = "http://www.netbeans.org/dtds/library-declaration-1_0.dtd"; //NOI18N
90
    static final String LIBRARY_NS = "http://www.netbeans.org/ns/library-declaration/2";    //NOI18N
91
    static final String VER_1 = "1.0";  //NOI18N
92
    static final String VER_2 = "2.0";  //NOI18N
93
    private static final String LIBRARY = "library";    //NOI18N
94
    private static final String VERSION = "version";    //NOI18N
95
    private static final String VOLUME = "volume";  //NOI18N
96
    private static final String DESCRIPTION = "description";    //NOI18N
97
    private static final String TYPE = "type";      //NOI18N
98
    private static final String RESOURCE = "resource";   //NOI18N
99
    private static final String NAME = "name";  //NOI18N
100
    private static final String BUNDLE = "localizing-bundle";   //NOI18N
101
    private static final String DISPLAY_NAME = "display-name";  //NOI18N
102
78
    private StringBuffer buffer;
103
    private StringBuffer buffer;
79
    private final LibraryDeclarationConvertor parslet;
104
    private final LibraryDeclarationConvertor parslet;
80
    private final LibraryDeclarationHandler handler;
105
    private final LibraryDeclarationHandler handler;
81
    private Stack<Object[]> context;
106
    private Stack<Object[]> context;
107
    private String expectedNS;
82
    private final AtomicBoolean used = new AtomicBoolean();
108
    private final AtomicBoolean used = new AtomicBoolean();
83
109
84
    /**
110
    /**
Lines 98-103 Link Here
98
     * This SAX interface method is implemented by the parser.
124
     * This SAX interface method is implemented by the parser.
99
     *
125
     *
100
     */
126
     */
127
    @Override
101
    public final void setDocumentLocator(Locator locator) {
128
    public final void setDocumentLocator(Locator locator) {
102
    }
129
    }
103
    
130
    
Lines 105-110 Link Here
105
     * This SAX interface method is implemented by the parser.
132
     * This SAX interface method is implemented by the parser.
106
     *
133
     *
107
     */
134
     */
135
    @Override
108
    public final void startDocument() throws SAXException {
136
    public final void startDocument() throws SAXException {
109
        handler.startDocument();
137
        handler.startDocument();
110
    }
138
    }
Lines 113-118 Link Here
113
     * This SAX interface method is implemented by the parser.
141
     * This SAX interface method is implemented by the parser.
114
     *
142
     *
115
     */
143
     */
144
    @Override
116
    public final void endDocument() throws SAXException {
145
    public final void endDocument() throws SAXException {
117
        handler.endDocument();
146
        handler.endDocument();
118
    }
147
    }
Lines 121-133 Link Here
121
     * This SAX interface method is implemented by the parser.
150
     * This SAX interface method is implemented by the parser.
122
     *
151
     *
123
     */
152
     */
153
    @Override
124
    public final void startElement(String ns, String name, String qname, Attributes attrs) throws SAXException {
154
    public final void startElement(String ns, String name, String qname, Attributes attrs) throws SAXException {
125
        dispatch(true);
155
        dispatch(true);
126
        context.push(new Object[] {qname, new AttributesImpl(attrs)});
156
        context.push(new Object[] {qname, ns, new AttributesImpl(attrs)});
127
        if ("volume".equals(qname)) {
157
        if (VOLUME.equals(qname)) {
128
            handler.start_volume(attrs);
158
            handler.start_volume(attrs);
129
        } else if ("library".equals(qname)) {
159
        } else if (LIBRARY.equals(qname)) {
130
            handler.start_library(attrs);
160
            expectedNS = handler.start_library(ns, attrs);
131
        }
161
        }
132
    }
162
    }
133
    
163
    
Lines 135-146 Link Here
135
     * This SAX interface method is implemented by the parser.
165
     * This SAX interface method is implemented by the parser.
136
     *
166
     *
137
     */
167
     */
168
    @Override
138
    public final void endElement(String ns, String name, String qname) throws SAXException {
169
    public final void endElement(String ns, String name, String qname) throws SAXException {
139
        dispatch(false);
170
        dispatch(false);
140
        context.pop();
171
        context.pop();
141
        if ("volume".equals(qname)) {
172
        if (VOLUME.equals(qname)) {
142
            handler.end_volume();
173
            handler.end_volume();
143
        } else if ("library".equals(qname)) {
174
        } else if (LIBRARY.equals(qname)) {
144
            handler.end_library();
175
            handler.end_library();
145
        }
176
        }
146
    }
177
    }
Lines 149-154 Link Here
149
     * This SAX interface method is implemented by the parser.
180
     * This SAX interface method is implemented by the parser.
150
     *
181
     *
151
     */
182
     */
183
    @Override
152
    public final void characters(char[] chars, int start, int len) throws SAXException {
184
    public final void characters(char[] chars, int start, int len) throws SAXException {
153
        buffer.append(chars, start, len);
185
        buffer.append(chars, start, len);
154
    }
186
    }
Lines 157-162 Link Here
157
     * This SAX interface method is implemented by the parser.
189
     * This SAX interface method is implemented by the parser.
158
     *
190
     *
159
     */
191
     */
192
    @Override
160
    public final void ignorableWhitespace(char[] chars, int start, int len) throws SAXException {
193
    public final void ignorableWhitespace(char[] chars, int start, int len) throws SAXException {
161
    }
194
    }
162
    
195
    
Lines 164-169 Link Here
164
     * This SAX interface method is implemented by the parser.
197
     * This SAX interface method is implemented by the parser.
165
     *
198
     *
166
     */
199
     */
200
    @Override
167
    public final void processingInstruction(String target, String data) throws SAXException {
201
    public final void processingInstruction(String target, String data) throws SAXException {
168
    }
202
    }
169
    
203
    
Lines 171-176 Link Here
171
     * This SAX interface method is implemented by the parser.
205
     * This SAX interface method is implemented by the parser.
172
     *
206
     *
173
     */
207
     */
208
    @Override
174
    public final void startPrefixMapping(final String prefix, final String uri) throws SAXException {
209
    public final void startPrefixMapping(final String prefix, final String uri) throws SAXException {
175
    }
210
    }
176
    
211
    
Lines 178-183 Link Here
178
     * This SAX interface method is implemented by the parser.
213
     * This SAX interface method is implemented by the parser.
179
     *
214
     *
180
     */
215
     */
216
    @Override
181
    public final void endPrefixMapping(final String prefix) throws SAXException {
217
    public final void endPrefixMapping(final String prefix) throws SAXException {
182
    }
218
    }
183
    
219
    
Lines 185-214 Link Here
185
     * This SAX interface method is implemented by the parser.
221
     * This SAX interface method is implemented by the parser.
186
     *
222
     *
187
     */
223
     */
224
    @Override
188
    public final void skippedEntity(String name) throws SAXException {
225
    public final void skippedEntity(String name) throws SAXException {
189
    }
226
    }
190
    
227
    
191
    private void dispatch(final boolean fireOnlyIfMixed) throws SAXException {
228
    private void dispatch(final boolean fireOnlyIfMixed) throws SAXException {
192
        if (fireOnlyIfMixed && buffer.length() == 0) return; //skip it
229
        if (fireOnlyIfMixed && buffer.length() == 0) return; //skip it
193
        
230
        
194
        Object[] ctx = context.peek();
231
        final Object[] ctx = context.peek();
195
        String here = (String) ctx[0];
232
        final String here = (String) ctx[0];
196
        Attributes attrs = (Attributes) ctx[1];
233
        final String ns = (String) ctx[1];
197
        if ("description".equals(here)) {
234
        Attributes attrs = (Attributes) ctx[2];
235
        if (!expectedNS.equals(ns)) {
236
            throw new SAXException("Invalid librray descriptor namespace"); // NOI18N
237
        }
238
        if (DESCRIPTION.equals(here)) {
198
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
239
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
199
            handler.handle_description (buffer.length() == 0 ? null : buffer.toString(), attrs);
240
            handler.handle_description (buffer.length() == 0 ? null : buffer.toString(), attrs);
200
        } else if ("type".equals(here)) {
241
        } else if (TYPE.equals(here)) {
201
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
242
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
202
            handler.handle_type(buffer.length() == 0 ? null : buffer.toString(), attrs);
243
            handler.handle_type(buffer.length() == 0 ? null : buffer.toString(), attrs);
203
        } else if ("resource".equals(here)) {
244
        } else if (RESOURCE.equals(here)) {
204
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
245
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
205
            handler.handle_resource(parslet.parseResource(buffer.length() == 0 ? null : buffer.toString()), attrs);
246
            handler.handle_resource(parslet.parseResource(buffer.length() == 0 ? null : buffer.toString()), attrs);
206
        } else if ("name".equals(here)) {
247
        } else if (NAME.equals(here)) {
207
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
248
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
208
            handler.handle_name(buffer.length() == 0 ? null : buffer.toString(), attrs);
249
            handler.handle_name(buffer.length() == 0 ? null : buffer.toString(), attrs);
209
        } else if ("localizing-bundle".equals(here)) {
250
        } else if (BUNDLE.equals(here)) {
210
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
251
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
211
            handler.handle_localizingBundle(buffer.length() == 0 ? null : buffer.toString(), attrs);
252
            handler.handle_localizingBundle(buffer.length() == 0 ? null : buffer.toString(), attrs);
253
        } else if (DISPLAY_NAME.equals(here) && LIBRARY_NS.equals(ns)) {
254
            if (fireOnlyIfMixed) throw new IllegalStateException("Unexpected characters() event! (Missing DTD?)");
255
            handler.handle_displayName(buffer.length() == 0 ? null : buffer.toString(), attrs);
212
        } else {
256
        } else {
213
            //do not care
257
            //do not care
214
        }
258
        }
Lines 225-251 Link Here
225
     *
269
     *
226
     */
270
     */
227
    public void parse(final InputSource input) throws SAXException, ParserConfigurationException, IOException {
271
    public void parse(final InputSource input) throws SAXException, ParserConfigurationException, IOException {
228
        parse(input, this);
229
    }
230
231
    private void parse(final InputSource input, final LibraryDeclarationParser recognizer) throws SAXException, ParserConfigurationException, IOException {
232
        if (used.getAndSet(true)) {
272
        if (used.getAndSet(true)) {
233
            throw new IllegalStateException("The LibraryDeclarationParser was already used, create a new instance");  //NOI18N
273
            throw new IllegalStateException("The LibraryDeclarationParser was already used, create a new instance");  //NOI18N
234
        }
274
        }
235
        try {
275
        try {
236
            XMLReader parser = XMLUtil.createXMLReader(false, false);
276
            final XMLReader parser = XMLUtil.createXMLReader(false, true);
237
            parser.setContentHandler(recognizer);
277
            parser.setContentHandler(this);
238
            parser.setErrorHandler(recognizer.getDefaultErrorHandler());
278
            parser.setErrorHandler(getDefaultErrorHandler());
239
            parser.setEntityResolver(recognizer);
279
            parser.setEntityResolver(this);
240
            parser.parse(input);
280
            parser.parse(input);
241
        } finally {
281
        } finally {
242
            //Recover recognizer internal state from exceptions to be reusable
282
            //Recover recognizer internal state from exceptions to be reusable
243
            if (!recognizer.context.empty()) {
283
            if (!context.empty()) {
244
                recognizer.context.clear();
284
                context.clear();
245
            }
285
            }
246
            if (recognizer.buffer.length() > 0) {
286
            if (buffer.length() > 0) {
247
                recognizer.buffer.delete(0, recognizer.buffer.length());
287
                buffer.delete(0, buffer.length());
248
            }
288
            }
289
            expectedNS = null;
249
        }
290
        }
250
    }
291
    }
251
    
292
    
Lines 256-269 Link Here
256
     */
297
     */
257
    protected ErrorHandler getDefaultErrorHandler() {
298
    protected ErrorHandler getDefaultErrorHandler() {
258
        return new ErrorHandler() {
299
        return new ErrorHandler() {
300
            @Override
259
            public void error(SAXParseException ex) throws SAXException  {
301
            public void error(SAXParseException ex) throws SAXException  {
260
                throw ex;
302
                throw ex;
261
            }
303
            }
262
            
304
            
305
            @Override
263
            public void fatalError(SAXParseException ex) throws SAXException {
306
            public void fatalError(SAXParseException ex) throws SAXException {
264
                throw ex;
307
                throw ex;
265
            }
308
            }
266
            
309
            
310
            @Override
267
            public void warning(SAXParseException ex) throws SAXException {
311
            public void warning(SAXParseException ex) throws SAXException {
268
                // ignore
312
                // ignore
269
            }
313
            }
Lines 273-285 Link Here
273
    
317
    
274
    /** Implementation of entity resolver. Points to the local DTD
318
    /** Implementation of entity resolver. Points to the local DTD
275
     * for our public ID */
319
     * for our public ID */
320
    @Override
276
    public InputSource resolveEntity (String publicId, String systemId)
321
    public InputSource resolveEntity (String publicId, String systemId)
277
    throws SAXException {
322
    throws SAXException {
278
        if ("-//NetBeans//DTD Library Declaration 1.0//EN".equals(publicId)) {
323
        if (LIBRARY_DEF_1.equals(publicId)) {
279
            InputStream is = new ByteArrayInputStream(new byte[0]);
324
            InputStream is = new ByteArrayInputStream(new byte[0]);
280
            return new InputSource(is);
325
            return new InputSource(is);
281
        }
326
        }
282
        return null; // i.e. follow advice of systemID
327
        return null; // i.e. follow advice of systemID
283
    }
328
    }
329
330
    static void writeLibraryDefinition (
331
            final @NonNull FileObject definitionFile,
332
            final @NonNull LibraryImplementation library,
333
            final @NonNull LibraryTypeProvider libraryTypeProvider) throws IOException {
334
        final Document doc = Util.supportsDisplayName(library) ?
335
                createLibraryDefinition2(library, libraryTypeProvider) :
336
                createLibraryDefinition1(library, libraryTypeProvider);
337
        final OutputStream os = definitionFile.getOutputStream();
338
        try {
339
            XMLUtil.write(doc, os, "UTF-8"); // NOI18N
340
        } finally {
341
            os.close();
342
        }
343
    }
344
345
    private static Document createLibraryDefinition1(
346
            final @NonNull LibraryImplementation library,
347
            final @NonNull LibraryTypeProvider libraryTypeProvider) {
348
        final Document doc = XMLUtil.createDocument(LIBRARY, null,
349
                LIBRARY_DEF_1,
350
                LIBRARY_DTD_1);
351
        final Element libraryE = doc.getDocumentElement();
352
        libraryE.setAttribute(VERSION, VER_1); // NOI18N
353
        libraryE.appendChild(doc.createElement(NAME)).appendChild(doc.createTextNode(library.getName())); // NOI18N
354
        libraryE.appendChild(doc.createElement(TYPE)).appendChild(doc.createTextNode(library.getType())); // NOI18N
355
        String description = library.getDescription();
356
        if (description != null && description.length() > 0) {
357
            libraryE.appendChild(doc.createElement(DESCRIPTION)).appendChild(doc.createTextNode(description)); // NOI18N
358
        }
359
        String localizingBundle = library.getLocalizingBundle();
360
        if (localizingBundle != null && localizingBundle.length() > 0) {
361
            libraryE.appendChild(doc.createElement(BUNDLE)).appendChild(doc.createTextNode(localizingBundle)); // NOI18N
362
        }
363
        String displayname = Util.getDisplayName(library);
364
        if (displayname != null) {
365
            libraryE.appendChild(doc.createElement(DISPLAY_NAME)).appendChild(doc.createTextNode(displayname)); // NOI18N
366
        }
367
        for (String vtype : libraryTypeProvider.getSupportedVolumeTypes()) {
368
            Element volumeE = (Element) libraryE.appendChild(doc.createElement(VOLUME)); // NOI18N
369
            volumeE.appendChild(doc.createElement(TYPE)).appendChild(doc.createTextNode(vtype)); // NOI18N
370
            List<URL> volume = library.getContent(vtype);
371
            if (volume != null) {
372
                //If null -> broken library, repair it.
373
                for (URL url : volume) {
374
                    volumeE.appendChild(doc.createElement(RESOURCE)).appendChild(doc.createTextNode(url.toString())); // NOI18N
375
                }
376
            }
377
        }
378
        return doc;
379
    }
380
381
    private static Document createLibraryDefinition2(
382
            final @NonNull LibraryImplementation library,
383
            final @NonNull LibraryTypeProvider libraryTypeProvider) {
384
        final Document doc = XMLUtil.createDocument(LIBRARY, LIBRARY_NS, null, null);
385
        final Element libraryE = doc.getDocumentElement();
386
        libraryE.setAttribute(VERSION, VER_2); // NOI18N
387
        libraryE.appendChild(doc.createElementNS(LIBRARY_NS, NAME)).appendChild(doc.createTextNode(library.getName())); // NOI18N
388
        libraryE.appendChild(doc.createElementNS(LIBRARY_NS, TYPE)).appendChild(doc.createTextNode(library.getType())); // NOI18N
389
        String description = library.getDescription();
390
        if (description != null && description.length() > 0) {
391
            libraryE.appendChild(doc.createElementNS(LIBRARY_NS, DESCRIPTION)).appendChild(doc.createTextNode(description)); // NOI18N
392
        }
393
        String localizingBundle = library.getLocalizingBundle();
394
        if (localizingBundle != null && localizingBundle.length() > 0) {
395
            libraryE.appendChild(doc.createElementNS(LIBRARY_NS, BUNDLE)).appendChild(doc.createTextNode(localizingBundle)); // NOI18N
396
        }
397
        String displayname = Util.getDisplayName(library);
398
        if (displayname != null) {
399
            libraryE.appendChild(doc.createElementNS(LIBRARY_NS, DISPLAY_NAME)).appendChild(doc.createTextNode(displayname)); // NOI18N
400
        }
401
        for (String vtype : libraryTypeProvider.getSupportedVolumeTypes()) {
402
            Element volumeE = (Element) libraryE.appendChild(doc.createElementNS(LIBRARY_NS,VOLUME)); // NOI18N
403
            volumeE.appendChild(doc.createElementNS(LIBRARY_NS, TYPE)).appendChild(doc.createTextNode(vtype)); // NOI18N
404
            List<URL> volume = library.getContent(vtype);
405
            if (volume != null) {
406
                for (URL url : volume) {
407
                    volumeE.appendChild(doc.createElementNS(LIBRARY_NS, RESOURCE)).appendChild(doc.createTextNode(url.toString())); // NOI18N
408
                }
409
            }
410
        }
411
        return doc;
412
    }
284
}
413
}
285
414
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/Util.java (+148 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.project.libraries;
43
44
import java.util.Map;
45
import java.util.MissingResourceException;
46
import java.util.ResourceBundle;
47
import java.util.WeakHashMap;
48
import java.util.logging.Level;
49
import java.util.logging.Logger;
50
import org.netbeans.api.annotations.common.CheckForNull;
51
import org.netbeans.api.annotations.common.NonNull;
52
import org.netbeans.api.annotations.common.NullAllowed;
53
import org.netbeans.modules.project.libraries.ui.ProxyLibraryImplementation;
54
import org.netbeans.spi.project.libraries.LibraryImplementation;
55
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
56
import org.openide.filesystems.FileObject;
57
import org.openide.util.NbBundle;
58
59
/**
60
 *
61
 * @author Tomas Zezula
62
 */
63
public class Util {
64
65
    private static final Logger LOG = Logger.getLogger(Util.class.getName());
66
    private static Map<LibraryImplementation,FileObject> sources = new WeakHashMap<LibraryImplementation,FileObject>();
67
68
    private Util(){}
69
70
    public static @NonNull String getLocalizedName(LibraryImplementation impl) {
71
        if (supportsDisplayName(impl) && ((NamedLibraryImplementation)impl).getDisplayName() != null) {
72
            return ((NamedLibraryImplementation)impl).getDisplayName();
73
        }
74
        final FileObject src = sources.get(impl);
75
        if (src != null) {
76
            Object obj = src.getAttribute("displayName"); // NOI18N
77
            if (obj instanceof String) {
78
                return (String)obj;
79
            }
80
        }
81
        if (impl instanceof ProxyLibraryImplementation) {
82
            String proxiedName = getLocalizedName(((ProxyLibraryImplementation)impl).getOriginal());
83
            if (proxiedName != null) {
84
                return proxiedName;
85
            }
86
        }
87
88
        return getLocalizedString(impl.getLocalizingBundle(), impl.getName());
89
    }
90
91
    public static boolean supportsDisplayName(final @NonNull LibraryImplementation impl) {
92
        assert impl != null;
93
        if (impl instanceof ProxyLibraryImplementation) {
94
            return supportsDisplayName(((ProxyLibraryImplementation)impl).getOriginal());
95
        }
96
        return impl instanceof NamedLibraryImplementation;
97
    }
98
99
    public static @CheckForNull String getDisplayName (final @NonNull LibraryImplementation impl) {
100
        return supportsDisplayName(impl) ?
101
                ((NamedLibraryImplementation)impl).getDisplayName() :
102
                null;
103
    }
104
105
    public static boolean setDisplayName(
106
            final @NonNull LibraryImplementation impl,
107
            final @NullAllowed String name) {
108
        if (supportsDisplayName(impl)) {
109
            ((NamedLibraryImplementation)impl).setDisplayName(name);
110
            return true;
111
112
        } else {
113
            return false;
114
        }
115
    }
116
117
    public static void registerSource(
118
        final @NonNull LibraryImplementation impl,
119
        final @NonNull FileObject descriptorFile) {
120
        sources.put(impl, descriptorFile);
121
    }
122
123
124
    private static String getLocalizedString (
125
            final @NullAllowed String bundleResourceName,
126
            final @NullAllowed String key) {
127
        if (key == null) {
128
            return null;
129
        }
130
        if (bundleResourceName == null) {
131
            return key;
132
        }
133
        final ResourceBundle bundle;
134
        try {
135
            bundle = NbBundle.getBundle(bundleResourceName);
136
        } catch (MissingResourceException mre) {
137
            // Bundle should have existed.
138
            LOG.log(Level.INFO, "Wrong resource bundle", mre);      //NOI18N
139
            return key;
140
        }
141
        try {
142
            return bundle.getString (key);
143
        } catch (MissingResourceException mre) {
144
            // No problem, not specified.
145
            return key;
146
        }
147
    }
148
}
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/resources/j2se-project.xsd (-22 / +22 lines)
Lines 44-76 Link Here
44
made subject to such option by the copyright holder.
44
made subject to such option by the copyright holder.
45
-->
45
-->
46
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
46
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
47
            targetNamespace="http://www.netbeans.org/ns/j2se-project/1"
47
            targetNamespace="http://www.netbeans.org/ns/library-declaration/2"
48
            xmlns="http://www.netbeans.org/ns/j2se-project/1"
48
            xmlns="http://www.netbeans.org/ns/library-declaration/2"
49
            elementFormDefault="qualified">
49
            elementFormDefault="qualified">
50
    <xsd:element name="data">
50
    <xsd:element name="library">
51
        <xsd:complexType>
51
        <xsd:complexType>
52
            <xsd:sequence>
52
            <xsd:sequence>
53
                <xsd:element name="name" type="xsd:token"/>
53
                <xsd:element name="name" type="xsd:token"/>
54
                <xsd:element name="minimum-ant-version" minOccurs="0">
54
                <xsd:element name="type" type="xsd:token"/>
55
                    <xsd:simpleType>
55
                <xsd:element name="description" type="xsd:string" minOccurs="0" />
56
                        <xsd:restriction base="xsd:NMTOKEN">
56
                <xsd:element name="localizing-bundle" type="xsd:string" minOccurs="0"/>
57
                            <xsd:enumeration value="1.6"/>
57
                <xsd:element name="display-name" type="xsd:string" minOccurs="0"/>
58
                        </xsd:restriction>
58
                <xsd:element name="volume" type="volume" minOccurs="0" maxOccurs="unbounded"/>
59
                    </xsd:simpleType>
60
                </xsd:element>
61
                <xsd:element name="explicit-platform" minOccurs="0">
62
                    <xsd:complexType>
63
                        <xsd:attribute name="explicit-source-supported" use="required">
64
                            <xsd:simpleType>
65
                                <xsd:restriction base="xsd:NMTOKEN">
66
                                    <xsd:enumeration value="true"/>
67
                                    <xsd:enumeration value="false"/>
68
                                </xsd:restriction>
69
                            </xsd:simpleType>
70
                        </xsd:attribute>
71
                    </xsd:complexType>
72
                </xsd:element>
73
            </xsd:sequence>
59
            </xsd:sequence>
60
            <xsd:attribute name="version" use="required">
61
                <xsd:simpleType>
62
                    <xsd:restriction base="xsd:NMTOKEN">
63
                        <xsd:enumeration value="2.0"/>
64
                    </xsd:restriction>
65
                </xsd:simpleType>
66
            </xsd:attribute>
74
        </xsd:complexType>
67
        </xsd:complexType>
75
    </xsd:element>
68
    </xsd:element>
69
70
    <xsd:complexType name="volume">
71
        <xsd:sequence>
72
            <xsd:element name="type" type="xsd:token"/>
73
            <xsd:element name="resource" type="xsd:anyURI" minOccurs="0" maxOccurs="unbounded"/>
74
        </xsd:sequence>
75
    </xsd:complexType>
76
</xsd:schema>
76
</xsd:schema>
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/resources/mf-layer.xml (+6 lines)
Lines 56-61 Link Here
56
        </folder>
56
        </folder>
57
    </folder>
57
    </folder>
58
58
59
    <folder name="ProjectXMLCatalog">
60
        <folder name="library-declaration">
61
            <file name="2.xsd" url="library-declaration-2_0.xsd"/>
62
        </folder>
63
    </folder>
64
59
    <!-- Create well known SFS folders. -->
65
    <!-- Create well known SFS folders. -->
60
    <folder name="org-netbeans-api-project-libraries">
66
    <folder name="org-netbeans-api-project-libraries">
61
        <folder name="Libraries"/>
67
        <folder name="Libraries"/>
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/ui/Bundle.properties (-1 lines)
Lines 51-57 Link Here
51
51
52
ERR_ExistingName=Library {0} already exists.
52
ERR_ExistingName=Library {0} already exists.
53
ERR_InvalidName=The library name is not valid.
53
ERR_InvalidName=The library name is not valid.
54
ERR_InvalidCharacters=The library name contains invalid characters
55
54
56
CTL_LibrariesManager=&Libraries
55
CTL_LibrariesManager=&Libraries
57
56
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/ui/LibrariesCustomizer.java (-60 / +57 lines)
Lines 66-82 Link Here
66
import java.util.Collections;
66
import java.util.Collections;
67
import java.util.Comparator;
67
import java.util.Comparator;
68
import java.util.List;
68
import java.util.List;
69
import java.util.Map;
69
import java.util.regex.Pattern;
70
import java.util.MissingResourceException;
71
import java.util.ResourceBundle;
72
import java.util.WeakHashMap;
73
import java.util.logging.Level;
74
import java.util.logging.Logger;
75
import javax.swing.JComponent;
70
import javax.swing.JComponent;
76
import javax.swing.JPanel;
71
import javax.swing.JPanel;
77
import javax.swing.event.ChangeEvent;
72
import javax.swing.event.ChangeEvent;
78
import javax.swing.event.ChangeListener;
73
import javax.swing.event.ChangeListener;
74
import org.netbeans.api.annotations.common.NonNull;
75
import org.netbeans.api.annotations.common.NullAllowed;
79
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
76
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
77
import org.netbeans.modules.project.libraries.Util;
80
import org.netbeans.spi.project.libraries.LibraryCustomizerContext;
78
import org.netbeans.spi.project.libraries.LibraryCustomizerContext;
81
import org.netbeans.spi.project.libraries.LibraryImplementation;
79
import org.netbeans.spi.project.libraries.LibraryImplementation;
82
import org.netbeans.spi.project.libraries.LibraryStorageArea;
80
import org.netbeans.spi.project.libraries.LibraryStorageArea;
Lines 86-92 Link Here
86
import org.openide.NotifyDescriptor;
84
import org.openide.NotifyDescriptor;
87
import org.openide.explorer.ExplorerManager;
85
import org.openide.explorer.ExplorerManager;
88
import org.openide.explorer.view.BeanTreeView;
86
import org.openide.explorer.view.BeanTreeView;
89
import org.openide.filesystems.FileObject;
90
import org.openide.filesystems.FileUtil;
87
import org.openide.filesystems.FileUtil;
91
import org.openide.loaders.DataFolder;
88
import org.openide.loaders.DataFolder;
92
import org.openide.nodes.AbstractNode;
89
import org.openide.nodes.AbstractNode;
Lines 102-109 Link Here
102
99
103
public final class LibrariesCustomizer extends JPanel implements ExplorerManager.Provider, HelpCtx.Provider {
100
public final class LibrariesCustomizer extends JPanel implements ExplorerManager.Provider, HelpCtx.Provider {
104
101
105
    private static final Logger LOG = Logger.getLogger(LibrariesCustomizer.class.getName());
102
    private static final Pattern VALID_LIBRARY_NAME = Pattern.compile("[-._a-zA-Z0-9]+"); // NOI18N
106
107
    private ExplorerManager manager;
103
    private ExplorerManager manager;
108
    private LibrariesModel model;
104
    private LibrariesModel model;
109
    private BeanTreeView libraries;
105
    private BeanTreeView libraries;
Lines 196-201 Link Here
196
        }
192
        }
197
    }
193
    }
198
194
195
    @Override
199
    public HelpCtx getHelpCtx() {
196
    public HelpCtx getHelpCtx() {
200
        return new HelpCtx( LibrariesCustomizer.class );
197
        return new HelpCtx( LibrariesCustomizer.class );
201
    }
198
    }
Lines 210-225 Link Here
210
        }
207
        }
211
    }
208
    }
212
209
210
    @Override
213
    public void addNotify() {
211
    public void addNotify() {
214
        super.addNotify();
212
        super.addNotify();
215
        expandTree();
213
        expandTree();
216
        this.libraries.requestFocus();
214
        this.libraries.requestFocus();
217
    }    
215
    }    
218
    
216
    
217
    @Override
219
    public ExplorerManager getExplorerManager () {
218
    public ExplorerManager getExplorerManager () {
220
        if (this.manager == null) {
219
        if (this.manager == null) {
221
            this.manager = new ExplorerManager ();
220
            this.manager = new ExplorerManager ();
222
            this.manager.addPropertyChangeListener (new PropertyChangeListener() {
221
            this.manager.addPropertyChangeListener (new PropertyChangeListener() {
222
                @Override
223
                public void propertyChange (PropertyChangeEvent event) {
223
                public void propertyChange (PropertyChangeEvent event) {
224
                    if (ExplorerManager.PROP_SELECTED_NODES.equals(event.getPropertyName())) {
224
                    if (ExplorerManager.PROP_SELECTED_NODES.equals(event.getPropertyName())) {
225
                        Node[] nodes = (Node[]) event.getNewValue ();
225
                        Node[] nodes = (Node[]) event.getNewValue ();
Lines 229-234 Link Here
229
                }
229
                }
230
            });
230
            });
231
            this.manager.addVetoableChangeListener(new VetoableChangeListener() {
231
            this.manager.addVetoableChangeListener(new VetoableChangeListener() {
232
                @Override
232
                public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException {
233
                public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException {
233
                    if (ExplorerManager.PROP_SELECTED_NODES.equals(event.getPropertyName())) {
234
                    if (ExplorerManager.PROP_SELECTED_NODES.equals(event.getPropertyName())) {
234
                        Node[] nodes = (Node[]) event.getNewValue();
235
                        Node[] nodes = (Node[]) event.getNewValue();
Lines 255-260 Link Here
255
        this.libraryName.setEnabled(false);
256
        this.libraryName.setEnabled(false);
256
        this.libraryName.addActionListener(
257
        this.libraryName.addActionListener(
257
                new ActionListener () {
258
                new ActionListener () {
259
                    @Override
258
                    public void actionPerformed(ActionEvent e) {
260
                    public void actionPerformed(ActionEvent e) {
259
                        nameChanged();
261
                        nameChanged();
260
                    }
262
                    }
Lines 314-320 Link Here
314
        boolean editable = model.isLibraryEditable (impl);
316
        boolean editable = model.isLibraryEditable (impl);
315
        this.libraryName.setEnabled(editable);
317
        this.libraryName.setEnabled(editable);
316
        this.deleteButton.setEnabled(editable);
318
        this.deleteButton.setEnabled(editable);
317
        this.libraryName.setText (getLocalizedName(impl));
319
        this.libraryName.setText (Util.getLocalizedName(impl));
318
        LibraryTypeProvider provider = nodes[0].getLookup().lookup(LibraryTypeProvider.class);
320
        LibraryTypeProvider provider = nodes[0].getLookup().lookup(LibraryTypeProvider.class);
319
        if (provider == null)
321
        if (provider == null)
320
            return;
322
            return;
Lines 523-530 Link Here
523
            dlg = DialogDisplayer.getDefault().createDialog (dd);
525
            dlg = DialogDisplayer.getDefault().createDialog (dd);
524
            dlg.setVisible(true);
526
            dlg.setVisible(true);
525
            if (dd.getValue() == DialogDescriptor.OK_OPTION) {
527
            if (dd.getValue() == DialogDescriptor.OK_OPTION) {
526
                String libraryType = p.getLibraryType();
528
                final String libraryType = p.getLibraryType();
527
                String currentLibraryName = p.getLibraryName();
529
                final String currentLibraryName = p.getLibraryName();
530
                final String antLibraryName = createFreeAntLibraryName(currentLibraryName, model, area);
528
                LibraryImplementation impl;
531
                LibraryImplementation impl;
529
                if (area != LibrariesModel.GLOBAL_AREA) {
532
                if (area != LibrariesModel.GLOBAL_AREA) {
530
                    impl = model.createArealLibrary(libraryType, currentLibraryName, area);
533
                    impl = model.createArealLibrary(libraryType, currentLibraryName, area);
Lines 534-541 Link Here
534
                        return;
537
                        return;
535
                    }
538
                    }
536
                    impl = provider.createLibrary();
539
                    impl = provider.createLibrary();
537
                    impl.setName(currentLibraryName);
540
                    impl.setName(antLibraryName);
538
                }
541
                }
542
                Util.setDisplayName(impl, currentLibraryName);
539
                model.addLibrary (impl);                
543
                model.addLibrary (impl);                
540
                forceTreeRecreation();
544
                forceTreeRecreation();
541
                String[] path = {impl.getType(), impl.getName()};
545
                String[] path = {impl.getType(), impl.getName()};
Lines 564-570 Link Here
564
        }
568
        }
565
    }//GEN-LAST:event_createLibrary
569
    }//GEN-LAST:event_createLibrary
566
570
567
    static boolean isValidName(LibrariesModel model, String name, LibraryStorageArea area) {
571
    static boolean isExistingDisplayName(
572
            final @NonNull LibrariesModel model,
573
            final @NonNull String name,
574
            final @NullAllowed LibraryStorageArea area) {
575
        for (LibraryImplementation lib : model.getLibraries()) {
576
            if (Util.getLocalizedName(lib).equals(name) && Utilities.compareObjects(model.getArea(lib), area)) {
577
                return true;
578
            }
579
        }
580
        return false;
581
    }
582
583
    private static boolean isValidName(
584
            final @NonNull LibrariesModel model,
585
            final @NonNull String name,
586
            final @NullAllowed LibraryStorageArea area) {
568
        for (LibraryImplementation lib : model.getLibraries()) {
587
        for (LibraryImplementation lib : model.getLibraries()) {
569
            if (lib.getName().equals(name) && Utilities.compareObjects(model.getArea(lib), area)) {
588
            if (lib.getName().equals(name) && Utilities.compareObjects(model.getArea(lib), area)) {
570
                return false;
589
                return false;
Lines 573-625 Link Here
573
        return true;
592
        return true;
574
    }
593
    }
575
594
576
    private static Map<LibraryImplementation,FileObject> sources = new WeakHashMap<LibraryImplementation,FileObject>();
595
577
    public static void registerSource(LibraryImplementation impl, FileObject descriptorFile) {
596
    public static String createFreeAntLibraryName(
578
        sources.put(impl, descriptorFile);
597
            @NonNull String name,
598
            final @NonNull LibrariesModel model,
599
            final @NullAllowed LibraryStorageArea area) {
600
        // XXX: there is method in PropertyUtils
601
        // which should be used here but that would create dependency
602
        // on ant/project modules which is not desirable.
603
        if (!VALID_LIBRARY_NAME.matcher(name).matches()) {
604
            final StringBuilder sb = new StringBuilder(name);
605
            for (int i=0; i<sb.length(); i++) {
606
                if (!VALID_LIBRARY_NAME.matcher(sb.substring(i,i+1)).matches()) {
607
                    sb.replace(i,i+1,"_");
608
                }
609
            }
610
            name = sb.toString();
611
        }        
612
        String uniqueName = name;
613
        for (int i=2; !isValidName(model, uniqueName, area); i++) {
614
            uniqueName = String.format("%s_%d", name,i);    //NOI18N
615
        }
616
        return uniqueName;
579
    }
617
    }
580
618
581
619
        
582
    public static String getLocalizedName(LibraryImplementation impl) {
583
        FileObject src = sources.get(impl);
584
        if (src != null) {
585
            Object obj = src.getAttribute("displayName"); // NOI18N
586
            if (obj instanceof String) {
587
                return (String)obj;
588
            }
589
        }
590
        if (impl instanceof ProxyLibraryImplementation) {
591
            String proxiedName = getLocalizedName(((ProxyLibraryImplementation)impl).getOriginal());
592
            if (proxiedName != null) {
593
                return proxiedName;
594
            }
595
        }
596
597
        return getLocalizedString(impl.getLocalizingBundle(), impl.getName());
598
    }
599
600
    static String getLocalizedString (String bundleResourceName, String key) {
601
        if (key == null) {
602
            return null;
603
        }
604
        if (bundleResourceName == null) {
605
            return key;
606
        }
607
        ResourceBundle bundle;
608
        try {
609
            bundle = NbBundle.getBundle(bundleResourceName);
610
        } catch (MissingResourceException mre) {
611
            // Bundle should have existed.
612
            LOG.log(Level.INFO, "Wrong resource bundle", mre);      //NOI18N
613
            return key;
614
        }
615
        try {
616
            return bundle.getString (key);
617
        } catch (MissingResourceException mre) {
618
            // No problem, not specified.
619
            return key;
620
        }
621
    }
622
623
    // Variables declaration - do not modify//GEN-BEGIN:variables
620
    // Variables declaration - do not modify//GEN-BEGIN:variables
624
    private javax.swing.JButton createButton;
621
    private javax.swing.JButton createButton;
625
    private javax.swing.JButton deleteButton;
622
    private javax.swing.JButton deleteButton;
Lines 851-857 Link Here
851
        }
848
        }
852
        
849
        
853
        public String getDisplayName () {
850
        public String getDisplayName () {
854
            return getLocalizedName(this.lib);
851
            return Util.getLocalizedName(this.lib);
855
        }
852
        }
856
        
853
        
857
    }
854
    }
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/ui/LibrariesModel.java (-4 / +32 lines)
Lines 65-77 Link Here
65
import java.util.logging.Level;
65
import java.util.logging.Level;
66
import java.util.logging.Logger;
66
import java.util.logging.Logger;
67
import javax.swing.event.ChangeListener;
67
import javax.swing.event.ChangeListener;
68
import org.netbeans.api.annotations.common.NullAllowed;
68
import org.netbeans.modules.project.libraries.LibraryAccessor;
69
import org.netbeans.modules.project.libraries.LibraryAccessor;
70
import org.netbeans.modules.project.libraries.Util;
69
import org.netbeans.spi.project.libraries.LibraryImplementation;
71
import org.netbeans.spi.project.libraries.LibraryImplementation;
70
import org.netbeans.spi.project.libraries.LibraryProvider;
72
import org.netbeans.spi.project.libraries.LibraryProvider;
71
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
73
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
72
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
74
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
73
import org.netbeans.spi.project.libraries.LibraryImplementation2;
75
import org.netbeans.spi.project.libraries.LibraryImplementation2;
74
import org.netbeans.spi.project.libraries.LibraryStorageArea;
76
import org.netbeans.spi.project.libraries.LibraryStorageArea;
77
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
75
import org.openide.util.Exceptions;
78
import org.openide.util.Exceptions;
76
import org.openide.util.Lookup;
79
import org.openide.util.Lookup;
77
import org.openide.util.ChangeSupport;
80
import org.openide.util.ChangeSupport;
Lines 246-252 Link Here
246
            if (area != null) {
249
            if (area != null) {
247
                ArealLibraryProvider alp = area2Storage.get(area);
250
                ArealLibraryProvider alp = area2Storage.get(area);
248
                assert alp != null : "Unknown area: " + area + " known areas: " + area2Storage.keySet();
251
                assert alp != null : "Unknown area: " + area + " known areas: " + area2Storage.keySet();
249
                LibraryAccessor.createLibrary(alp, impl.getType(), impl.getName(), area, ((DummyArealLibrary) impl).contents);
252
                final LibraryImplementation2 createdLib = LibraryAccessor.createLibrary(alp, impl.getType(), impl.getName(), area, ((DummyArealLibrary) impl).contents);
253
                Util.setDisplayName(createdLib, Util.getDisplayName(impl));
250
            } else if (writableProvider != null) {
254
            } else if (writableProvider != null) {
251
                writableProvider.addLibrary(impl);
255
                writableProvider.addLibrary(impl);
252
            } else {
256
            } else {
Lines 358-401 Link Here
358
362
359
    private static class LibrariesComparator implements Comparator<LibraryImplementation> {
363
    private static class LibrariesComparator implements Comparator<LibraryImplementation> {
360
        public int compare(LibraryImplementation lib1, LibraryImplementation lib2) {
364
        public int compare(LibraryImplementation lib1, LibraryImplementation lib2) {
361
            String name1 = LibrariesCustomizer.getLocalizedName(lib1);
365
            String name1 = Util.getLocalizedName(lib1);
362
            String name2 = LibrariesCustomizer.getLocalizedName(lib2);
366
            String name2 = Util.getLocalizedName(lib2);
363
            int r = name1.compareToIgnoreCase(name2);
367
            int r = name1.compareToIgnoreCase(name2);
364
            return r != 0 ? r : System.identityHashCode(lib1) - System.identityHashCode(lib2);
368
            return r != 0 ? r : System.identityHashCode(lib1) - System.identityHashCode(lib2);
365
        }
369
        }
366
    }
370
    }
367
371
368
    private static final class DummyArealLibrary implements LibraryImplementation2 {
372
    private static final class DummyArealLibrary implements LibraryImplementation2, NamedLibraryImplementation {
369
373
370
        private final String type, name;
374
        private final String type, name;
371
        final Map<String,List<URI>> contents = new HashMap<String,List<URI>>();
375
        final Map<String,List<URI>> contents = new HashMap<String,List<URI>>();
372
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
376
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
377
        private String displayName;
373
378
374
        public DummyArealLibrary(String type, String name) {
379
        public DummyArealLibrary(String type, String name) {
375
            this.type = type;
380
            this.type = type;
376
            this.name = name;
381
            this.name = name;
377
        }
382
        }
378
383
384
        @Override
379
        public String getType() {
385
        public String getType() {
380
            return type;
386
            return type;
381
        }
387
        }
382
388
389
        @Override
383
        public String getName() {
390
        public String getName() {
384
            return name;
391
            return name;
385
        }
392
        }
386
393
394
        @Override
395
        public String getDisplayName() {
396
            return displayName;
397
        }
398
399
        @Override
387
        public String getDescription() {
400
        public String getDescription() {
388
            return null;
401
            return null;
389
        }
402
        }
390
403
404
        @Override
391
        public String getLocalizingBundle() {
405
        public String getLocalizingBundle() {
392
            return null;
406
            return null;
393
        }
407
        }
394
408
409
        @Override
395
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
410
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
396
            return convertURIsToURLs(getURIContent(volumeType));
411
            return convertURIsToURLs(getURIContent(volumeType));
397
        }
412
        }
398
        
413
        
414
        @Override
399
        public List<URI> getURIContent(String volumeType) throws IllegalArgumentException {
415
        public List<URI> getURIContent(String volumeType) throws IllegalArgumentException {
400
            List<URI> content = contents.get(volumeType);
416
            List<URI> content = contents.get(volumeType);
401
            if (content != null) {
417
            if (content != null) {
Lines 405-434 Link Here
405
            }
421
            }
406
        }
422
        }
407
423
424
        @Override
408
        public void setName(String name) {
425
        public void setName(String name) {
409
            throw new UnsupportedOperationException();
426
            throw new UnsupportedOperationException();
410
        }
427
        }
411
428
429
        @Override
430
        public void setDisplayName(final @NullAllowed String displayName) {
431
            this.displayName = displayName;
432
        }
433
434
        @Override
412
        public void setDescription(String text) {
435
        public void setDescription(String text) {
413
            throw new UnsupportedOperationException();
436
            throw new UnsupportedOperationException();
414
        }
437
        }
415
438
439
        @Override
416
        public void setLocalizingBundle(String resourceName) {
440
        public void setLocalizingBundle(String resourceName) {
417
            throw new UnsupportedOperationException();
441
            throw new UnsupportedOperationException();
418
        }
442
        }
419
443
444
        @Override
420
        public void addPropertyChangeListener(PropertyChangeListener l) {
445
        public void addPropertyChangeListener(PropertyChangeListener l) {
421
            pcs.addPropertyChangeListener(l);
446
            pcs.addPropertyChangeListener(l);
422
        }
447
        }
423
448
449
        @Override
424
        public void removePropertyChangeListener(PropertyChangeListener l) {
450
        public void removePropertyChangeListener(PropertyChangeListener l) {
425
            pcs.removePropertyChangeListener(l);
451
            pcs.removePropertyChangeListener(l);
426
        }
452
        }
427
453
454
        @Override
428
        public void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
455
        public void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
429
            setURIContent(volumeType, convertURLsToURIs(path));
456
            setURIContent(volumeType, convertURLsToURIs(path));
430
        }
457
        }
431
458
459
        @Override
432
        public void setURIContent(String volumeType, List<URI> path) throws IllegalArgumentException {
460
        public void setURIContent(String volumeType, List<URI> path) throws IllegalArgumentException {
433
            contents.put(volumeType, path);
461
            contents.put(volumeType, path);
434
            pcs.firePropertyChange(LibraryImplementation.PROP_CONTENT, null, null);
462
            pcs.firePropertyChange(LibraryImplementation.PROP_CONTENT, null, null);
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/ui/LibraryRenderer.java (-1 / +2 lines)
Lines 48-60 Link Here
48
import java.awt.Component;
48
import java.awt.Component;
49
import javax.swing.DefaultListCellRenderer;
49
import javax.swing.DefaultListCellRenderer;
50
import javax.swing.JList;
50
import javax.swing.JList;
51
import org.netbeans.modules.project.libraries.Util;
51
52
52
class LibraryRenderer extends DefaultListCellRenderer {
53
class LibraryRenderer extends DefaultListCellRenderer {
53
54
54
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
55
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
55
        LibraryImplementation impl = (LibraryImplementation) value;
56
        LibraryImplementation impl = (LibraryImplementation) value;
56
        return super.getListCellRendererComponent(list,
57
        return super.getListCellRendererComponent(list,
57
                LibrariesCustomizer.getLocalizedName(impl),
58
                Util.getLocalizedName(impl),
58
                index, isSelected, cellHasFocus);
59
                index, isSelected, cellHasFocus);
59
    }
60
    }
60
61
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/ui/NewLibraryPanel.java (-30 / +7 lines)
Lines 45-57 Link Here
45
package org.netbeans.modules.project.libraries.ui;
45
package org.netbeans.modules.project.libraries.ui;
46
46
47
import java.awt.Color;
47
import java.awt.Color;
48
import java.awt.Component;
49
import java.util.HashMap;
48
import java.util.HashMap;
50
import java.util.Map;
49
import java.util.Map;
51
import java.util.regex.Pattern;
52
import javax.swing.DefaultComboBoxModel;
53
import javax.swing.DefaultListCellRenderer;
54
import javax.swing.JList;
55
import org.openide.DialogDescriptor;
50
import org.openide.DialogDescriptor;
56
import org.openide.util.NbBundle;
51
import org.openide.util.NbBundle;
57
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
52
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
Lines 65-72 Link Here
65
    private LibraryStorageArea area;
60
    private LibraryStorageArea area;
66
61
67
    private DialogDescriptor dd;
62
    private DialogDescriptor dd;
68
63
    
69
    private static final Pattern VALID_LIBRARY_NAME = Pattern.compile("[-._a-zA-Z0-9]+"); // NOI18N
70
64
71
    public NewLibraryPanel (LibrariesModel model, String preselectedLibraryType, LibraryStorageArea area) {
65
    public NewLibraryPanel (LibrariesModel model, String preselectedLibraryType, LibraryStorageArea area) {
72
        this.model = model;
66
        this.model = model;
Lines 142-178 Link Here
142
    private void nameChanged () {
136
    private void nameChanged () {
143
        String name = this.name.getText();
137
        String name = this.name.getText();
144
        boolean valid = false;
138
        boolean valid = false;
145
        String message;
139
        String message = "";    //NOI18N
146
        if (name.length() == 0) {
140
        if (name.length() == 0) {
147
            message = NbBundle.getMessage(NewLibraryPanel.class,"ERR_InvalidName");
141
            message = NbBundle.getMessage(NewLibraryPanel.class,"ERR_InvalidName");
148
        }
142
        } else if (LibrariesCustomizer.isExistingDisplayName(model, name, area)){
149
        else {
143
            message = NbBundle.getMessage(NewLibraryPanel.class, "ERR_ExistingName", name);
150
            valid = LibrariesCustomizer.isValidName(model, name, area);
144
        } else {
151
            if (valid) {
145
            valid = true;
152
                if (isReasonableAntProperty(name)) {
153
                    message = " ";   //NOI18N
154
                } else {
155
                    valid = false;
156
                    message = NbBundle.getMessage(NewLibraryPanel.class,"ERR_InvalidCharacters");
157
                }
158
            }
159
            else {
160
                message = NbBundle.getMessage(NewLibraryPanel.class, "ERR_ExistingName", name);
161
            }
162
        }
146
        }
163
        if (dd != null) {
147
        if (dd != null) {
164
            dd.setValid(valid);
148
            dd.setValid(valid);
165
        }
149
        }
166
        this.status.setText(message);
150
        this.status.setText(message);
167
    }
151
    }
168
    
152
        
169
    private boolean isReasonableAntProperty(String name) {
170
        // XXX: there is method in PropertyUtils.isUsablePropertyName()
171
        // which should be used here but that would create dependency
172
        // on ant/project modules which is not desirable.
173
        // XXX: The restriction of display name should be fixed in promo F
174
        return VALID_LIBRARY_NAME.matcher(name).matches();
175
    }
176
    
153
    
177
    /** This method is called from within the constructor to
154
    /** This method is called from within the constructor to
178
     * initialize the form.
155
     * initialize the form.
(-)a/project.libraries/src/org/netbeans/modules/project/libraries/ui/ProxyLibraryImplementation.java (-4 / +50 lines)
Lines 52-75 Link Here
52
import java.beans.PropertyChangeSupport;
52
import java.beans.PropertyChangeSupport;
53
import java.beans.PropertyChangeListener;
53
import java.beans.PropertyChangeListener;
54
import java.beans.PropertyChangeEvent;
54
import java.beans.PropertyChangeEvent;
55
import org.netbeans.api.annotations.common.NullAllowed;
56
import org.netbeans.modules.project.libraries.Util;
55
57
56
import org.netbeans.spi.project.libraries.LibraryImplementation;
58
import org.netbeans.spi.project.libraries.LibraryImplementation;
57
import org.netbeans.spi.project.libraries.LibraryImplementation2;
59
import org.netbeans.spi.project.libraries.LibraryImplementation2;
60
import org.netbeans.spi.project.libraries.NamedLibraryImplementation;
58
import org.openide.util.WeakListeners;
61
import org.openide.util.WeakListeners;
59
62
60
/**
63
/**
61
 *
64
 *
62
 * @author  tom
65
 * @author  tom
63
 */
66
 */
64
public class ProxyLibraryImplementation implements LibraryImplementation, PropertyChangeListener  {
67
public class ProxyLibraryImplementation implements NamedLibraryImplementation, PropertyChangeListener  {
65
68
66
    private final LibraryImplementation original;
69
    private final LibraryImplementation original;
67
    private final LibrariesModel model;
70
    private final LibrariesModel model;
68
    Map<String,List<URL>> newContents;
71
    Map<String,List<URL>> newContents;
69
    private String newName;
72
    private String newName;
73
    private String newDisplayName;
70
    private String newDescription;
74
    private String newDescription;
71
    private PropertyChangeSupport support;
75
    private PropertyChangeSupport support;
72
76
77
    @SuppressWarnings("LeakingThisInConstructor")
73
    private ProxyLibraryImplementation (LibraryImplementation original, LibrariesModel model) {
78
    private ProxyLibraryImplementation (LibraryImplementation original, LibrariesModel model) {
74
        assert original != null && model != null;
79
        assert original != null && model != null;
75
        this.original = original;
80
        this.original = original;
Lines 98-116 Link Here
98
        return this.original;
103
        return this.original;
99
    }
104
    }
100
    
105
    
106
    @Override
101
    public void addPropertyChangeListener(PropertyChangeListener l) {
107
    public void addPropertyChangeListener(PropertyChangeListener l) {
102
        this.support.addPropertyChangeListener(l);
108
        this.support.addPropertyChangeListener(l);
103
    }
109
    }
104
    
110
    
111
    @Override
105
    public void removePropertyChangeListener(PropertyChangeListener l) {
112
    public void removePropertyChangeListener(PropertyChangeListener l) {
106
        this.support.removePropertyChangeListener(l);
113
        this.support.removePropertyChangeListener(l);
107
    }
114
    }
108
    
115
    
116
    @Override
109
    public String getType() {
117
    public String getType() {
110
        return this.original.getType ();
118
        return this.original.getType ();
111
    }
119
    }
112
    
120
    
113
    
121
    
122
    @Override
114
    public synchronized List<URL> getContent(String volumeType) throws IllegalArgumentException {
123
    public synchronized List<URL> getContent(String volumeType) throws IllegalArgumentException {
115
        List<URL> result = null;
124
        List<URL> result = null;
116
        if (newContents == null || (result = newContents.get(volumeType)) == null) {
125
        if (newContents == null || (result = newContents.get(volumeType)) == null) {
Lines 121-126 Link Here
121
        }
130
        }
122
    }
131
    }
123
    
132
    
133
    @Override
124
    public synchronized String getDescription() {
134
    public synchronized String getDescription() {
125
        if (this.newDescription != null) {
135
        if (this.newDescription != null) {
126
            return this.newDescription;
136
            return this.newDescription;
Lines 130-135 Link Here
130
        }
140
        }
131
    }
141
    }
132
    
142
    
143
    @Override
133
    public synchronized String getName() {
144
    public synchronized String getName() {
134
        if (this.newName != null) {
145
        if (this.newName != null) {
135
            return this.newName;
146
            return this.newName;
Lines 138-144 Link Here
138
            return this.original.getName ();
149
            return this.original.getName ();
139
        }
150
        }
140
    }
151
    }
152
153
    @Override
154
    public String getDisplayName() {
155
        if (!Util.supportsDisplayName(original)) {
156
            throw new IllegalStateException("Original does not support displayName");   //NOI18N
157
        }
158
        synchronized (this) {
159
            return newDisplayName != null ? newDisplayName : Util.getDisplayName(original);
160
        }
161
    }
141
    
162
    
163
    @Override
142
    public synchronized void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
164
    public synchronized void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
143
        if (this.newContents == null) {
165
        if (this.newContents == null) {
144
            this.newContents = new HashMap<String,List<URL>>();
166
            this.newContents = new HashMap<String,List<URL>>();
Lines 148-153 Link Here
148
        this.support.firePropertyChange(PROP_CONTENT,null,null);        //NOI18N
170
        this.support.firePropertyChange(PROP_CONTENT,null,null);        //NOI18N
149
    }
171
    }
150
    
172
    
173
    @Override
151
    public synchronized void setDescription(String text) {
174
    public synchronized void setDescription(String text) {
152
        String oldDescription = this.newDescription == null ? this.original.getDescription() : this.newDescription;
175
        String oldDescription = this.newDescription == null ? this.original.getDescription() : this.newDescription;
153
        this.newDescription = text;
176
        this.newDescription = text;
Lines 155-160 Link Here
155
        this.support.firePropertyChange(PROP_DESCRIPTION,oldDescription,this.newDescription);   //NOI18N
178
        this.support.firePropertyChange(PROP_DESCRIPTION,oldDescription,this.newDescription);   //NOI18N
156
    }
179
    }
157
    
180
    
181
    @Override
158
    public synchronized void setName(String name) {
182
    public synchronized void setName(String name) {
159
        String oldName = this.newName == null ? this.original.getName() : this.newName;
183
        String oldName = this.newName == null ? this.original.getName() : this.newName;
160
        this.newName = name;
184
        this.newName = name;
Lines 162-185 Link Here
162
        this.support.firePropertyChange(PROP_NAME,oldName,this.newName);       //NOI18N
186
        this.support.firePropertyChange(PROP_NAME,oldName,this.newName);       //NOI18N
163
    }
187
    }
164
188
189
    @Override
190
    public void setDisplayName(final @NullAllowed String displayName) {
191
        final String oldName;
192
        synchronized (this) {
193
            oldName = this.newDisplayName != null ? this.newDisplayName : Util.getDisplayName(original);
194
            this.newName = displayName;
195
            this.model.modifyLibrary(this);
196
        }
197
        this.support.firePropertyChange(PROP_DISPLAY_NAME, oldName, displayName);
198
    }
165
199
200
201
    @Override
166
    public String getLocalizingBundle() {
202
    public String getLocalizingBundle() {
167
        return this.original.getLocalizingBundle();
203
        return this.original.getLocalizingBundle();
168
    }
204
    }
169
205
206
    @Override
170
    public void setLocalizingBundle(String resourceName) {
207
    public void setLocalizingBundle(String resourceName) {
171
        throw new UnsupportedOperationException();
208
        throw new UnsupportedOperationException();
172
    }
209
    }
173
210
211
    @Override
174
    public void propertyChange(PropertyChangeEvent evt) {
212
    public void propertyChange(PropertyChangeEvent evt) {
175
        this.support.firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());
213
        this.support.firePropertyChange(evt.getPropertyName(),evt.getOldValue(),evt.getNewValue());
176
    }
214
    }
177
215
178
216
217
    @Override
179
    public int hashCode() {
218
    public int hashCode() {
180
        return this.original.hashCode();
219
        return this.original.hashCode();
181
    }
220
    }
182
221
222
    @Override
183
    public boolean equals(Object obj) {
223
    public boolean equals(Object obj) {
184
        if (obj instanceof ProxyLibraryImplementation) {
224
        if (obj instanceof ProxyLibraryImplementation) {
185
            return this.original.equals(((ProxyLibraryImplementation)obj).getOriginal());
225
            return this.original.equals(((ProxyLibraryImplementation)obj).getOriginal());
Lines 188-198 Link Here
188
            return false;
228
            return false;
189
    }
229
    }
190
230
191
    public @Override String toString() {
231
    @Override
232
    public String toString() {
192
        return "Proxy[" + original + "]"; // NOI18N
233
        return "Proxy[" + original + "]"; // NOI18N
193
    }
234
    }
194
235
195
    static class ProxyLibraryImplementation2 extends ProxyLibraryImplementation implements LibraryImplementation2 {
236
    static class ProxyLibraryImplementation2 extends ProxyLibraryImplementation implements LibraryImplementation2, NamedLibraryImplementation {
196
237
197
        Map<String,List<URI>> newURIContents;
238
        Map<String,List<URI>> newURIContents;
198
        
239
        
Lines 204-209 Link Here
204
            return (LibraryImplementation2)getOriginal();
245
            return (LibraryImplementation2)getOriginal();
205
        }
246
        }
206
        
247
        
248
        @Override
207
        public List<URI> getURIContent(String volumeType) throws IllegalArgumentException {
249
        public List<URI> getURIContent(String volumeType) throws IllegalArgumentException {
208
            List<URI> result = null;
250
            List<URI> result = null;
209
            if (newURIContents == null || (result = newURIContents.get(volumeType)) == null) {
251
            if (newURIContents == null || (result = newURIContents.get(volumeType)) == null) {
Lines 213-218 Link Here
213
            }
255
            }
214
        }
256
        }
215
257
258
        @Override
216
        public void setURIContent(String volumeType, List<URI> path) throws IllegalArgumentException {
259
        public void setURIContent(String volumeType, List<URI> path) throws IllegalArgumentException {
217
            if (newURIContents == null) {
260
            if (newURIContents == null) {
218
                newURIContents = new HashMap<String,List<URI>>();
261
                newURIContents = new HashMap<String,List<URI>>();
Lines 222-231 Link Here
222
            getSupport().firePropertyChange(PROP_CONTENT,null,null);
265
            getSupport().firePropertyChange(PROP_CONTENT,null,null);
223
        }
266
        }
224
        
267
        
268
        @Override
225
        public final int hashCode() {
269
        public final int hashCode() {
226
            return getOriginal().hashCode();
270
            return getOriginal().hashCode();
227
        }
271
        }
228
272
273
        @Override
229
        public final boolean equals(Object obj) {
274
        public final boolean equals(Object obj) {
230
            if (obj instanceof ProxyLibraryImplementation2) {
275
            if (obj instanceof ProxyLibraryImplementation2) {
231
                return getOriginal().equals(((ProxyLibraryImplementation2)obj).getOriginal());
276
                return getOriginal().equals(((ProxyLibraryImplementation2)obj).getOriginal());
Lines 234-240 Link Here
234
                return false;
279
                return false;
235
        }
280
        }
236
281
237
        public @Override String toString() {
282
        @Override
283
        public String toString() {
238
            return "Proxy2[" + getOriginal() + "]"; // NOI18N
284
            return "Proxy2[" + getOriginal() + "]"; // NOI18N
239
        }
285
        }
240
    }
286
    }
(-)a/project.libraries/src/org/netbeans/spi/project/libraries/NamedLibraryImplementation.java (+72 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.spi.project.libraries;
43
44
import org.netbeans.api.annotations.common.CheckForNull;
45
import org.netbeans.api.annotations.common.NullAllowed;
46
47
/**
48
 * LibraryImplementation extension allowing setting/getting display name.
49
 * @author Tomas Zezula
50
 * @since org.netbeans.modules.project.libraries/1 1.31
51
 */
52
public interface NamedLibraryImplementation extends LibraryImplementation {
53
54
    /**
55
     * Name of displayName property.
56
     */
57
    String PROP_DISPLAY_NAME = "displayName";   //NOI18N
58
59
    /**
60
     * Sets the display name.
61
     * @param displayName the new value of the displayName.
62
     * If null resets the display name to the value provided
63
     * by the localizing bundle or the identifying name.
64
     */
65
    void setDisplayName(@NullAllowed String displayName);
66
67
    /**
68
     * Returns the display name if available or null.
69
     * @return the display name
70
     */
71
    @CheckForNull String getDisplayName();
72
}
(-)a/project.libraries/test/unit/src/org/netbeans/modules/project/libraries/LibrariesStorageTest.java (-2 / +2 lines)
Lines 138-149 Link Here
138
        assertEquals("Libraries count",2,libs.length);
138
        assertEquals("Libraries count",2,libs.length);
139
        LibraryImplementation impl = libs[0].getName().equals("Library2") ? libs[0] : libs[1];
139
        LibraryImplementation impl = libs[0].getName().equals("Library2") ? libs[0] : libs[1];
140
140
141
        assertEquals("MyName", LibrariesCustomizer.getLocalizedName(impl));
141
        assertEquals("MyName", Util.getLocalizedName(impl));
142
142
143
        LibrariesModel model = new LibrariesModel();
143
        LibrariesModel model = new LibrariesModel();
144
        ProxyLibraryImplementation proxy = ProxyLibraryImplementation.createProxy(impl, model);
144
        ProxyLibraryImplementation proxy = ProxyLibraryImplementation.createProxy(impl, model);
145
145
146
        assertEquals("MyName", LibrariesCustomizer.getLocalizedName(proxy));
146
        assertEquals("MyName", Util.getLocalizedName(proxy));
147
    }
147
    }
148
148
149
    public void testAddLibrary() throws Exception {
149
    public void testAddLibrary() throws Exception {

Return to bug 199253