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 44035
Collapse All | Expand All

(-)projects/libraries/apichanges.xml:1.9 (+43 lines)
Lines 103-108 Link Here
103
103
104
    <!-- ACTUAL CHANGES BEGIN HERE: -->
104
    <!-- ACTUAL CHANGES BEGIN HERE: -->
105
    <changes>
105
    <changes>
106
107
    <change id="project-libraries">
108
        <api name="general"/>
109
        <summary>Support for project libraries</summary>
110
        <version major="1" minor="17"/>
111
        <date day="22" month="1" year="2008"/>
112
        <author login="jglick"/>
113
        <compatibility addition="yes" deprecation="yes">
114
            <p>
115
                <code>LibraryManager.addLibrary</code> will not work with areas,
116
                so it was deprecated in favor of the new <code>createLibrary</code>.
117
            </p>
118
            <p>
119
                Code which obtained a <code>Library</code> of arbitrary origin,
120
                and then assumed it could refer to that library henceforth by name only,
121
                will not work with project libraries.
122
                The simplest persistent identifier for a new-style library is pair of name
123
                and URL of manager (null for the default manager).
124
            </p>
125
        </compatibility>
126
        <description>
127
            <p>
128
                There is a new API and SPI for project libraries
129
                (or, more generally, libraries with specific storage locations).
130
                <code>LibraryChooser</code>, <code>ArealLibraryProvider</code>,
131
                and <code>LibraryStorageArea</code> are new, as are methods
132
                <code>Library.getManager</code>,
133
                <code>LibraryManager.getDisplayName</code>,
134
                <code>LibraryManager.getLocation</code>,
135
                <code>LibraryManager.createLibrary</code>,
136
                <code>LibraryManager.forLocation</code>, and
137
                <code>LibraryManager.getOpenManagers</code>.
138
                (<code>LibraryProvider</code> was also generified.)
139
            </p>
140
        </description>
141
        <class package="org.netbeans.api.project.libraries" name="LibraryManager"/>
142
        <class package="org.netbeans.api.project.libraries" name="Library"/>
143
        <class package="org.netbeans.api.project.libraries" name="LibraryChooser"/>
144
        <class package="org.netbeans.spi.project.libraries" name="LibraryProvider"/>
145
        <class package="org.netbeans.spi.project.libraries" name="ArealLibraryProvider"/>
146
        <class package="org.netbeans.spi.project.libraries" name="LibraryStorageArea"/>
147
        <issue number="44035"/>
148
    </change>
106
    
149
    
107
    <change id="Customizer-can-be-null">
150
    <change id="Customizer-can-be-null">
108
            <api name="general"/>
151
            <api name="general"/>
(-)projects/libraries/nbproject/project.xml:1.16 (+10 lines)
Lines 47-52 Link Here
47
            <code-name-base>org.netbeans.modules.project.libraries</code-name-base>
47
            <code-name-base>org.netbeans.modules.project.libraries</code-name-base>
48
            <module-dependencies>
48
            <module-dependencies>
49
                <dependency>
49
                <dependency>
50
                    <code-name-base>org.jdesktop.layout</code-name-base>
51
                    <build-prerequisite/>
52
                    <compile-dependency/>
53
                    <run-dependency>
54
                        <release-version>1</release-version>
55
                        <specification-version>1.5</specification-version>
56
                    </run-dependency>
57
                </dependency>
58
                <dependency>
50
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
59
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
51
                    <build-prerequisite/>
60
                    <build-prerequisite/>
52
                    <compile-dependency/>
61
                    <compile-dependency/>
Lines 145-150 Link Here
145
                    </test-dependency>
154
                    </test-dependency>
146
                    <test-dependency>
155
                    <test-dependency>
147
                        <code-name-base>org.openide.util</code-name-base>
156
                        <code-name-base>org.openide.util</code-name-base>
157
                        <compile-dependency/>
148
                        <test/>
158
                        <test/>
149
                    </test-dependency>
159
                    </test-dependency>
150
                </test-type>
160
                </test-type>
(-)projects/libraries/src/org/netbeans/api/project/libraries/Bundle.properties:1.6 (+13 lines)
Lines 38-40 Link Here
38
# made subject to such option by the copyright holder.
38
# made subject to such option by the copyright holder.
39
39
40
TXT_LibrariesManager=Library Manager
40
TXT_LibrariesManager=Library Manager
41
42
LibraryChooserGUI.add.title=Add Library
43
LibraryChooserGUI.add.button=Add Library
44
LibraryChooserGUI.import.title=Import Library
45
LibraryChooserGUI.import.button=Import Library
46
LibraryChooserGUI.manage=&Manage Libraries...
47
LibraryChooserGUI.accessibleDescription=The library manager allows you to add predefined libraries to the project classpath or to edit library definitions.
48
LibraryChooserGUI.librariesLabel=Available &Libraries:
49
LibraryChooserGUI.createButton.text=Create...
50
LibraryChooserGUI.importButton.text=Import...
51
LibraryChooserGUI.manageLibrariesButton.text=Manage Libraries...
52
LibrariesCustomizer.createLibrary.title=Create New Library
53
LibrariesCustomizer.customizeLibrary.title=Customize Library
(-)projects/libraries/src/org/netbeans/api/project/libraries/LibrariesCustomizer.java:1.5 (-10 / +101 lines)
Lines 45-50 Link Here
45
import org.openide.DialogDisplayer;
45
import org.openide.DialogDisplayer;
46
import org.openide.util.NbBundle;
46
import org.openide.util.NbBundle;
47
import java.awt.Dialog;
47
import java.awt.Dialog;
48
import javax.swing.border.EmptyBorder;
49
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
50
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
51
import org.netbeans.modules.project.libraries.ui.NewLibraryPanel;
52
import org.netbeans.spi.project.libraries.LibraryImplementation;
53
import org.netbeans.spi.project.libraries.LibraryStorageArea;
54
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
48
55
49
/** Provides method for opening Libraries customizer
56
/** Provides method for opening Libraries customizer
50
 *
57
 *
Lines 55-86 Link Here
55
    }
62
    }
56
63
57
    /**
64
    /**
58
     * Shows libraries customizer
65
     * Shows libraries customizer for given library manager.
59
     * @param activeLibrary if not null the activeLibrary is selected in the opened customizer
66
     * @param activeLibrary if not null the activeLibrary is selected in the opened customizer
60
     * @return true if user pressed OK and libraries were sucessfully modified
67
     * @return true if user pressed OK and libraries were sucessfully modified
61
     */
68
     */
62
    public static boolean showCustomizer (Library activeLibrary) {
69
    public static boolean showCustomizer (Library activeLibrary, LibraryManager libraryManager) {
63
        org.netbeans.modules.project.libraries.ui.LibrariesCustomizer  customizer =
70
        org.netbeans.modules.project.libraries.ui.LibrariesCustomizer  customizer =
64
                new org.netbeans.modules.project.libraries.ui.LibrariesCustomizer ();
71
                new org.netbeans.modules.project.libraries.ui.LibrariesCustomizer (libraryManager.getArea());
72
        customizer.setBorder(new EmptyBorder(12, 12, 0, 12));
65
        if (activeLibrary != null)
73
        if (activeLibrary != null)
66
            customizer.setSelectedLibrary (activeLibrary.getLibraryImplementation ());
74
            customizer.setSelectedLibrary (activeLibrary.getLibraryImplementation ());
67
        DialogDescriptor descriptor = new DialogDescriptor (customizer,NbBundle.getMessage(LibrariesCustomizer.class,
75
        DialogDescriptor descriptor = new DialogDescriptor (customizer,NbBundle.getMessage(LibrariesCustomizer.class,
68
                "TXT_LibrariesManager"));
76
                "TXT_LibrariesManager"));
69
        Dialog dlg = null;
77
        Dialog dlg = DialogDisplayer.getDefault().createDialog(descriptor);
70
        try {
78
        try {
71
            dlg = DialogDisplayer.getDefault().createDialog (descriptor);
72
            dlg.setVisible(true);
79
            dlg.setVisible(true);
73
            if (descriptor.getValue() == DialogDescriptor.OK_OPTION) {
80
            if (descriptor.getValue() == DialogDescriptor.OK_OPTION) {
74
                return customizer.apply();
81
                return customizer.apply();
82
            } else {
83
                return false;
84
            }
85
        } finally {
86
            dlg.dispose();
87
        }
88
    }
89
90
    /**
91
     * Shows libraries customizer for global libraries.
92
     * @param activeLibrary if not null the activeLibrary is selected in the opened customizer
93
     * @return true if user pressed OK and libraries were sucessfully modified
94
     */
95
    public static boolean showCustomizer (Library activeLibrary) {
96
        return showCustomizer(activeLibrary, LibraryManager.getDefault());
97
    }
98
    
99
    /**
100
     * Show customizer for creating new library in the given library manager.
101
     * @param manager manager
102
     * @return created persisted library or null if user cancelled operation
103
     * @since org.netbeans.modules.project.libraries/1 1.16
104
     */
105
    public static Library showCreateNewLibraryCustomizer(LibraryManager manager) {                                             
106
        if (manager == null) {
107
            manager = LibraryManager.getDefault();
108
        }
109
        LibraryStorageArea area = manager.getArea();
110
        if (area == null) {
111
            area = LibrariesModel.GLOBAL_AREA;
112
        }
113
        org.netbeans.modules.project.libraries.ui.LibrariesCustomizer  customizer =
114
                new org.netbeans.modules.project.libraries.ui.LibrariesCustomizer (area);
115
        NewLibraryPanel p = new NewLibraryPanel(customizer.getModel(), null, area);
116
        DialogDescriptor dd = new DialogDescriptor (p, 
117
                NbBundle.getMessage(LibrariesCustomizer.class,"LibrariesCustomizer.createLibrary.title"),
118
                true, DialogDescriptor.OK_CANCEL_OPTION, null, null);
119
        p.setDialogDescriptor(dd);
120
        Dialog dlg = DialogDisplayer.getDefault().createDialog (dd);
121
        dlg.setVisible(true);
122
        if (dd.getValue() == DialogDescriptor.OK_OPTION) {
123
            LibraryImplementation impl;
124
            if (area != LibrariesModel.GLOBAL_AREA) {
125
                impl = customizer.getModel().createArealLibrary(p.getLibraryType(), p.getLibraryName(), manager.getArea());
126
            } else {
127
                LibraryTypeProvider provider = LibraryTypeRegistry.getDefault().getLibraryTypeProvider(p.getLibraryType());
128
                if (provider == null) {
129
                    return null;
130
                }
131
                impl = provider.createLibrary();
132
                impl.setName(p.getLibraryName());
133
            }
134
            customizer.getModel().addLibrary(impl);
135
            customizer.forceTreeRecreation();
136
            if (customizeLibrary(customizer, impl)) {
137
                return manager.getLibrary(impl.getName());
75
            }
138
            }
76
            else {
139
        }
77
                customizer.cancel();
140
        return null;
141
    }                                            
142
143
    /**
144
     * Show library customizer for the given library.
145
     * @param library library
146
     * @return true if library was modified or not
147
     * @since org.netbeans.modules.project.libraries/1 1.16
148
     */
149
    public static boolean showSingleLibraryCustomizer(Library library) {                                             
150
        org.netbeans.modules.project.libraries.ui.LibrariesCustomizer  customizer =
151
                new org.netbeans.modules.project.libraries.ui.LibrariesCustomizer (library.getManager().getArea());
152
        return customizeLibrary(customizer, library.getLibraryImplementation());
153
    }
154
    
155
    private static boolean customizeLibrary(org.netbeans.modules.project.libraries.ui.LibrariesCustomizer customizer, 
156
            LibraryImplementation activeLibrary) {
157
        customizer.hideLibrariesList();
158
        customizer.setBorder(new EmptyBorder(12, 8, 0, 10));
159
        customizer.setSelectedLibrary (activeLibrary);
160
        DialogDescriptor descriptor = new DialogDescriptor (customizer,NbBundle.getMessage(LibrariesCustomizer.class,
161
                "LibrariesCustomizer.customizeLibrary.title"));
162
        Dialog dlg = DialogDisplayer.getDefault().createDialog(descriptor);
163
        try {
164
            dlg.setVisible(true);
165
            if (descriptor.getValue() == DialogDescriptor.OK_OPTION) {
166
                customizer.apply();
167
                return true;
168
            } else {
169
                return false;
78
            }
170
            }
79
        } finally {
171
        } finally {
80
            if (dlg != null)
172
            dlg.dispose();
81
                dlg.dispose();
82
        }
173
        }
83
        return false;
84
    }
174
    }
175
    
85
}
176
}
86
177
(-)projects/libraries/src/org/netbeans/api/project/libraries/Library.java:1.12 (-12 / +19 lines)
Lines 45-51 Link Here
45
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeEvent;
46
import java.net.URL;
46
import java.net.URL;
47
import java.util.ArrayList;
47
import java.util.ArrayList;
48
import java.util.Iterator;
49
import java.util.List;
48
import java.util.List;
50
import java.util.MissingResourceException;
49
import java.util.MissingResourceException;
51
import java.util.ResourceBundle;
50
import java.util.ResourceBundle;
Lines 76-86 Link Here
76
75
77
    private List<PropertyChangeListener> listeners;
76
    private List<PropertyChangeListener> listeners;
78
77
79
    /**
78
    private final LibraryManager manager;
80
     * Creates new library instance
79
81
     *
80
    Library(LibraryImplementation impl, LibraryManager manager) {
82
     */
83
    private Library (LibraryImplementation impl) {
84
        this.impl = impl;
81
        this.impl = impl;
85
        this.impl.addPropertyChangeListener (new PropertyChangeListener () {
82
        this.impl.addPropertyChangeListener (new PropertyChangeListener () {
86
            public void propertyChange(PropertyChangeEvent evt) {
83
            public void propertyChange(PropertyChangeEvent evt) {
Lines 88-96 Link Here
88
                Library.this.fireChange (propName,evt.getOldValue(),evt.getNewValue());
85
                Library.this.fireChange (propName,evt.getOldValue(),evt.getNewValue());
89
            }
86
            }
90
        });
87
        });
88
        this.manager = manager;
91
    } // end create
89
    } // end create
92
90
93
    /**
91
    /**
92
     * Gets the associated library manager.
93
     * @return the manager (may be the "default" global manager, or a local manager)
94
     * @since org.netbeans.modules.project.libraries/1 1.15
95
     */
96
    public LibraryManager getManager() {
97
        return manager;
98
    }
99
100
    /**
94
     * Access typed but raw library data.
101
     * Access typed but raw library data.
95
     * <p>
102
     * <p>
96
     * The contents are defined by SPI providers and identified
103
     * The contents are defined by SPI providers and identified
Lines 169-179 Link Here
169
        return impl.hashCode();
176
        return impl.hashCode();
170
    }
177
    }
171
    
178
    
172
    @Override
173
    public String toString () {
174
        return this.getName();
175
    }
176
177
    /**
179
    /**
178
     * Adds PropertyChangeListener
180
     * Adds PropertyChangeListener
179
     * @param listener
181
     * @param listener
Lines 235-245 Link Here
235
            return key;
237
            return key;
236
        }
238
        }
237
    }
239
    }
240
241
    @Override
242
    public String toString() {
243
        return "Library[" + getName() + "]"; // NOI18N
244
    }
238
    
245
    
239
    static {
246
    static {
240
        LibraryAccessor.DEFAULT = new LibraryAccessor () {
247
        LibraryAccessor.DEFAULT = new LibraryAccessor () {
241
            public Library createLibrary (LibraryImplementation impl) {
248
            public Library createLibrary (LibraryImplementation impl) {
242
                return new Library (impl);
249
                return new Library(impl, LibraryManager.getDefault());
243
            }
250
            }
244
        };
251
        };
245
    }
252
    }
(-)/dev/null (+135 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.api.project.libraries;
21
22
import java.awt.Component;
23
import java.beans.PropertyChangeListener;
24
import java.io.IOException;
25
import java.util.Set;
26
27
/**
28
 * Visual picker for libraries.
29
 * @since org.netbeans.modules.project.libraries/1 1.16
30
 */
31
public final class LibraryChooser {
32
33
    private LibraryChooser() {
34
    }
35
    
36
    /**
37
     * Create a chooser showing libraries from given library manager and let the
38
     * user to pick some.
39
     * @param manager manager; can be null in which case global libraries are listed
40
     * @param filter optional libraries filter; null for no filtering
41
     * @param handler handler to perform library importing; can be null in which case
42
     *  import will not be allowed in UI
43
     * @return a nonempty set of libraries that were selected, or null if the dialog was cancelled
44
     */
45
    public static Set<Library> showDialog(LibraryManager manager, Filter filter, LibraryImportHandler handler) {
46
        return LibraryChooserGUI.showChooser(manager, filter, handler, true);
47
    }
48
49
    /**
50
     * Create a picker as an embeddable panel.
51
     * Might be used in a wizard, for example.
52
     * @param manager library manager to use or null for global libraries
53
     * @param filter optional libraries filter; null for no filtering
54
     * @return a panel controller
55
     */
56
    public static Panel createPanel(LibraryManager manager, Filter filter) {
57
        return LibraryChooserGUI.createPanel(manager, filter);
58
    }
59
60
    /**
61
     * Filter for use by {@link LibraryChooser#createPanel()} or 
62
     * {@link LibraryChooser#showDialog()}.
63
     */
64
    public interface Filter {
65
66
        /**
67
         * Accepts or rejects a library.
68
         * @param library a library found in one of the managers
69
         * @return true to display, false to hide
70
         */
71
        boolean accept(Library library);
72
73
    }
74
75
    /**
76
     * Represents operations permitted by {@link #createPanel}.
77
     * Not to be implemented by foreign code (methods may be added in the future).
78
     */
79
    public interface Panel {
80
81
        /**
82
         * Produces the actual component you can display.
83
         * @return an embeddable GUI component
84
         */
85
        Component getVisualComponent();
86
87
        /**
88
         * Gets the set of libraries which are currently selected.
89
         * @return a (possibly empty) set of libraries
90
         */
91
        Set<Library> getSelectedLibraries();
92
93
        /**
94
         * Property fired when {@link #getSelectedLibraries} changes.
95
         * Do not expect the old and new values to be non-null.
96
         */
97
        String PROP_SELECTED_LIBRARIES = "selectedLibraries"; // NOI18N
98
99
        /**
100
         * Add a listener for {@link #PROP_SELECTED_LIBRARIES}.
101
         * @param listener the listener to add
102
         */
103
        void addPropertyChangeListener(PropertyChangeListener listener);
104
105
        /**
106
         * Remove a listener.
107
         * @param listener the listener to remove
108
         */
109
        void removePropertyChangeListener(PropertyChangeListener listener);
110
111
    }
112
113
    /**
114
     * Handler for library importing. The handler is used from library chooser
115
     * UI in order to import global library to sharable libraries location. A 
116
     * library is only imported if there is no library with the same library
117
     * name in destination library manager.
118
     */
119
    public interface LibraryImportHandler {
120
        
121
        /**
122
         * Implementation is expected to copy given global library to 
123
         * sharable libraries location, that is to library manager the library
124
         * chooser was created for.
125
         * 
126
         * @param library library to copy
127
         * @return newly created library
128
         * @throws java.io.IOException any IO failure
129
         * @throws IllegalArgumentException if there already exists library 
130
         *  with this name
131
         */
132
        Library importLibrary(Library library) throws IOException;
133
    }
134
    
135
}
(-)/dev/null (+113 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8" ?>
2
3
<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
4
  <AccessibilityProperties>
5
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
6
      <ResourceString bundle="org/netbeans/api/project/libraries/Bundle.properties" key="LibraryChooserGUI.accessibleDescription" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
7
    </Property>
8
  </AccessibilityProperties>
9
  <AuxValues>
10
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
11
    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
12
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
13
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
14
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
15
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
16
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
17
    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
18
  </AuxValues>
19
20
  <Layout>
21
    <DimensionLayout dim="0">
22
      <Group type="103" groupAlignment="0" attributes="0">
23
          <Component id="librariesLabel" min="-2" max="-2" attributes="0"/>
24
          <Group type="102" alignment="1" attributes="0">
25
              <Component id="tree" pref="257" max="32767" attributes="0"/>
26
              <EmptySpace max="-2" attributes="0"/>
27
              <Group type="103" groupAlignment="1" attributes="0">
28
                  <Component id="createButton" min="-2" max="-2" attributes="0"/>
29
                  <Component id="importButton" min="-2" max="-2" attributes="0"/>
30
              </Group>
31
          </Group>
32
          <Group type="102" alignment="0" attributes="0">
33
              <Component id="manageLibrariesButton" min="-2" max="-2" attributes="0"/>
34
              <EmptySpace max="-2" attributes="0"/>
35
          </Group>
36
      </Group>
37
    </DimensionLayout>
38
    <DimensionLayout dim="1">
39
      <Group type="103" groupAlignment="0" attributes="0">
40
          <Group type="102" alignment="0" attributes="0">
41
              <Component id="librariesLabel" min="-2" max="-2" attributes="0"/>
42
              <EmptySpace min="-2" max="-2" attributes="0"/>
43
              <Group type="103" groupAlignment="0" attributes="0">
44
                  <Group type="102" attributes="0">
45
                      <Component id="createButton" min="-2" max="-2" attributes="0"/>
46
                      <EmptySpace max="-2" attributes="0"/>
47
                      <Component id="importButton" min="-2" max="-2" attributes="0"/>
48
                  </Group>
49
                  <Component id="tree" pref="284" max="32767" attributes="0"/>
50
              </Group>
51
              <EmptySpace max="-2" attributes="0"/>
52
              <Component id="manageLibrariesButton" min="-2" max="-2" attributes="0"/>
53
          </Group>
54
      </Group>
55
    </DimensionLayout>
56
  </Layout>
57
  <SubComponents>
58
    <Component class="javax.swing.JLabel" name="librariesLabel">
59
      <Properties>
60
        <Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
61
          <ComponentRef name="tree"/>
62
        </Property>
63
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
64
          <ResourceString bundle="org/netbeans/api/project/libraries/Bundle.properties" key="LibraryChooserGUI.librariesLabel" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
65
        </Property>
66
      </Properties>
67
      <AuxValues>
68
        <AuxValue name="generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
69
      </AuxValues>
70
    </Component>
71
    <Component class="org.openide.explorer.view.BeanTreeView" name="tree">
72
      <Properties>
73
        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
74
          <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
75
            <EtchetBorder/>
76
          </Border>
77
        </Property>
78
        <Property name="popupAllowed" type="boolean" value="false"/>
79
        <Property name="rootVisible" type="boolean" value="false"/>
80
      </Properties>
81
    </Component>
82
    <Component class="javax.swing.JButton" name="createButton">
83
      <Properties>
84
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
85
          <ResourceString bundle="org/netbeans/api/project/libraries/Bundle.properties" key="LibraryChooserGUI.createButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
86
        </Property>
87
      </Properties>
88
      <Events>
89
        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createButtonActionPerformed"/>
90
      </Events>
91
    </Component>
92
    <Component class="javax.swing.JButton" name="importButton">
93
      <Properties>
94
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
95
          <ResourceString bundle="org/netbeans/api/project/libraries/Bundle.properties" key="LibraryChooserGUI.importButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
96
        </Property>
97
      </Properties>
98
      <Events>
99
        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="importButtonActionPerformed"/>
100
      </Events>
101
    </Component>
102
    <Component class="javax.swing.JButton" name="manageLibrariesButton">
103
      <Properties>
104
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
105
          <ResourceString bundle="org/netbeans/api/project/libraries/Bundle.properties" key="LibraryChooserGUI.manageLibrariesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
106
        </Property>
107
      </Properties>
108
      <Events>
109
        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="manageLibrariesButtonActionPerformed"/>
110
      </Events>
111
    </Component>
112
  </SubComponents>
113
</Form>
(-)/dev/null (+382 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.api.project.libraries;
21
22
import java.awt.BorderLayout;
23
import java.awt.Component;
24
import java.awt.Image;
25
import java.beans.PropertyChangeEvent;
26
import java.beans.PropertyChangeListener;
27
import java.beans.PropertyVetoException;
28
import java.io.IOException;
29
import java.text.Collator;
30
import java.util.ArrayList;
31
import java.util.Collection;
32
import java.util.Collections;
33
import java.util.Comparator;
34
import java.util.HashSet;
35
import java.util.List;
36
import java.util.Set;
37
import javax.swing.JButton;
38
import javax.swing.JPanel;
39
import javax.swing.border.EmptyBorder;
40
import org.openide.DialogDescriptor;
41
import org.openide.DialogDisplayer;
42
import org.openide.NotifyDescriptor;
43
import org.openide.explorer.ExplorerManager;
44
import org.openide.filesystems.Repository;
45
import org.openide.loaders.DataFolder;
46
import org.openide.nodes.AbstractNode;
47
import org.openide.nodes.Children;
48
import org.openide.nodes.Node;
49
import org.openide.nodes.NodeNotFoundException;
50
import org.openide.nodes.NodeOp;
51
import org.openide.util.Exceptions;
52
import org.openide.util.HelpCtx;
53
import org.openide.util.NbBundle;
54
import org.openide.util.lookup.Lookups;
55
56
class LibraryChooserGUI extends JPanel implements ExplorerManager.Provider, HelpCtx.Provider, LibraryChooser.Panel {
57
58
    private final LibraryManager manager;
59
    private final LibraryChooser.Filter filter;
60
    private final ExplorerManager explorer;
61
    private LibraryChooser.LibraryImportHandler importHandler;
62
63
    private LibraryChooserGUI(LibraryManager manager, LibraryChooser.Filter filter, 
64
            LibraryChooser.LibraryImportHandler importHandler) {
65
        if (manager == null) {
66
            manager = LibraryManager.getDefault();
67
        }
68
        this.manager = manager;
69
        this.filter = filter;
70
        this.importHandler = importHandler;
71
        explorer = new ExplorerManager();
72
        initComponents();
73
        tree.setDefaultActionAllowed(false);
74
    }
75
    
76
    public static LibraryChooser.Panel createPanel(LibraryManager manager, 
77
            LibraryChooser.Filter filter) {
78
        LibraryChooserGUI l = new LibraryChooserGUI(manager, filter, null);
79
        l.configureForEmbedded();
80
        return l;
81
    }
82
83
    public static Set<Library> showChooser(LibraryManager manager, LibraryChooser.Filter filter, 
84
            LibraryChooser.LibraryImportHandler handler, boolean addOperation) {
85
        LibraryChooserGUI l = new LibraryChooserGUI(manager, filter, handler);
86
        return l.showDialog(addOperation);
87
    }
88
89
    private Set<Library> showDialog(boolean addOperatation) {
90
        // show manage button only in embedded panel:
91
        manageLibrariesButton.setVisible(false);
92
        // import enabled only for non-global library manager
93
        importButton.setVisible(manager.getLocation() != null && importHandler != null);
94
        JPanel inset = new JPanel(new BorderLayout());
95
        inset.setBorder(new EmptyBorder(12,12,0,12));
96
        inset.add(this);
97
        String title;
98
        String buttonLabel;
99
        if (addOperatation) {
100
            title = NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.add.title");
101
            buttonLabel = NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.add.button");
102
        } else {
103
            title = NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.import.title");
104
            buttonLabel = NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.import.button");
105
            createButton.setVisible(false);
106
        }
107
        DialogDescriptor dd = new DialogDescriptor(inset, title);
108
        dd.setModal(true);
109
        final JButton add = new JButton(buttonLabel);
110
        add.setEnabled(false);
111
        add.setDefaultCapable(true);
112
        explorer.addPropertyChangeListener(new PropertyChangeListener() {
113
           public void propertyChange(PropertyChangeEvent evt) {
114
               add.setEnabled(!getSelectedLibraries().isEmpty());
115
           }
116
        });
117
        dd.setOptions(new Object[] {add, NotifyDescriptor.CANCEL_OPTION});
118
        dd.setClosingOptions(new Object[] {add, NotifyDescriptor.CANCEL_OPTION});
119
        if (DialogDisplayer.getDefault().notify(dd) == add) {
120
            Set<Library> selection = getSelectedLibraries();
121
            assert !selection.isEmpty();
122
            return selection;
123
        } else {
124
            return null;
125
        }
126
    }
127
128
    private void configureForEmbedded() {
129
        explorer.addPropertyChangeListener(new PropertyChangeListener() {
130
           public void propertyChange(PropertyChangeEvent evt) {
131
               firePropertyChange(PROP_SELECTED_LIBRARIES, null, null);
132
           }
133
        });
134
        createButton.setVisible(false);
135
        importButton.setVisible(false);
136
    }
137
138
    public Set<Library> getSelectedLibraries() {
139
        Set<Library> s = new HashSet<Library>();
140
        for (Node n : explorer.getSelectedNodes()) {
141
            Library l = n.getLookup().lookup(Library.class);
142
            if (l != null) {
143
                s.add(l);
144
            } else {
145
                return Collections.emptySet();
146
            }
147
        }
148
        return s;
149
    }
150
151
    public Component getVisualComponent() {
152
        return this;
153
    }
154
155
    public ExplorerManager getExplorerManager() {
156
        return explorer;
157
    }
158
159
    public HelpCtx getHelpCtx() {
160
        return new HelpCtx(LibraryChooserGUI.class);
161
    }
162
163
    private void setRootNode() {
164
        explorer.setRootContext(new AbstractNode(new LibraryManagerChildren()));
165
        tree.expandAll();
166
        try {
167
            if (explorer.getRootContext().getChildren().getNodes(true).length > 0) {
168
                explorer.setSelectedNodes(new Node[] {explorer.getRootContext().getChildren().getNodes(true)[0]});
169
            }
170
        } catch (PropertyVetoException x) {
171
            Exceptions.printStackTrace(x);
172
        }
173
        /* XXX Nothing seems to work to scroll to top; how is it done?
174
        tree.getViewport().setViewPosition(new Point());
175
        tree.getViewport().scrollRectToVisible(new Rectangle(0, 0, 1, 1));
176
         */
177
        tree.requestFocus();
178
    }
179
180
    @Override
181
    public void addNotify() {
182
        super.addNotify();
183
        setRootNode();
184
    }
185
186
    private class LibraryManagerChildren extends Children.Keys<LibraryManager> {
187
188
        @Override
189
        protected void addNotify() {
190
            super.addNotify();
191
            if (manager != null) {
192
                setKeys(Collections.singleton(manager));
193
            }
194
        }
195
196
        protected Node[] createNodes(LibraryManager mgr) {
197
            List<Library> libs = new ArrayList<Library>();
198
            for (Library lib : mgr.getLibraries()) {
199
                if (filter == null || filter.accept(lib)) {
200
                    libs.add(lib);
201
                }
202
            }
203
            if (libs.isEmpty()) {
204
                return new Node[0];
205
            } else {
206
                Collections.sort(libs,new Comparator<Library>() {
207
                    Collator COLL = Collator.getInstance();
208
                    public int compare(Library lib1, Library lib2) {
209
                        return COLL.compare(lib1.getDisplayName(), lib2.getDisplayName());
210
                    }
211
                });
212
                Node n = new AbstractNode(new LibraryChildren(libs)) {
213
                    Node iconDelegate = DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot()).getNodeDelegate();
214
                    public Image getIcon(int type) {
215
                        return iconDelegate.getIcon(type);
216
                    }
217
                    public Image getOpenedIcon(int type) {
218
                        return iconDelegate.getOpenedIcon(type);
219
                    }
220
                };
221
                n.setName(mgr.getDisplayName());
222
                n.setDisplayName(mgr.getDisplayName());
223
                return new Node[] {n};
224
            }
225
        }
226
227
    }
228
229
    private class LibraryChildren extends Children.Keys<Library> {
230
231
        LibraryChildren(List<Library> libs) {
232
            setKeys(libs);
233
        }
234
235
        protected Node[] createNodes(Library lib) {
236
            AbstractNode n = new AbstractNode(Children.LEAF, Lookups.singleton(lib));
237
            n.setName(lib.getName());
238
            n.setDisplayName(lib.getDisplayName());
239
            n.setShortDescription(lib.getDescription());
240
            n.setIconBaseWithExtension("org/netbeans/modules/project/libraries/resources/libraries.gif"); // NOI18N
241
            return new Node[] {n};
242
        }
243
244
    }
245
246
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
247
    private void initComponents() {
248
249
        librariesLabel = new javax.swing.JLabel();
250
        tree = new org.openide.explorer.view.BeanTreeView();
251
        createButton = new javax.swing.JButton();
252
        importButton = new javax.swing.JButton();
253
        manageLibrariesButton = new javax.swing.JButton();
254
255
        librariesLabel.setLabelFor(tree);
256
        org.openide.awt.Mnemonics.setLocalizedText(librariesLabel, org.openide.util.NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.librariesLabel")); // NOI18N
257
258
        tree.setBorder(javax.swing.BorderFactory.createEtchedBorder());
259
        tree.setPopupAllowed(false);
260
        tree.setRootVisible(false);
261
262
        createButton.setText(org.openide.util.NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.createButton.text")); // NOI18N
263
        createButton.addActionListener(new java.awt.event.ActionListener() {
264
            public void actionPerformed(java.awt.event.ActionEvent evt) {
265
                createButtonActionPerformed(evt);
266
            }
267
        });
268
269
        importButton.setText(org.openide.util.NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.importButton.text")); // NOI18N
270
        importButton.addActionListener(new java.awt.event.ActionListener() {
271
            public void actionPerformed(java.awt.event.ActionEvent evt) {
272
                importButtonActionPerformed(evt);
273
            }
274
        });
275
276
        manageLibrariesButton.setText(org.openide.util.NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.manageLibrariesButton.text")); // NOI18N
277
        manageLibrariesButton.addActionListener(new java.awt.event.ActionListener() {
278
            public void actionPerformed(java.awt.event.ActionEvent evt) {
279
                manageLibrariesButtonActionPerformed(evt);
280
            }
281
        });
282
283
        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
284
        this.setLayout(layout);
285
        layout.setHorizontalGroup(
286
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
287
            .add(librariesLabel)
288
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
289
                .add(tree, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 257, Short.MAX_VALUE)
290
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
291
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
292
                    .add(createButton)
293
                    .add(importButton)))
294
            .add(layout.createSequentialGroup()
295
                .add(manageLibrariesButton)
296
                .addContainerGap())
297
        );
298
        layout.setVerticalGroup(
299
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
300
            .add(layout.createSequentialGroup()
301
                .add(librariesLabel)
302
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
303
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
304
                    .add(layout.createSequentialGroup()
305
                        .add(createButton)
306
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
307
                        .add(importButton))
308
                    .add(tree, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE))
309
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
310
                .add(manageLibrariesButton))
311
        );
312
313
        getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(LibraryChooserGUI.class, "LibraryChooserGUI.accessibleDescription")); // NOI18N
314
    }// </editor-fold>//GEN-END:initComponents
315
316
    private void manageLibrariesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageLibrariesButtonActionPerformed
317
        if (LibrariesCustomizer.showCustomizer(null, manager)) {
318
            setRootNode();
319
        }
320
    }//GEN-LAST:event_manageLibrariesButtonActionPerformed
321
322
    private void createButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createButtonActionPerformed
323
        Library l = LibrariesCustomizer.showCreateNewLibraryCustomizer(manager);
324
        if (l != null) {
325
            setRootNode();
326
            selectLibrary(Collections.singleton(l));
327
        }
328
    }//GEN-LAST:event_createButtonActionPerformed
329
330
    private void selectLibrary(Collection<Library> libraries) {
331
        Node root = explorer.getRootContext();
332
        List<Node> selection = new ArrayList<Node>();
333
        for (Library lib : libraries) {
334
            String[] path = {lib.getManager().getDisplayName(), lib.getName()};
335
            try {
336
                Node node = NodeOp.findPath(root, path);
337
                if (node != null) {
338
                    selection.add(node);
339
                }
340
            } catch (NodeNotFoundException e) {
341
                //Ignore it
342
            }
343
        }
344
        try {
345
            explorer.setSelectedNodes(selection.toArray(new Node[selection.size()]));
346
        } catch (PropertyVetoException e) {
347
            //Ignore it
348
        }
349
    }
350
    
351
    private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importButtonActionPerformed
352
        Set<Library> libs = showChooser(LibraryManager.getDefault(), 
353
                new IgnoreAlreadyImportedLibrariesFilter(), null, false);
354
        if (libs != null) {
355
            Set<Library> importedLibs = new HashSet<Library>();
356
            try {
357
                for (Library lib : libs) {
358
                    importedLibs.add(importHandler.importLibrary(lib));
359
                }
360
            } catch (IOException ex) {
361
                Exceptions.printStackTrace(ex);
362
            }
363
            setRootNode();        
364
            selectLibrary(importedLibs);
365
        }
366
    }//GEN-LAST:event_importButtonActionPerformed
367
368
    private class IgnoreAlreadyImportedLibrariesFilter implements LibraryChooser.Filter {
369
        public boolean accept(Library library) {
370
            return manager.getLibrary(library.getName()) == null;
371
        }
372
    }
373
374
    // Variables declaration - do not modify//GEN-BEGIN:variables
375
    private javax.swing.JButton createButton;
376
    private javax.swing.JButton importButton;
377
    private javax.swing.JLabel librariesLabel;
378
    private javax.swing.JButton manageLibrariesButton;
379
    private org.openide.explorer.view.BeanTreeView tree;
380
    // End of variables declaration//GEN-END:variables
381
382
}
(-)projects/libraries/src/org/netbeans/api/project/libraries/LibraryManager.java:1.9 (-55 / +262 lines)
Lines 41-64 Link Here
41
41
42
package org.netbeans.api.project.libraries;
42
package org.netbeans.api.project.libraries;
43
43
44
45
import org.netbeans.api.project.libraries.Library;
46
import org.netbeans.spi.project.libraries.LibraryImplementation;
47
import org.netbeans.spi.project.libraries.LibraryProvider;
48
import org.openide.util.Lookup;
49
import org.openide.util.LookupListener;
50
import org.openide.util.LookupEvent;
51
52
import java.beans.PropertyChangeSupport;
44
import java.beans.PropertyChangeSupport;
53
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeListener;
54
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeEvent;
55
import java.io.IOException;
47
import java.io.IOException;
56
import java.util.*;
48
import java.net.URL;
49
import java.util.ArrayList;
50
import java.util.Collection;
51
import java.util.HashSet;
52
import java.util.List;
53
import java.util.Map;
54
import java.util.Set;
55
import org.netbeans.modules.project.libraries.LibraryAccessor;
57
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
56
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
58
import org.netbeans.spi.project.libraries.LibraryFactory;
57
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
58
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
59
import org.netbeans.spi.project.libraries.LibraryImplementation;
60
import org.netbeans.spi.project.libraries.LibraryProvider;
61
import org.netbeans.spi.project.libraries.LibraryStorageArea;
62
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
59
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
63
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
60
64
import org.openide.util.Lookup;
61
// XXX make getLibraries return Set not array
65
import org.openide.util.LookupListener;
66
import org.openide.util.LookupEvent;
62
67
63
/**
68
/**
64
 * LibraryManager provides registry of the installed libraries.
69
 * LibraryManager provides registry of the installed libraries.
Lines 67-85 Link Here
67
 */
72
 */
68
public final class LibraryManager {
73
public final class LibraryManager {
69
74
75
    /**
76
     * Property fired when the set of libraries changes.
77
     */
70
    public static final String PROP_LIBRARIES = "libraries"; //NOI18N
78
    public static final String PROP_LIBRARIES = "libraries"; //NOI18N
71
79
72
    private static LibraryManager instance;
80
    private static LibraryManager instance;
73
81
74
    private Lookup.Result<LibraryProvider> result;
82
    private Lookup.Result<LibraryProvider> result;
75
    private Collection<LibraryProvider> currentStorages = new ArrayList<LibraryProvider>();
83
    private final Collection<LibraryProvider> currentStorages = new ArrayList<LibraryProvider>();
76
    private PropertyChangeListener plistener;
84
    private final PropertyChangeListener plistener = new PropertyChangeListener() {
77
    private PropertyChangeSupport listeners;
85
        public void propertyChange(PropertyChangeEvent evt) {
78
    private Collection<Library> cache;
86
            if (LibraryProvider.PROP_LIBRARIES.equals(evt.getPropertyName())) {
87
                resetCache();
88
            }
89
        }
90
    };
91
    private final PropertyChangeSupport listeners = new PropertyChangeSupport(this);
92
    private static final PropertyChangeSupport openLibraryManagerListListeners = 
93
            new PropertyChangeSupport(LibraryManager.class);
94
    private static final PropertyChangeListener AREAL_LIBRARY_PROVIDER_LISTENER = new PropertyChangeListener() {
95
            public void propertyChange(PropertyChangeEvent evt) {
96
                openLibraryManagerListListeners.firePropertyChange(PROP_OPEN_LIBRARY_MANAGERS, null, null);
97
            }
98
        };
99
        
100
    /** Property fired when list of open library managers changes. */
101
    public static final String PROP_OPEN_LIBRARY_MANAGERS = "openManagers"; // NOI18N
102
    private static Lookup.Result<ArealLibraryProvider> areaProvidersLookupResult = null;
103
    private static Collection<? extends ArealLibraryProvider> currentAreaProviders = new ArrayList<ArealLibraryProvider>();
79
104
105
    private Collection<Library> cache;
106
    /** null for default manager */
107
    private final ArealLibraryProvider alp;
108
    /** null for default manager */
109
    private final LibraryStorageArea area;
80
110
81
    private LibraryManager () {
111
    private LibraryManager () {
82
        this.listeners = new PropertyChangeSupport(this);
112
        alp = null;
113
        area = null;
114
    }
115
116
    private LibraryManager(ArealLibraryProvider alp, LibraryStorageArea area) {
117
        this.alp = alp;
118
        this.area = area;
119
        LibraryProvider lp = LibraryAccessor.getLibraries(alp, area);
120
        lp.addPropertyChangeListener(plistener);
121
        currentStorages.add(lp);
122
    }
123
124
    /**
125
     * Gets a human-readable description of this manager.
126
     * This may be used to visually differentiate the global manager from various local managers.
127
     * @return a localized display name
128
     * @see LibraryStorageArea#getDisplayName
129
     * @since org.netbeans.modules.project.libraries/1 1.15
130
     */
131
    public String getDisplayName() {
132
        if (area == null) {
133
            return LibrariesModel.GLOBAL_AREA.getDisplayName();
134
        } else {
135
            return area.getDisplayName();
136
        }
137
    }
138
139
    /**
140
     * Gets the location associated with this manager.
141
     * @return a location where library definitions are kept, or null in the case of {@link #getDefault}
142
     * @see LibraryStorageArea#getLocation
143
     * @see #forLocation
144
     * @since org.netbeans.modules.project.libraries/1 1.15
145
     */
146
    public URL getLocation() {
147
        return area != null ? area.getLocation() : null;
83
    }
148
    }
84
149
85
    /**
150
    /**
Lines 99-142 Link Here
99
    }
164
    }
100
165
101
    /**
166
    /**
102
     * List all library defined in the IDE.
167
     * Lists all libraries defined in this manager.
103
     *
168
     * @return library definitions (never <code>null</code>)
104
     * @return Library[] library definitions never <code>null</code>
105
     */
169
     */
106
    public synchronized Library[] getLibraries() {
170
    public synchronized Library[] getLibraries() {
107
        if (this.cache == null) {
171
        if (this.cache == null) {
108
            if (this.result == null) {
172
            List<Library> l = new ArrayList<Library>();
109
                plistener = new PropertyChangeListener() {
173
            if (area == null) {
110
                    public void propertyChange(PropertyChangeEvent evt) {
174
                if (result == null) {
111
                        resetCache ();
175
                    result = Lookup.getDefault().lookupResult(LibraryProvider.class);
112
                    }
176
                    result.addLookupListener(new LookupListener() {
113
                };
177
                        public void resultChanged(LookupEvent ev) {
114
                result = Lookup.getDefault().lookupResult(LibraryProvider.class);
178
                            resetCache();
115
                result.addLookupListener (new LookupListener() {
179
                        }
116
                    public void resultChanged(LookupEvent ev) {
180
                    });
117
                            resetCache ();
181
                }
182
                Collection<? extends LibraryProvider> instances = result.allInstances();
183
                Collection<LibraryProvider> added = new HashSet<LibraryProvider>(instances);
184
                added.removeAll(currentStorages);
185
                Collection<LibraryProvider> removed = new HashSet<LibraryProvider>(currentStorages);
186
                removed.removeAll(instances);
187
                currentStorages.clear();
188
                for (LibraryProvider storage : instances) {
189
                    this.currentStorages.add(storage);
190
                    for (LibraryImplementation impl : storage.getLibraries()) {
191
                        l.add(new Library(impl, this));
118
                    }
192
                    }
119
                });
193
                }
194
                for (LibraryProvider p : removed) {
195
                    p.removePropertyChangeListener(this.plistener);
196
                }
197
                for (LibraryProvider p : added) {
198
                    p.addPropertyChangeListener(this.plistener);
199
                }
200
            } else {
201
                for (LibraryImplementation impl : currentStorages.iterator().next().getLibraries()) {
202
                    l.add(new Library(impl, this));
203
                }
120
            }
204
            }
121
            List<Library> l = new ArrayList<Library>();
122
            Collection<? extends LibraryProvider> instances = result.allInstances();
123
            Collection<LibraryProvider> added = new HashSet<LibraryProvider>(instances);
124
            added.removeAll (currentStorages);
125
            Collection<LibraryProvider> removed = new HashSet<LibraryProvider>(currentStorages);
126
            removed.removeAll (instances);
127
            currentStorages.clear();
128
            for (LibraryProvider storage : instances) {
129
                this.currentStorages.add (storage);
130
                for (LibraryImplementation impl : storage.getLibraries()) {
131
                    l.add(LibraryFactory.createLibrary(impl));
132
                }
133
            }
134
            for (LibraryProvider p : removed) {
135
                p.removePropertyChangeListener(this.plistener);
136
            }
137
            for (LibraryProvider p : added) {
138
                p.addPropertyChangeListener(this.plistener);
139
            }            
140
            this.cache = l;
205
            this.cache = l;
141
        }
206
        }
142
        return this.cache.toArray(new Library[this.cache.size()]);
207
        return this.cache.toArray(new Library[this.cache.size()]);
Lines 160-168 Link Here
160
     * @throws IOException when the library cannot be stored
225
     * @throws IOException when the library cannot be stored
161
     * @throws IllegalArgumentException if the library is not recognized by any 
226
     * @throws IllegalArgumentException if the library is not recognized by any 
162
     * {@link org.netbeans.spi.project.libraries.LibraryTypeProvider} or the library
227
     * {@link org.netbeans.spi.project.libraries.LibraryTypeProvider} or the library
163
     * of the same name already exists.
228
     * of the same name already exists, or if this manager is not {@link #getDefault}.
164
     * @since org.netbeans.modules.project.libraries/1 1.14
229
     * @since org.netbeans.modules.project.libraries/1 1.14
230
     * @deprecated Use {@link #createLibrary} instead, as this properly supports local managers.
165
     */
231
     */
232
    @Deprecated
166
    public void addLibrary (final Library library) throws IOException, IllegalArgumentException {
233
    public void addLibrary (final Library library) throws IOException, IllegalArgumentException {
167
        assert library != null;
234
        assert library != null;
168
        if (LibrariesSupport.getLibraryTypeProvider(library.getType()) == null) {
235
        if (LibrariesSupport.getLibraryTypeProvider(library.getType()) == null) {
Lines 176-182 Link Here
176
        assert providers.size() == 1;        
243
        assert providers.size() == 1;        
177
        providers.iterator().next().addLibrary(library.getLibraryImplementation());
244
        providers.iterator().next().addLibrary(library.getLibraryImplementation());
178
    }
245
    }
179
    
246
247
    /**
248
     * Creates a new library definition and adds it to the list.
249
     * @param type the type of library, as in {@link LibraryTypeProvider#getLibraryType} or {@link LibraryImplementation#getType}
250
     * @param name the identifying name of the new library (must not duplicate a name already in use by a library in this manager)
251
     * @param contents the initial contents of the library's volumes, as a map from volume type to volume content
252
     * @return a newly created library
253
     * @throws IOException if the new definition could not be stored
254
     * @throws IllegalArgumentException if the library type or one of the content volume types is not supported,
255
     *                                  or if a library of the same name already exists in this manager
256
     * @see ArealLibraryProvider#createLibrary
257
     * @since org.netbeans.modules.project.libraries/1 1.15
258
     */
259
    public Library createLibrary(String type, String name, Map<String,List<URL>> contents) throws IOException {
260
        if (getLibrary(name) != null) {
261
            throw new IllegalArgumentException("Name already in use: " + name); // NOI18N
262
        }
263
        LibraryImplementation impl;
264
        if (area == null) {
265
            LibraryTypeProvider ltp = LibrariesSupport.getLibraryTypeProvider(type);
266
            if (ltp == null) {
267
                throw new IllegalArgumentException("Trying to add a library of unknown type: " + type); // NOI18N
268
            }
269
            impl = ltp.createLibrary();
270
            impl.setName(name);
271
            for (Map.Entry<String,List<URL>> entry : contents.entrySet()) {
272
                impl.setContent(entry.getKey(), entry.getValue());
273
            }
274
            Lookup.getDefault().lookup(WritableLibraryProvider.class).addLibrary(impl);
275
        } else {
276
            impl = LibraryAccessor.createLibrary(alp, type, name, area, contents);
277
        }
278
        return new Library(impl, this);
279
    }
280
180
    /**
281
    /**
181
     * Removes installed library 
282
     * Removes installed library 
182
     * @param library to be removed. 
283
     * @param library to be removed. 
Lines 187-195 Link Here
187
     */
288
     */
188
    public void removeLibrary (final Library library) throws IOException, IllegalArgumentException {
289
    public void removeLibrary (final Library library) throws IOException, IllegalArgumentException {
189
        assert library != null;
290
        assert library != null;
190
        final Collection<? extends WritableLibraryProvider> providers = Lookup.getDefault().lookupAll(WritableLibraryProvider.class);
291
        if (area == null) {
191
        assert providers.size() == 1;
292
            final Collection<? extends WritableLibraryProvider> providers = Lookup.getDefault().lookupAll(WritableLibraryProvider.class);
192
        providers.iterator().next().removeLibrary(library.getLibraryImplementation());
293
            assert providers.size() == 1;
294
            providers.iterator().next().removeLibrary(library.getLibraryImplementation());
295
        } else {
296
            LibraryAccessor.remove(alp, library.getLibraryImplementation());
297
        }
193
    }
298
    }
194
299
195
    /**
300
    /**
Lines 229-235 Link Here
229
        return instance;
334
        return instance;
230
    }
335
    }
231
336
337
    /**
338
     * Gets a library manager which loads library definitions from a particular location.
339
     * There is no guarantee that the return value is the same object from call to call with the same location.
340
     * @param location any storage location supported by an installed provider
341
     * @return a library manager whose {@link #getLocation} matches the supplied location
342
     * @throws IllegalArgumentException if no installed provider is able to manage locations of this kind
343
     * @see ArealLibraryProvider#loadArea
344
     * @see ArealLibraryProvider#getLibraries
345
     * @since org.netbeans.modules.project.libraries/1 1.15
346
     */
347
    public static LibraryManager forLocation(URL location) throws IllegalArgumentException {
348
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
349
            LibraryStorageArea area = alp.loadArea(location);
350
            if (area != null) {
351
                return new LibraryManager(alp, area);
352
            }
353
        }
354
        throw new IllegalArgumentException(location.toExternalForm());
355
    }
356
357
    /**
358
     * Gets an unspecified collection of managers which are somehow to be represented as open.
359
     * For example, library storages referred to from open projects might be returned.
360
     * You can listen on changes in list of open managers via {@link #addOpenManagersPropertyChangeListener}.
361
     * There is no guarantee that the non-default managers are the same objects from call to call
362
     * even if the locations remain the same.
363
     * @see ArealLibraryProvider#getOpenAreas
364
     * @return a set of managers, always including at least {@link #getDefault}
365
     * @since org.netbeans.modules.project.libraries/1 1.15
366
     */
367
    public static Collection<LibraryManager> getOpenManagers() {
368
        List<LibraryManager> managers = new ArrayList<LibraryManager>();
369
        managers.add(getDefault());
370
        Set<URL> locations = new HashSet<URL>();
371
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
372
            for (LibraryStorageArea area : LibraryAccessor.getOpenAreas(alp)) {
373
                if (locations.add(area.getLocation())) {
374
                    managers.add(new LibraryManager(alp, area));
375
                }
376
            }
377
        }
378
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
379
            for (URL location : LibrariesModel.createdAreas) {
380
                LibraryStorageArea area = alp.loadArea(location);
381
                if (area != null) {
382
                    assert area.getLocation().equals(location) : "Bad location " + area.getLocation() + " does not match " + location + " from " + alp.getClass().getName();
383
                    if (locations.add(location)) {
384
                        managers.add(new LibraryManager(alp, area));
385
                    }
386
                }
387
            }
388
        }
389
        return managers;
390
    }
391
392
    /**
393
     * Adds PropertyChangeListener on list of open library managers.
394
     * The listener is notified when list of open library managers changes via
395
     * {@link #PROP_OPEN_LIBRARY_MANAGERS}.
396
     * @param listener to be notified
397
     */
398
    public static synchronized void addOpenManagersPropertyChangeListener (PropertyChangeListener listener) {
399
        assert listener != null;
400
        if (areaProvidersLookupResult == null) {
401
            areaProvidersLookupResult = Lookup.getDefault().lookupResult(ArealLibraryProvider.class);
402
            attachListeners(areaProvidersLookupResult.allInstances());
403
            areaProvidersLookupResult.addLookupListener(new LookupListener() {
404
                public void resultChanged(LookupEvent ev) {
405
                    attachListeners(areaProvidersLookupResult.allInstances());
406
                }
407
            });
408
        }
409
        openLibraryManagerListListeners.addPropertyChangeListener (listener);
410
    }
411
    
412
    private static synchronized void attachListeners(Collection<? extends ArealLibraryProvider> currentProviders) {
413
        for (ArealLibraryProvider provider : currentAreaProviders) {
414
            provider.removePropertyChangeListener(AREAL_LIBRARY_PROVIDER_LISTENER);
415
        }
416
        for (ArealLibraryProvider provider : currentProviders) {
417
            provider.addPropertyChangeListener(AREAL_LIBRARY_PROVIDER_LISTENER);
418
        }
419
        currentAreaProviders = currentProviders;
420
    }
421
422
    /**
423
     * Removes PropertyChangeListener
424
     * @param listener
425
     */
426
    public static void removeOpenManagersPropertyChangeListener (PropertyChangeListener listener) {
427
        assert listener != null;
428
        openLibraryManagerListListeners.removePropertyChangeListener (listener);
429
    }
430
    
431
    @Override
432
    public String toString() {
433
        URL loc = getLocation();
434
        return "LibraryManager[" + (loc != null ? loc : "default") + "]"; // NOI18N
435
    }
232
436
437
    LibraryStorageArea getArea() {
438
        return area;
439
    }
233
440
234
} // end LibraryManager
441
} // end LibraryManager
235
442
(-)projects/libraries/src/org/netbeans/modules/project/libraries/DefaultLibraryImplementation.java:1.8 (-2 / +2 lines)
Lines 139-146 Link Here
139
        this.listeners.remove (l);
139
        this.listeners.remove (l);
140
    }
140
    }
141
141
142
    public String toString () {
142
    public @Override String toString() {
143
        return "LibraryImplementation[Name="+this.name+"]"; //NOI18N
143
        return "DefaultLibraryImplementation[" + name + "]"; // NOI18N
144
    }
144
    }
145
145
146
    private void firePropertyChange (String propName, Object oldValue, Object newValue) {
146
    private void firePropertyChange (String propName, Object oldValue, Object newValue) {
(-)projects/libraries/src/org/netbeans/modules/project/libraries/LibrariesStorage.java:1.26 (-1 / +1 lines)
Lines 76-82 Link Here
76
import org.xml.sax.InputSource;
76
import org.xml.sax.InputSource;
77
import org.xml.sax.SAXException;
77
import org.xml.sax.SAXException;
78
78
79
public class LibrariesStorage extends FileChangeAdapter implements WritableLibraryProvider {
79
public class LibrariesStorage extends FileChangeAdapter implements WritableLibraryProvider<LibraryImplementation> {
80
80
81
    private static final String NB_HOME_PROPERTY = "netbeans.home";  //NOI18N
81
    private static final String NB_HOME_PROPERTY = "netbeans.home";  //NOI18N
82
    private static final String LIBRARIES_REPOSITORY = "org-netbeans-api-project-libraries/Libraries";  //NOI18N
82
    private static final String LIBRARIES_REPOSITORY = "org-netbeans-api-project-libraries/Libraries";  //NOI18N
(-)projects/libraries/src/org/netbeans/modules/project/libraries/LibraryAccessor.java:1.2 (-5 / +51 lines)
Lines 41-54 Link Here
41
41
42
package org.netbeans.modules.project.libraries;
42
package org.netbeans.modules.project.libraries;
43
43
44
import java.io.IOException;
45
import java.net.URL;
46
import java.util.List;
47
import java.util.Map;
48
import java.util.Set;
44
import org.netbeans.api.project.libraries.Library;
49
import org.netbeans.api.project.libraries.Library;
50
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
45
import org.netbeans.spi.project.libraries.LibraryImplementation;
51
import org.netbeans.spi.project.libraries.LibraryImplementation;
52
import org.netbeans.spi.project.libraries.LibraryProvider;
53
import org.netbeans.spi.project.libraries.LibraryStorageArea;
46
import org.openide.util.Exceptions;
54
import org.openide.util.Exceptions;
47
55
48
/**
49
 *
50
 * @author Tomas Zezula
51
 */
52
public abstract class LibraryAccessor {
56
public abstract class LibraryAccessor {
53
    
57
    
54
    public static LibraryAccessor DEFAULT;
58
    public static LibraryAccessor DEFAULT;
Lines 63-67 Link Here
63
    }
67
    }
64
    
68
    
65
    public abstract Library createLibrary (LibraryImplementation libraryImplementation);
69
    public abstract Library createLibrary (LibraryImplementation libraryImplementation);
66
    
70
71
    // RADIKAL GENERIC HAX!
72
73
    /**
74
     * Type-safe accessor for {@link ArealLibraryProvider#remove}.
75
     * @throws ClassCastException if the runtime types do not match
76
     */
77
    public static void remove(ArealLibraryProvider alp, LibraryImplementation lib) throws IOException {
78
        remove0((ArealLibraryProvider<?,?>) alp, lib);
79
    }
80
    private static <L extends LibraryImplementation> void remove0(ArealLibraryProvider<?,L> alp, LibraryImplementation lib) throws IOException {
81
        alp.remove(alp.libraryType().cast(lib));
82
    }
83
84
    /**
85
     * Type-safe accessor for {@link ArealLibraryProvider#getOpenAreas}.
86
     */
87
    public static Set<? extends LibraryStorageArea> getOpenAreas(ArealLibraryProvider alp) {
88
        return ((ArealLibraryProvider<?,?>) alp).getOpenAreas();
89
    }
90
91
    /**
92
     * Type-safe accessor for {@link ArealLibraryProvider#createLibrary}.
93
     * @throws ClassCastException if the runtime types do not match
94
     */
95
    public static LibraryImplementation createLibrary(ArealLibraryProvider alp, String type, String name, LibraryStorageArea area, Map<String,List<URL>> contents) throws IOException {
96
        return createLibrary0(((ArealLibraryProvider<?,?>) alp), type, name, area, contents);
97
    }
98
    private static <A extends LibraryStorageArea> LibraryImplementation createLibrary0(ArealLibraryProvider<A,?> alp, String type, String name, LibraryStorageArea area, Map<String,List<URL>> contents) throws IOException {
99
        return alp.createLibrary(type, name, alp.areaType().cast(area), contents);
100
    }
101
102
    /**
103
     * Type-safe accessor for {@link ArealLibraryProvider#getLibraries}.
104
     * @throws ClassCastException if the runtime types do not match
105
     */
106
    public static LibraryProvider getLibraries(ArealLibraryProvider alp, LibraryStorageArea area) {
107
        return getLibraries0((ArealLibraryProvider<?,?>) alp, area);
108
    }
109
    private static <A extends LibraryStorageArea> LibraryProvider getLibraries0(ArealLibraryProvider<A,?> alp, LibraryStorageArea area) {
110
        return alp.getLibraries(alp.areaType().cast(area));
111
    }
112
67
}
113
}
(-)projects/libraries/src/org/netbeans/modules/project/libraries/WritableLibraryProvider.java:1.2 (-1 / +1 lines)
Lines 44-50 Link Here
44
import org.netbeans.spi.project.libraries.LibraryProvider;
44
import org.netbeans.spi.project.libraries.LibraryProvider;
45
import java.io.IOException;
45
import java.io.IOException;
46
46
47
public interface WritableLibraryProvider extends LibraryProvider {
47
public interface WritableLibraryProvider<L extends LibraryImplementation> extends LibraryProvider<L> {
48
48
49
    void addLibrary(LibraryImplementation library) throws IOException;
49
    void addLibrary(LibraryImplementation library) throws IOException;
50
50
(-)/dev/null (+64 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8" ?>
2
3
<Form version="1.5" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
4
  <AuxValues>
5
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
6
    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
7
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
8
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
9
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
10
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
11
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
12
    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
13
  </AuxValues>
14
15
  <Layout>
16
    <DimensionLayout dim="0">
17
      <Group type="103" groupAlignment="0" attributes="0">
18
          <Group type="102" alignment="1" attributes="0">
19
              <EmptySpace min="-2" max="-2" attributes="0"/>
20
              <Group type="103" groupAlignment="1" attributes="0">
21
                  <Component id="placeholder" alignment="0" pref="377" max="32767" attributes="0"/>
22
                  <Group type="102" alignment="1" attributes="0">
23
                      <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
24
                      <EmptySpace max="-2" attributes="0"/>
25
                      <Component id="libraryManagerComboBox" pref="289" max="32767" attributes="0"/>
26
                  </Group>
27
              </Group>
28
              <EmptySpace min="-2" max="-2" attributes="0"/>
29
          </Group>
30
      </Group>
31
    </DimensionLayout>
32
    <DimensionLayout dim="1">
33
      <Group type="103" groupAlignment="0" attributes="0">
34
          <Group type="102" alignment="0" attributes="0">
35
              <EmptySpace max="-2" attributes="0"/>
36
              <Group type="103" groupAlignment="3" attributes="0">
37
                  <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
38
                  <Component id="libraryManagerComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
39
              </Group>
40
              <EmptySpace max="-2" attributes="0"/>
41
              <Component id="placeholder" pref="230" max="32767" attributes="0"/>
42
          </Group>
43
      </Group>
44
    </DimensionLayout>
45
  </Layout>
46
  <SubComponents>
47
    <Component class="javax.swing.JComboBox" name="libraryManagerComboBox">
48
      <Events>
49
        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="libraryManagerComboBoxActionPerformed"/>
50
      </Events>
51
    </Component>
52
    <Container class="javax.swing.JPanel" name="placeholder">
53
54
      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
55
    </Container>
56
    <Component class="javax.swing.JLabel" name="jLabel1">
57
      <Properties>
58
        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
59
          <ResourceString bundle="org/netbeans/modules/project/libraries/ui/Bundle.properties" key="AllLibrariesCustomizer.jLabel1.text" replaceFormat="java.text.MessageFormat.format(org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;), {arguments})"/>
60
        </Property>
61
      </Properties>
62
    </Component>
63
  </SubComponents>
64
</Form>
(-)/dev/null (+166 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.modules.project.libraries.ui;
43
44
import org.netbeans.api.project.libraries.*;
45
import org.netbeans.modules.project.libraries.ui.*;
46
import java.io.File;
47
import java.net.URL;
48
import java.util.ArrayList;
49
import java.util.List;
50
import javax.swing.DefaultComboBoxModel;
51
import org.netbeans.api.project.libraries.LibraryManager;
52
import org.netbeans.modules.project.libraries.LibraryAccessor;
53
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
54
import org.netbeans.spi.project.libraries.LibraryStorageArea;
55
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
56
import org.openide.util.Lookup;
57
import org.openide.util.NbBundle;
58
59
/**
60
 *
61
 */
62
class AllLibrariesCustomizer extends javax.swing.JPanel {
63
    
64
    private org.netbeans.modules.project.libraries.ui.LibrariesCustomizer librariesCustomizer;
65
    /** Creates new form AllLibrariesCustomizer */
66
    public AllLibrariesCustomizer() {
67
        initComponents();
68
        librariesCustomizer = new org.netbeans.modules.project.libraries.ui.LibrariesCustomizer(null);
69
        placeholder.add(librariesCustomizer);
70
        initModel();
71
    }
72
73
    public boolean apply() {
74
        return librariesCustomizer.apply();
75
    }
76
    
77
    private void initModel() {
78
        List<String> items = new ArrayList<String>();
79
        items.add(NbBundle.getMessage(AllLibrariesCustomizer.class, "LABEL_Global_Libraries"));
80
        for (LibraryManager man : LibraryManager.getOpenManagers()) {
81
            if (man.getLocation() == null) {
82
                continue;
83
            }
84
            items.add(LibrariesSupport.convertURLToFile(man.getLocation()).getPath());
85
        }
86
        libraryManagerComboBox.setModel(new DefaultComboBoxModel(items.toArray(new String[items.size()])));
87
    }
88
    
89
    /** This method is called from within the constructor to
90
     * initialize the form.
91
     * WARNING: Do NOT modify this code. The content of this method is
92
     * always regenerated by the Form Editor.
93
     */
94
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
95
    private void initComponents() {
96
97
        libraryManagerComboBox = new javax.swing.JComboBox();
98
        placeholder = new javax.swing.JPanel();
99
        jLabel1 = new javax.swing.JLabel();
100
101
        libraryManagerComboBox.addActionListener(new java.awt.event.ActionListener() {
102
            public void actionPerformed(java.awt.event.ActionEvent evt) {
103
                libraryManagerComboBoxActionPerformed(evt);
104
            }
105
        });
106
107
        placeholder.setLayout(new java.awt.BorderLayout());
108
109
        jLabel1.setText(java.text.MessageFormat.format(org.openide.util.NbBundle.getMessage(AllLibrariesCustomizer.class, "AllLibrariesCustomizer.jLabel1.text"), new Object[] {})); // NOI18N
110
111
        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
112
        this.setLayout(layout);
113
        layout.setHorizontalGroup(
114
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
115
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
116
                .addContainerGap()
117
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
118
                    .add(org.jdesktop.layout.GroupLayout.LEADING, placeholder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE)
119
                    .add(layout.createSequentialGroup()
120
                        .add(jLabel1)
121
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
122
                        .add(libraryManagerComboBox, 0, 289, Short.MAX_VALUE)))
123
                .addContainerGap())
124
        );
125
        layout.setVerticalGroup(
126
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
127
            .add(layout.createSequentialGroup()
128
                .addContainerGap()
129
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
130
                    .add(jLabel1)
131
                    .add(libraryManagerComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
132
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
133
                .add(placeholder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 230, Short.MAX_VALUE))
134
        );
135
    }// </editor-fold>//GEN-END:initComponents
136
137
    private void libraryManagerComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_libraryManagerComboBoxActionPerformed
138
        int index = libraryManagerComboBox.getSelectedIndex();
139
        if (index == -1) {
140
            return;
141
        } else if (index == 0) {
142
            librariesCustomizer.setLibraryStorageArea(null);
143
        } else if (index > 0) {
144
            URL u = LibrariesSupport.convertFileToURL(new File ((String)libraryManagerComboBox.getModel().getSelectedItem()));
145
            librariesCustomizer.setLibraryStorageArea(findLibraryStorageArea(u));
146
        }
147
    }//GEN-LAST:event_libraryManagerComboBoxActionPerformed
148
    
149
    private LibraryStorageArea findLibraryStorageArea(URL u) {
150
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
151
            for (LibraryStorageArea area : LibraryAccessor.getOpenAreas(alp)) {
152
                if (u.equals(area.getLocation())) {
153
                    return area;
154
                }
155
            }
156
        }
157
        return null;
158
    }
159
    
160
    // Variables declaration - do not modify//GEN-BEGIN:variables
161
    private javax.swing.JLabel jLabel1;
162
    private javax.swing.JComboBox libraryManagerComboBox;
163
    private javax.swing.JPanel placeholder;
164
    // End of variables declaration//GEN-END:variables
165
    
166
}
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/Bundle.properties:1.24 (+6 lines)
Lines 63-65 Link Here
63
AD_NewLibraryPanel=N/A
63
AD_NewLibraryPanel=N/A
64
64
65
TXT_LibrariesPanel=&Libraries\:
65
TXT_LibrariesPanel=&Libraries\:
66
LBL_global=Global Libraries
67
68
areaLabel.text=Storage &Location\:
69
LABEL_Global_Libraries=Global Libraries
70
TXT_LibrariesManager=Library Manager
71
AllLibrariesCustomizer.jLabel1.text=Libraries location:
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/LibrariesCustomizer.form:1.10 (-8 / +17 lines)
Lines 1-17 Link Here
1
<?xml version="1.0" encoding="UTF-8" ?>
1
<?xml version="1.0" encoding="UTF-8" ?>
2
2
3
<Form version="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
3
<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
4
  <Properties>
5
    <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
6
      <Dimension value="[642, 395]"/>
7
    </Property>
8
  </Properties>
4
  <AccessibilityProperties>
9
  <AccessibilityProperties>
5
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
10
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
6
      <ResourceString bundle="org/netbeans/modules/project/libraries/ui/Bundle.properties" key="AD_LibrariesCustomizer" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
11
      <ResourceString bundle="org/netbeans/modules/project/libraries/ui/Bundle.properties" key="AD_LibrariesCustomizer" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
7
    </Property>
12
    </Property>
8
  </AccessibilityProperties>
13
  </AccessibilityProperties>
9
  <AuxValues>
14
  <AuxValues>
15
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
16
    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
10
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
17
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
18
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
19
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
11
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
20
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
12
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
21
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
13
    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
22
    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
14
    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-67,0,0,2,-112"/>
23
    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-72,0,0,2,-112"/>
15
  </AuxValues>
24
  </AuxValues>
16
25
17
  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
26
  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
Lines 27-33 Link Here
27
      </Properties>
36
      </Properties>
28
      <Constraints>
37
      <Constraints>
29
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
38
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
30
          <GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="12" insetsRight="6" anchor="18" weightX="0.0" weightY="0.0"/>
39
          <GridBagConstraints gridX="3" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="12" insetsRight="6" anchor="18" weightX="0.0" weightY="0.0"/>
31
        </Constraint>
40
        </Constraint>
32
      </Constraints>
41
      </Constraints>
33
    </Component>
42
    </Component>
Lines 42-55 Link Here
42
      </AccessibilityProperties>
51
      </AccessibilityProperties>
43
      <Constraints>
52
      <Constraints>
44
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
53
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
45
          <GridBagConstraints gridX="3" gridY="1" gridWidth="0" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="12" insetsRight="12" anchor="18" weightX="0.6" weightY="0.0"/>
54
          <GridBagConstraints gridX="4" gridY="1" gridWidth="0" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="12" insetsRight="0" anchor="18" weightX="0.6" weightY="0.0"/>
46
        </Constraint>
55
        </Constraint>
47
      </Constraints>
56
      </Constraints>
48
    </Component>
57
    </Component>
49
    <Container class="javax.swing.JPanel" name="jPanel1">
58
    <Container class="javax.swing.JPanel" name="jPanel1">
50
      <Constraints>
59
      <Constraints>
51
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
60
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
52
          <GridBagConstraints gridX="2" gridY="2" gridWidth="0" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="12" insetsRight="12" anchor="18" weightX="1.0" weightY="1.0"/>
61
          <GridBagConstraints gridX="3" gridY="2" gridWidth="0" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="6" insetsBottom="12" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
53
        </Constraint>
62
        </Constraint>
54
      </Constraints>
63
      </Constraints>
55
64
Lines 95-101 Link Here
95
      </Events>
104
      </Events>
96
      <Constraints>
105
      <Constraints>
97
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
106
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
98
          <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="12" insetsBottom="0" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
107
          <GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
99
        </Constraint>
108
        </Constraint>
100
      </Constraints>
109
      </Constraints>
101
    </Component>
110
    </Component>
Lines 134-140 Link Here
134
      </AccessibilityProperties>
143
      </AccessibilityProperties>
135
      <Constraints>
144
      <Constraints>
136
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
145
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
137
          <GridBagConstraints gridX="0" gridY="1" gridWidth="2" gridHeight="2" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="12" insetsBottom="12" insetsRight="6" anchor="18" weightX="0.0" weightY="1.0"/>
146
          <GridBagConstraints gridX="0" gridY="1" gridWidth="3" gridHeight="2" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="12" insetsRight="6" anchor="18" weightX="0.0" weightY="1.0"/>
138
        </Constraint>
147
        </Constraint>
139
      </Constraints>
148
      </Constraints>
140
149
Lines 151-157 Link Here
151
      </Properties>
160
      </Properties>
152
      <Constraints>
161
      <Constraints>
153
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
162
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
154
          <GridBagConstraints gridX="0" gridY="0" gridWidth="0" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="12" insetsLeft="12" insetsBottom="2" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
163
          <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="2" insetsRight="12" anchor="18" weightX="0.0" weightY="0.0"/>
155
        </Constraint>
164
        </Constraint>
156
      </Constraints>
165
      </Constraints>
157
    </Component>
166
    </Component>
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/LibrariesCustomizer.java:1.28 (-168 / +322 lines)
Lines 43-48 Link Here
43
43
44
import java.awt.Dialog;
44
import java.awt.Dialog;
45
import java.awt.Dimension;
45
import java.awt.Dimension;
46
import java.awt.EventQueue;
46
import java.awt.GridBagConstraints;
47
import java.awt.GridBagConstraints;
47
import java.awt.GridBagLayout;
48
import java.awt.GridBagLayout;
48
import java.awt.Image;
49
import java.awt.Image;
Lines 54-69 Link Here
54
import java.beans.PropertyVetoException;
55
import java.beans.PropertyVetoException;
55
import java.beans.VetoableChangeListener;
56
import java.beans.VetoableChangeListener;
56
import java.io.IOException;
57
import java.io.IOException;
58
import java.net.URL;
59
import java.text.Collator;
57
import java.util.ArrayList;
60
import java.util.ArrayList;
58
import java.util.Collection;
61
import java.util.Collection;
62
import java.util.Collections;
63
import java.util.Comparator;
64
import java.util.List;
59
import java.util.MissingResourceException;
65
import java.util.MissingResourceException;
60
import java.util.ResourceBundle;
66
import java.util.ResourceBundle;
61
import javax.swing.JComponent;
67
import javax.swing.JComponent;
62
import javax.swing.JPanel;
68
import javax.swing.JPanel;
63
import javax.swing.event.ListDataEvent;
69
import javax.swing.event.ChangeEvent;
64
import javax.swing.event.ListDataListener;
70
import javax.swing.event.ChangeListener;
65
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
71
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
66
import org.netbeans.spi.project.libraries.LibraryImplementation;
72
import org.netbeans.spi.project.libraries.LibraryImplementation;
73
import org.netbeans.spi.project.libraries.LibraryStorageArea;
67
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
74
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
68
import org.openide.DialogDescriptor;
75
import org.openide.DialogDescriptor;
69
import org.openide.DialogDisplayer;
76
import org.openide.DialogDisplayer;
Lines 80-117 Link Here
80
import org.openide.nodes.NodeOp;
87
import org.openide.nodes.NodeOp;
81
import org.openide.util.HelpCtx;
88
import org.openide.util.HelpCtx;
82
import org.openide.util.NbBundle;
89
import org.openide.util.NbBundle;
90
import org.openide.util.Utilities;
83
import org.openide.util.lookup.Lookups;
91
import org.openide.util.lookup.Lookups;
84
92
85
/**
86
 *
87
 * @author  tom
88
 */
89
public final class LibrariesCustomizer extends JPanel implements ExplorerManager.Provider, HelpCtx.Provider {    
93
public final class LibrariesCustomizer extends JPanel implements ExplorerManager.Provider, HelpCtx.Provider {    
90
    
94
    
91
    private ExplorerManager manager;
95
    private ExplorerManager manager;
92
    private LibrariesModel model;
96
    private LibrariesModel model;
93
    private BeanTreeView libraries;
97
    private BeanTreeView libraries;
98
    private LibraryStorageArea libraryStorageArea;
94
99
95
    /** Creates new form LibrariesCustomizer */
100
    public LibrariesCustomizer (LibraryStorageArea libraryStorageArea) {
96
    public LibrariesCustomizer () {
97
        this.model = new LibrariesModel ();
101
        this.model = new LibrariesModel ();
102
        this.libraryStorageArea = (libraryStorageArea != null ? libraryStorageArea : LibrariesModel.GLOBAL_AREA);
98
        initComponents();
103
        initComponents();
99
        postInitComponents ();
104
        postInitComponents ();
105
        expandTree();
106
    }
107
    
108
    private void expandTree() {
109
        // get first library node
110
        Node[] n = getExplorerManager().getRootContext().getChildren().getNodes()[0].getChildren().getNodes();
111
        if (n.length != 0) {
112
            try {
113
                getExplorerManager().setSelectedNodes(new Node[]{n[0]});
114
            } catch (PropertyVetoException ex) {
115
                // OK to ignore - it is just selection initialization
116
            }
117
        }
118
    }
119
    
120
    public void setLibraryStorageArea(LibraryStorageArea libraryStorageArea) {
121
        this.libraryStorageArea = (libraryStorageArea != null ? libraryStorageArea : LibrariesModel.GLOBAL_AREA);
122
        forceTreeRecreation();
123
        expandTree();
124
    }
125
    
126
    public LibrariesModel getModel() {
127
        return model;
128
    }
129
    
130
    public void hideLibrariesList() {
131
        libsPanel.setVisible(false);
132
        jLabel2.setVisible(false);
133
        createButton.setVisible(false);
134
        deleteButton.setVisible(false);
135
    }
136
    
137
    /**
138
     * Force nodes recreation after LibrariesModel change. The nodes listen on
139
     * model and eventually refresh themselves but usually it is too late.
140
     * So forcing recreation makes sure that any subsequent call to 
141
     * NodeOp.findPath is successful and selects just created library node.
142
     */
143
    public void forceTreeRecreation() {
144
        getExplorerManager().setRootContext(buildTree());
100
    }
145
    }
101
102
146
103
    public void setSelectedLibrary (LibraryImplementation library) {
147
    public void setSelectedLibrary (LibraryImplementation library) {
104
        if (library == null)
148
        if (library == null)
105
            return;
149
            return;
106
        ExplorerManager manager = this.getExplorerManager();
150
        ExplorerManager currentManager = this.getExplorerManager();
107
        Node root = manager.getRootContext();        
151
        Node root = currentManager.getRootContext();        
108
        String[] path = new String[2];
152
        String[] path = {library.getType(), library.getName()};
109
        path[0]=library.getType();
110
        path[1]=library.getName();
111
        try {
153
        try {
112
            Node node = NodeOp.findPath(root, path);
154
            Node node = NodeOp.findPath(root, path);
113
            if (node != null) {
155
            if (node != null) {
114
                manager.setSelectedNodes(new Node[] {node});
156
                currentManager.setSelectedNodes(new Node[] {node});
115
            }
157
            }
116
        } catch (NodeNotFoundException e) {
158
        } catch (NodeNotFoundException e) {
117
            //Ignore it
159
            //Ignore it
Lines 135-167 Link Here
135
        }
177
        }
136
    }
178
    }
137
179
138
    public void cancel () {
139
        this.model.cancel();
140
    }
141
142
    public void addNotify() {
180
    public void addNotify() {
143
        super.addNotify();
181
        super.addNotify();
144
        expandAllNodes(this.libraries,this.getExplorerManager().getRootContext());
182
        expandAllNodes(this.libraries,this.getExplorerManager().getRootContext());
145
        //Select first library if nothing selected
183
        //Select first library if nothing selected
146
        if (this.getExplorerManager().getSelectedNodes().length == 0) {
184
        if (this.getExplorerManager().getSelectedNodes().length == 0) {
147
        Node root = this.getExplorerManager().getRootContext();
185
            SELECTED: for (Node areaNode : getExplorerManager().getRootContext().getChildren().getNodes(true)) {
148
            Node[] nodes = root.getChildren().getNodes (true);
186
                for (Node typeNode : areaNode.getChildren().getNodes(true)) {
149
            for (int i = 0; i< nodes.length; i++) {
187
                    for (Node libNode : typeNode.getChildren().getNodes(true)) {
150
                Node[] lnodes = nodes[i].getChildren().getNodes(true);
188
                        try {
151
                if (lnodes.length > 0) {
189
                            getExplorerManager().setSelectedNodes(new Node[] {libNode});
152
                    try {
190
                        } catch (PropertyVetoException e) {
153
                        this.getExplorerManager().setSelectedNodes(new Node[] {lnodes[0]});
191
                            //Ignore it
154
                    } catch (PropertyVetoException e) {
192
                        }
155
                        //Ignore it
193
                        break SELECTED;
156
                    }
194
                    }
157
                    break;
158
                }
195
                }
159
            }
196
            }
160
        }
197
        }
161
        this.libraries.requestFocus();
198
        this.libraries.requestFocus();
162
    }    
199
    }    
163
    
200
    
164
    
165
    public ExplorerManager getExplorerManager () {
201
    public ExplorerManager getExplorerManager () {
166
        if (this.manager == null) {
202
        if (this.manager == null) {
167
            this.manager = new ExplorerManager ();
203
            this.manager = new ExplorerManager ();
Lines 187-198 Link Here
187
                    }
223
                    }
188
                }
224
                }
189
            });            
225
            });            
190
            this.manager.setRootContext (buildTree(this.model));
226
            manager.setRootContext(buildTree());
191
        }
227
        }
192
        return this.manager;
228
        return this.manager;
193
    }
229
    }
194
230
195
196
    private void postInitComponents () {
231
    private void postInitComponents () {
197
        this.libraries = new LibrariesView ();        
232
        this.libraries = new LibrariesView ();        
198
        GridBagConstraints c = new GridBagConstraints ();
233
        GridBagConstraints c = new GridBagConstraints ();
Lines 217-235 Link Here
217
                });                        
252
                });                        
218
    }
253
    }
219
254
220
221
    private void nameChanged () {
255
    private void nameChanged () {
222
        Node[] nodes = this.getExplorerManager().getSelectedNodes();
256
        Node[] nodes = this.getExplorerManager().getSelectedNodes();
223
        if (nodes.length == 1 && (nodes[0] instanceof LibraryNode)) {
257
        if (nodes.length == 1) {
224
            LibraryNode node = (LibraryNode) nodes[0];
258
            LibraryImplementation lib = nodes[0].getLookup().lookup(LibraryImplementation.class);
259
            if (lib == null) {
260
                return;
261
            }
225
            String newName = this.libraryName.getText();
262
            String newName = this.libraryName.getText();
263
            if (newName.equals(lib.getName())) {
264
                return;
265
            }
226
            if (newName.length () == 0) {
266
            if (newName.length () == 0) {
227
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message (
267
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message (
228
                        NbBundle.getMessage(LibrariesCustomizer.class, "ERR_InvalidName"),
268
                        NbBundle.getMessage(LibrariesCustomizer.class, "ERR_InvalidName"),
229
                        NotifyDescriptor.ERROR_MESSAGE));
269
                        NotifyDescriptor.ERROR_MESSAGE));
230
            }
270
            } else if (isValidName(model, newName, model.getArea(lib))) {
231
            else if (isValidName (this.model, newName)) {
271
                lib.setName(newName);
232
                node.getLibrary().setName(newName);
233
            }
272
            }
234
            else {
273
            else {
235
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message (
274
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message (
Lines 239-245 Link Here
239
        }                        
278
        }                        
240
    }
279
    }
241
280
242
243
    private void selectLibrary (Node[] nodes) {
281
    private void selectLibrary (Node[] nodes) {
244
        int tabCount = this.properties.getTabCount();
282
        int tabCount = this.properties.getTabCount();
245
        for (int i=0; i<tabCount; i++) {
283
        for (int i=0; i<tabCount; i++) {
Lines 251-272 Link Here
251
        this.libraryName.setVisible(false);
289
        this.libraryName.setVisible(false);
252
        this.properties.setVisible(false);
290
        this.properties.setVisible(false);
253
        this.deleteButton.setEnabled(false);        
291
        this.deleteButton.setEnabled(false);        
254
        if (nodes.length != 1 || !(nodes[0] instanceof LibraryNode)) {            
292
        if (nodes.length != 1) {
293
            return;
294
        }
295
        LibraryImplementation impl = nodes[0].getLookup().lookup(LibraryImplementation.class);
296
        if (impl == null) {
255
            return;
297
            return;
256
        }
298
        }
257
        this.jLabel1.setVisible(true);
299
        this.jLabel1.setVisible(true);
258
        this.libraryName.setVisible(true);
300
        this.libraryName.setVisible(true);
259
        this.properties.setVisible(true);
301
        this.properties.setVisible(true);
260
        LibraryNode lnode = (LibraryNode) nodes[0];
261
        LibraryImplementation impl = lnode.getLibrary ();
262
        boolean editable = model.isLibraryEditable (impl);
302
        boolean editable = model.isLibraryEditable (impl);
263
        this.libraryName.setEnabled(editable);
303
        this.libraryName.setEnabled(editable);
264
        this.deleteButton.setEnabled(editable);
304
        this.deleteButton.setEnabled(editable);
265
        this.libraryName.setText (getLocalizedString(impl.getLocalizingBundle(),impl.getName()));
305
        this.libraryName.setText (getLocalizedString(impl.getLocalizingBundle(),impl.getName()));
266
        String libraryType = impl.getType();
306
        LibraryTypeProvider provider = nodes[0].getLookup().lookup(LibraryTypeProvider.class);
267
        LibraryTypeProvider provider = lnode.getProvider ();
268
        if (provider == null)
307
        if (provider == null)
269
            return;
308
            return;
309
        // a library customizer needs to know location of sharable library in order to
310
        // relativize paths. that's why object implementing both LibraryImplementation
311
        // and LibraryStorageArea is passed to JComponent here:
312
        LibraryStorageArea area = nodes[0].getLookup().lookup(LibraryStorageArea.class);
313
        if (area != null && area != LibrariesModel.GLOBAL_AREA) {
314
            impl = new LibraryImplementationWrapper(impl, area);
315
        }
316
270
        String[] volumeTypes = provider.getSupportedVolumeTypes();
317
        String[] volumeTypes = provider.getSupportedVolumeTypes();
271
        for (int i=0; i< volumeTypes.length; i++) {
318
        for (int i=0; i< volumeTypes.length; i++) {
272
            Customizer c = provider.getCustomizer (volumeTypes[i]);
319
            Customizer c = provider.getCustomizer (volumeTypes[i]);
Lines 282-294 Link Here
282
            }
329
            }
283
        }        
330
        }        
284
    }
331
    }
285
332
    
286
    /** This method is called from within the constructor to
333
    /** This method is called from within the constructor to
287
     * initialize the form.
334
     * initialize the form.
288
     * WARNING: Do NOT modify this code. The content of this method is
335
     * WARNING: Do NOT modify this code. The content of this method is
289
     * always regenerated by the Form Editor.
336
     * always regenerated by the Form Editor.
290
     */
337
     */
291
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
338
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
292
    private void initComponents() {
339
    private void initComponents() {
293
        java.awt.GridBagConstraints gridBagConstraints;
340
        java.awt.GridBagConstraints gridBagConstraints;
294
341
Lines 301-313 Link Here
301
        libsPanel = new javax.swing.JPanel();
348
        libsPanel = new javax.swing.JPanel();
302
        jLabel2 = new javax.swing.JLabel();
349
        jLabel2 = new javax.swing.JLabel();
303
350
351
        setMinimumSize(new java.awt.Dimension(642, 395));
304
        setLayout(new java.awt.GridBagLayout());
352
        setLayout(new java.awt.GridBagLayout());
305
353
306
        getAccessibleContext().setAccessibleDescription(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AD_LibrariesCustomizer"));
307
        jLabel1.setLabelFor(libraryName);
354
        jLabel1.setLabelFor(libraryName);
308
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("CTL_CustomizerLibraryName"));
355
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle"); // NOI18N
356
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, bundle.getString("CTL_CustomizerLibraryName")); // NOI18N
309
        gridBagConstraints = new java.awt.GridBagConstraints();
357
        gridBagConstraints = new java.awt.GridBagConstraints();
310
        gridBagConstraints.gridx = 2;
358
        gridBagConstraints.gridx = 3;
311
        gridBagConstraints.gridy = 1;
359
        gridBagConstraints.gridy = 1;
312
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
360
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
313
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 6);
361
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 6);
Lines 315-410 Link Here
315
363
316
        libraryName.setEditable(false);
364
        libraryName.setEditable(false);
317
        gridBagConstraints = new java.awt.GridBagConstraints();
365
        gridBagConstraints = new java.awt.GridBagConstraints();
318
        gridBagConstraints.gridx = 3;
366
        gridBagConstraints.gridx = 4;
319
        gridBagConstraints.gridy = 1;
367
        gridBagConstraints.gridy = 1;
320
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
368
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
321
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
369
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
322
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
370
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
323
        gridBagConstraints.weightx = 0.6;
371
        gridBagConstraints.weightx = 0.6;
324
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 12);
372
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
325
        add(libraryName, gridBagConstraints);
373
        add(libraryName, gridBagConstraints);
326
        libraryName.getAccessibleContext().setAccessibleDescription(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AD_LibraryName"));
374
        libraryName.getAccessibleContext().setAccessibleDescription(bundle.getString("AD_LibraryName")); // NOI18N
327
375
328
        jPanel1.setLayout(new java.awt.BorderLayout());
376
        jPanel1.setLayout(new java.awt.BorderLayout());
329
377
330
        properties.setPreferredSize(new java.awt.Dimension(400, 300));
378
        properties.setPreferredSize(new java.awt.Dimension(400, 300));
331
        jPanel1.add(properties, java.awt.BorderLayout.CENTER);
379
        jPanel1.add(properties, java.awt.BorderLayout.CENTER);
332
        properties.getAccessibleContext().setAccessibleName(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AN_LibrariesCustomizerProperties"));
380
        properties.getAccessibleContext().setAccessibleName(bundle.getString("AN_LibrariesCustomizerProperties")); // NOI18N
333
        properties.getAccessibleContext().setAccessibleDescription(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AD_LibrariesCustomizerProperties"));
381
        properties.getAccessibleContext().setAccessibleDescription(bundle.getString("AD_LibrariesCustomizerProperties")); // NOI18N
334
382
335
        gridBagConstraints = new java.awt.GridBagConstraints();
383
        gridBagConstraints = new java.awt.GridBagConstraints();
336
        gridBagConstraints.gridx = 2;
384
        gridBagConstraints.gridx = 3;
337
        gridBagConstraints.gridy = 2;
385
        gridBagConstraints.gridy = 2;
338
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
386
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
339
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
387
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
340
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
388
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
341
        gridBagConstraints.weightx = 1.0;
389
        gridBagConstraints.weightx = 1.0;
342
        gridBagConstraints.weighty = 1.0;
390
        gridBagConstraints.weighty = 1.0;
343
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 12);
391
        gridBagConstraints.insets = new java.awt.Insets(0, 6, 12, 0);
344
        add(jPanel1, gridBagConstraints);
392
        add(jPanel1, gridBagConstraints);
345
393
346
        org.openide.awt.Mnemonics.setLocalizedText(createButton, java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("CTL_NewLibrary"));
394
        org.openide.awt.Mnemonics.setLocalizedText(createButton, bundle.getString("CTL_NewLibrary")); // NOI18N
347
        createButton.addActionListener(new java.awt.event.ActionListener() {
395
        createButton.addActionListener(new java.awt.event.ActionListener() {
348
            public void actionPerformed(java.awt.event.ActionEvent evt) {
396
            public void actionPerformed(java.awt.event.ActionEvent evt) {
349
                createLibrary(evt);
397
                createLibrary(evt);
350
            }
398
            }
351
        });
399
        });
352
353
        gridBagConstraints = new java.awt.GridBagConstraints();
400
        gridBagConstraints = new java.awt.GridBagConstraints();
354
        gridBagConstraints.gridx = 0;
401
        gridBagConstraints.gridx = 0;
355
        gridBagConstraints.gridy = 3;
402
        gridBagConstraints.gridy = 3;
356
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
403
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
357
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 12);
404
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
358
        add(createButton, gridBagConstraints);
405
        add(createButton, gridBagConstraints);
359
        createButton.getAccessibleContext().setAccessibleDescription(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AD_NewLibrary"));
406
        createButton.getAccessibleContext().setAccessibleDescription(bundle.getString("AD_NewLibrary")); // NOI18N
360
407
361
        org.openide.awt.Mnemonics.setLocalizedText(deleteButton, java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("CTL_DeleteLibrary"));
408
        org.openide.awt.Mnemonics.setLocalizedText(deleteButton, bundle.getString("CTL_DeleteLibrary")); // NOI18N
362
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
409
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
363
            public void actionPerformed(java.awt.event.ActionEvent evt) {
410
            public void actionPerformed(java.awt.event.ActionEvent evt) {
364
                deleteLibrary(evt);
411
                deleteLibrary(evt);
365
            }
412
            }
366
        });
413
        });
367
368
        gridBagConstraints = new java.awt.GridBagConstraints();
414
        gridBagConstraints = new java.awt.GridBagConstraints();
369
        gridBagConstraints.gridx = 1;
415
        gridBagConstraints.gridx = 1;
370
        gridBagConstraints.gridy = 3;
416
        gridBagConstraints.gridy = 3;
371
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
417
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
372
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
418
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
373
        add(deleteButton, gridBagConstraints);
419
        add(deleteButton, gridBagConstraints);
374
        deleteButton.getAccessibleContext().setAccessibleDescription(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AD_DeleteLibrary"));
420
        deleteButton.getAccessibleContext().setAccessibleDescription(bundle.getString("AD_DeleteLibrary")); // NOI18N
375
421
422
        libsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
376
        libsPanel.setLayout(new java.awt.GridBagLayout());
423
        libsPanel.setLayout(new java.awt.GridBagLayout());
377
378
        libsPanel.setBorder(new javax.swing.border.EtchedBorder());
379
        gridBagConstraints = new java.awt.GridBagConstraints();
424
        gridBagConstraints = new java.awt.GridBagConstraints();
380
        gridBagConstraints.gridx = 0;
425
        gridBagConstraints.gridx = 0;
381
        gridBagConstraints.gridy = 1;
426
        gridBagConstraints.gridy = 1;
382
        gridBagConstraints.gridwidth = 2;
427
        gridBagConstraints.gridwidth = 3;
383
        gridBagConstraints.gridheight = 2;
428
        gridBagConstraints.gridheight = 2;
384
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
429
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
385
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
430
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
386
        gridBagConstraints.weighty = 1.0;
431
        gridBagConstraints.weighty = 1.0;
387
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 12, 6);
432
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 6);
388
        add(libsPanel, gridBagConstraints);
433
        add(libsPanel, gridBagConstraints);
389
        libsPanel.getAccessibleContext().setAccessibleDescription(java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("AD_libsPanel"));
434
        libsPanel.getAccessibleContext().setAccessibleDescription(bundle.getString("AD_libsPanel")); // NOI18N
390
435
391
        jLabel2.setLabelFor(libsPanel);
436
        jLabel2.setLabelFor(libsPanel);
392
        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, java.util.ResourceBundle.getBundle("org/netbeans/modules/project/libraries/ui/Bundle").getString("TXT_LibrariesPanel"));
437
        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, bundle.getString("TXT_LibrariesPanel")); // NOI18N
393
        gridBagConstraints = new java.awt.GridBagConstraints();
438
        gridBagConstraints = new java.awt.GridBagConstraints();
394
        gridBagConstraints.gridx = 0;
439
        gridBagConstraints.gridx = 0;
395
        gridBagConstraints.gridy = 0;
440
        gridBagConstraints.gridy = 0;
396
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
397
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
441
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
398
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
442
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
399
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 2, 12);
443
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 12);
400
        add(jLabel2, gridBagConstraints);
444
        add(jLabel2, gridBagConstraints);
401
445
402
    }
446
        getAccessibleContext().setAccessibleDescription(bundle.getString("AD_LibrariesCustomizer")); // NOI18N
403
    // </editor-fold>//GEN-END:initComponents
447
    }// </editor-fold>//GEN-END:initComponents
404
448
405
    private void deleteLibrary(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteLibrary
449
    private void deleteLibrary(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteLibrary
406
        Node[] nodes = this.getExplorerManager().getSelectedNodes();
450
        Node[] nodes = this.getExplorerManager().getSelectedNodes();
407
        if (nodes.length == 1 && (nodes[0] instanceof LibraryNode)) {            
451
        if (nodes.length == 1) {
452
            LibraryImplementation library = nodes[0].getLookup().lookup(LibraryImplementation.class);
453
            if (library == null) {
454
                return;
455
            }
408
            Node[] sib = nodes[0].getParentNode().getChildren().getNodes(true);            
456
            Node[] sib = nodes[0].getParentNode().getChildren().getNodes(true);            
409
            Node selNode = null;
457
            Node selNode = null;
410
            for (int i=0; i < sib.length; i++) {
458
            for (int i=0; i < sib.length; i++) {
Lines 417-423 Link Here
417
                    }
465
                    }
418
                }
466
                }
419
            }            
467
            }            
420
            model.removeLibrary (((LibraryNode)nodes[0]).getLibrary());
468
            model.removeLibrary(library);
421
            try {
469
            try {
422
                if (selNode != null) {
470
                if (selNode != null) {
423
                    this.getExplorerManager().setSelectedNodes(new Node[] {selNode});            
471
                    this.getExplorerManager().setSelectedNodes(new Node[] {selNode});            
Lines 433-446 Link Here
433
        Dialog dlg = null;
481
        Dialog dlg = null;
434
        try {
482
        try {
435
            String preselectedLibraryType = null;
483
            String preselectedLibraryType = null;
484
            LibraryStorageArea area = null;
436
            Node[] preselectedNodes = this.getExplorerManager().getSelectedNodes();
485
            Node[] preselectedNodes = this.getExplorerManager().getSelectedNodes();
437
            if (preselectedNodes.length == 1) {
486
            if (preselectedNodes.length == 1) {
438
                LibraryCategory lc = preselectedNodes[0].getLookup().lookup(LibraryCategory.class);
487
                LibraryTypeProvider provider = preselectedNodes[0].getLookup().lookup(LibraryTypeProvider.class);
439
                if (lc != null) {
488
                if (provider != null) {
440
                    preselectedLibraryType = lc.getCategoryType();
489
                    preselectedLibraryType = provider.getLibraryType();
441
                }
490
                }
491
                area = preselectedNodes[0].getLookup().lookup(LibraryStorageArea.class);
492
            }
493
            if (area == null) {
494
                area = LibrariesModel.GLOBAL_AREA;
442
            }
495
            }
443
            NewLibraryPanel p = new NewLibraryPanel (this.model, preselectedLibraryType);
496
            NewLibraryPanel p = new NewLibraryPanel(model, preselectedLibraryType, area);
444
            DialogDescriptor dd = new DialogDescriptor (p, NbBundle.getMessage(LibrariesCustomizer.class,"CTL_CreateLibrary"),
497
            DialogDescriptor dd = new DialogDescriptor (p, NbBundle.getMessage(LibrariesCustomizer.class,"CTL_CreateLibrary"),
445
                    true, DialogDescriptor.OK_CANCEL_OPTION, null, null);
498
                    true, DialogDescriptor.OK_CANCEL_OPTION, null, null);
446
            p.setDialogDescriptor(dd);
499
            p.setDialogDescriptor(dd);
Lines 448-464 Link Here
448
            dlg.setVisible(true);
501
            dlg.setVisible(true);
449
            if (dd.getValue() == DialogDescriptor.OK_OPTION) {
502
            if (dd.getValue() == DialogDescriptor.OK_OPTION) {
450
                String libraryType = p.getLibraryType();
503
                String libraryType = p.getLibraryType();
451
                String libraryName = p.getLibraryName();
504
                String currentLibraryName = p.getLibraryName();
452
                LibraryTypeProvider provider = LibraryTypeRegistry.getDefault().getLibraryTypeProvider (libraryType);
505
                LibraryImplementation impl;
453
                if (provider == null) {
506
                if (area != LibrariesModel.GLOBAL_AREA) {
454
                    return;
507
                    impl = model.createArealLibrary(libraryType, currentLibraryName, area);
508
                } else {
509
                    LibraryTypeProvider provider = LibraryTypeRegistry.getDefault().getLibraryTypeProvider(libraryType);
510
                    if (provider == null) {
511
                        return;
512
                    }
513
                    impl = provider.createLibrary();
514
                    impl.setName(currentLibraryName);
455
                }
515
                }
456
                LibraryImplementation impl = provider.createLibrary();
457
                impl.setName (libraryName);
458
                model.addLibrary (impl);                
516
                model.addLibrary (impl);                
459
                String[] path = new String[2];
517
                forceTreeRecreation();
460
                path[0] = impl.getType();
518
                String[] path = {impl.getType(), impl.getName()};
461
                path[1] = impl.getName();
462
                ExplorerManager mgr = this.getExplorerManager();
519
                ExplorerManager mgr = this.getExplorerManager();
463
                try {
520
                try {
464
                    Node node = NodeOp.findPath(mgr.getRootContext(),path);
521
                    Node node = NodeOp.findPath(mgr.getRootContext(),path);
Lines 484-501 Link Here
484
        }
541
        }
485
    }//GEN-LAST:event_createLibrary
542
    }//GEN-LAST:event_createLibrary
486
543
487
544
    static boolean isValidName(LibrariesModel model, String name, LibraryStorageArea area) {
488
    static boolean isValidName (LibrariesModel model, String name) {
545
        for (LibraryImplementation lib : model.getLibraries()) {
489
        int count = model.getSize();
546
            if (lib.getName().equals(name) && Utilities.compareObjects(model.getArea(lib), area)) {
490
        for (int i=0; i<count; i++) {
491
            LibraryImplementation lib = (LibraryImplementation) model.getElementAt (i);
492
            if (lib != null && lib.getName().equals(name))
493
                return false;
547
                return false;
548
            }
494
        }
549
        }
495
        return true;
550
        return true;
496
    }
551
    }
497
552
498
499
    static String getLocalizedString (String bundleResourceName, String key) {
553
    static String getLocalizedString (String bundleResourceName, String key) {
500
        if (key == null) {
554
        if (key == null) {
501
            return null;
555
            return null;
Lines 519-525 Link Here
519
        }
573
        }
520
    }
574
    }
521
575
522
523
    // Variables declaration - do not modify//GEN-BEGIN:variables
576
    // Variables declaration - do not modify//GEN-BEGIN:variables
524
    private javax.swing.JButton createButton;
577
    private javax.swing.JButton createButton;
525
    private javax.swing.JButton deleteButton;
578
    private javax.swing.JButton deleteButton;
Lines 530-536 Link Here
530
    private javax.swing.JPanel libsPanel;
583
    private javax.swing.JPanel libsPanel;
531
    private javax.swing.JTabbedPane properties;
584
    private javax.swing.JTabbedPane properties;
532
    // End of variables declaration//GEN-END:variables
585
    // End of variables declaration//GEN-END:variables
533
            
534
586
535
    private static void expandAllNodes (BeanTreeView btv, Node node) {
587
    private static void expandAllNodes (BeanTreeView btv, Node node) {
536
        btv.expandNode (node);
588
        btv.expandNode (node);
Lines 558-573 Link Here
558
        
610
        
559
    }
611
    }
560
    
612
    
561
    
613
    private class AreaChildren extends Children.Keys<LibraryStorageArea> implements ChangeListener {
562
    private static class RootChildren extends Children.Keys<LibraryTypeProvider> {
614
563
        
615
        @Override
564
        private LibrariesModel model;
616
        protected void addNotify() {
565
        
617
            super.addNotify();
566
        public RootChildren (LibrariesModel model) {
618
            model.addChangeListener(this);
567
            this.model = model;
619
            computeKeys();
568
        }
620
        }
569
        
621
622
        @Override
623
        protected void removeNotify() {
624
            super.removeNotify();
625
            model.removeChangeListener(this);
626
            setKeys(Collections.<LibraryStorageArea>emptySet());
627
        }
628
629
        private void computeKeys() {
630
            setKeys(getSortedAreas(model));
631
        }
632
633
        protected Node[] createNodes(LibraryStorageArea area) {
634
            return new Node[] {new AreaNode(area)};
635
        }
636
637
        public void stateChanged(ChangeEvent e) {
638
            EventQueue.invokeLater(new Runnable() {
639
                public void run() {
640
                    computeKeys();
641
                }
642
            });
643
        }
644
645
    }
646
647
    static Collection<? extends LibraryStorageArea> getSortedAreas(LibrariesModel model) {
648
        List<LibraryStorageArea> areas = new ArrayList<LibraryStorageArea>(model.getAreas());
649
        Collections.sort(areas,new Comparator<LibraryStorageArea>() {
650
            Collator COLL = Collator.getInstance();
651
            public int compare(LibraryStorageArea a1, LibraryStorageArea a2) {
652
                return COLL.compare(a1.getDisplayName(), a2.getDisplayName());
653
            }
654
        });
655
        areas.add(0, LibrariesModel.GLOBAL_AREA);
656
        assert !areas.contains(null);
657
        return areas;
658
    }
659
660
    private final class AreaNode extends AbstractNode {
661
662
        private final LibraryStorageArea area;
663
664
        AreaNode(LibraryStorageArea area) {
665
            super(new TypeChildren(area), Lookups.singleton(area));
666
            this.area = area;
667
        }
668
669
        @Override
670
        public String getName() {
671
            return getDisplayName();
672
        }
673
674
        @Override
675
        public String getDisplayName() {
676
            return area.getDisplayName();
677
        }
678
679
        private Node delegate() {
680
            return DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot()).getNodeDelegate();
681
        }
682
683
        public Image getIcon(int type) {
684
            return delegate().getIcon(type);
685
        }
686
687
        public Image getOpenedIcon(int type) {
688
            return delegate().getOpenedIcon(type);
689
        }
690
691
    }
692
693
    private class TypeChildren extends Children.Keys<LibraryTypeProvider> {
694
695
        private final LibraryStorageArea area;
696
697
        TypeChildren(LibraryStorageArea area) {
698
            this.area = area;
699
        }
700
570
        public void addNotify () {
701
        public void addNotify () {
702
            // Could also filter by area (would then need to listen to model too)
571
            this.setKeys(LibraryTypeRegistry.getDefault().getLibraryTypeProviders());
703
            this.setKeys(LibraryTypeRegistry.getDefault().getLibraryTypeProviders());
572
        }
704
        }
573
        
705
        
Lines 576-609 Link Here
576
        }
708
        }
577
        
709
        
578
        protected Node[] createNodes(LibraryTypeProvider provider) {
710
        protected Node[] createNodes(LibraryTypeProvider provider) {
579
            return new Node[] {new CategoryNode(provider, model)};
711
            return new Node[] {new CategoryNode(provider, area)};
580
        }
712
        }
581
        
713
        
582
    }
714
    }
583
    
715
    
584
    
716
    private class CategoryNode extends AbstractNode {
585
    private static final class LibraryCategory {
586
        
587
        private final String name;
588
        
589
        LibraryCategory (String name) {
590
            this.name = name;
591
        }
592
        
593
        public String getCategoryType () {
594
            return this.name;
595
        }
596
        
597
    }
598
    
599
    private static class CategoryNode extends AbstractNode {
600
                
601
        
717
        
602
        private LibraryTypeProvider provider;
718
        private LibraryTypeProvider provider;
603
        private Node iconDelegate;
719
        private Node iconDelegate;
604
                
720
                
605
        public CategoryNode (LibraryTypeProvider provider, LibrariesModel model) {
721
        public CategoryNode(LibraryTypeProvider provider, LibraryStorageArea area) {
606
            super (new CategoryChildren(provider, model), Lookups.singleton(new LibraryCategory (provider.getLibraryType())));
722
            super(new CategoryChildren(provider, area), Lookups.fixed(provider, area));
607
            this.provider = provider;       
723
            this.provider = provider;       
608
            this.iconDelegate = DataFolder.findFolder (Repository.getDefault().getDefaultFileSystem().getRoot()).getNodeDelegate();
724
            this.iconDelegate = DataFolder.findFolder (Repository.getDefault().getDefaultFileSystem().getRoot()).getNodeDelegate();
609
        }
725
        }
Lines 625-647 Link Here
625
        }        
741
        }        
626
                        
742
                        
627
    }    
743
    }    
628
    
744
629
    private static class CategoryChildren extends Children.Keys<LibraryImplementation> implements ListDataListener {
745
    private class CategoryChildren extends Children.Keys<LibraryImplementation> implements ChangeListener {
630
        
746
        
631
        private LibraryTypeProvider provider;
747
        private LibraryTypeProvider provider;
632
        private LibrariesModel model;
748
        private final LibraryStorageArea area;
633
        
749
        
634
        public CategoryChildren (LibraryTypeProvider provider, LibrariesModel model) {
750
        public CategoryChildren(LibraryTypeProvider provider, LibraryStorageArea area) {
635
            this.provider = provider;
751
            this.provider = provider;
636
            this.model = model;
752
            this.area = area;
637
            this.model.addListDataListener(this);
753
            model.addChangeListener(this);
638
        }
754
        }
639
        
755
        
640
        public void addNotify () {
756
        public void addNotify () {
641
            Collection<LibraryImplementation> keys = new ArrayList<LibraryImplementation>();
757
            Collection<LibraryImplementation> keys = new ArrayList<LibraryImplementation>();
642
            for (int i=0; i<model.getSize(); i++) {
758
            for (LibraryImplementation impl : model.getLibraries()) {
643
                LibraryImplementation impl = (LibraryImplementation) model.getElementAt(i);
759
                if (provider.getLibraryType().equals(impl.getType()) && model.getArea(impl).equals(area)) {
644
                if (this.provider.getLibraryType().equals(impl.getType())) {
645
                    keys.add (impl);
760
                    keys.add (impl);
646
                }
761
                }
647
            }
762
            }
Lines 653-674 Link Here
653
        }
768
        }
654
        
769
        
655
        protected Node[] createNodes(LibraryImplementation impl) {
770
        protected Node[] createNodes(LibraryImplementation impl) {
656
            return new Node[] {new LibraryNode(impl, provider)};
771
            return new Node[] {new LibraryNode(impl, provider, area)};
657
        }
658
        
659
        public void contentsChanged(ListDataEvent e) {
660
            //Todo: Optimize it
661
            this.addNotify();
662
        }
663
        
664
        public void intervalAdded(ListDataEvent e) {
665
            //Todo: Optimize it
666
            this.addNotify();
667
        }
772
        }
668
        
773
        
669
        public void intervalRemoved(ListDataEvent e) {
774
        public void stateChanged(ChangeEvent e) {
670
            //Todo: Optimize it
775
            EventQueue.invokeLater(new Runnable() {
671
            this.addNotify();
776
                public void run() {
777
                    addNotify();
778
                }
779
            });
672
        }
780
        }
673
        
781
        
674
    }
782
    }
Lines 680-687 Link Here
680
        private LibraryImplementation lib;
788
        private LibraryImplementation lib;
681
        private LibraryTypeProvider provider;
789
        private LibraryTypeProvider provider;
682
        
790
        
683
        public LibraryNode (LibraryImplementation lib, LibraryTypeProvider provider) {            
791
        public LibraryNode(LibraryImplementation lib, LibraryTypeProvider provider, LibraryStorageArea area) {
684
            super (Children.LEAF);
792
            super(Children.LEAF, Lookups.fixed(lib, provider, area));
685
            this.lib = lib;
793
            this.lib = lib;
686
            this.provider = provider;
794
            this.provider = provider;
687
            this.setIconBaseWithExtension(ICON);
795
            this.setIconBaseWithExtension(ICON);
Lines 695-721 Link Here
695
            return getLocalizedString(this.lib.getLocalizingBundle(), this.lib.getName());
803
            return getLocalizedString(this.lib.getLocalizingBundle(), this.lib.getName());
696
        }
804
        }
697
        
805
        
698
        public LibraryImplementation getLibrary () {
806
    }
699
            return this.lib;            
807
    
700
        }
808
    private Node buildTree() {
809
        return new AbstractNode(new TypeChildren(libraryStorageArea));
810
    }
811
812
    private static class LibraryImplementationWrapper implements LibraryImplementation, LibraryStorageArea {
701
        
813
        
702
        public LibraryTypeProvider getProvider () {
814
        private LibraryImplementation lib;
703
            return this.provider;
815
        private LibraryStorageArea area;
704
        }
705
        
816
        
706
        public boolean equals (Object other) {
817
        public LibraryImplementationWrapper(LibraryImplementation lib, LibraryStorageArea area) {
707
            if (other instanceof LibraryNode) {
818
            this.lib =  lib;
708
                LibraryNode ol = (LibraryNode) other;
819
            this.area = area;
709
                return (this.lib == null ? ol.lib == null : this.lib.equals(ol.lib))
820
        }
710
                    && (this.provider == null ? ol.provider == null : this.provider.equals(ol.provider));
821
711
            }
822
        public String getType() {
712
            return false;
823
            return lib.getType();
824
        }
825
826
        public String getName() {
827
            return lib.getName();
828
        }
829
830
        public String getDescription() {
831
            return lib.getDescription();
832
        }
833
834
        public String getLocalizingBundle() {
835
            return lib.getLocalizingBundle();
836
        }
837
838
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
839
            return lib.getContent(volumeType);
840
        }
841
842
        public void setName(String name) {
843
            lib.setName(name);
844
        }
845
846
        public void setDescription(String text) {
847
            lib.setDescription(text);
848
        }
849
850
        public void setLocalizingBundle(String resourceName) {
851
            lib.setLocalizingBundle(resourceName);
852
        }
853
854
        public void addPropertyChangeListener(PropertyChangeListener l) {
855
            lib.addPropertyChangeListener(l);
856
        }
857
858
        public void removePropertyChangeListener(PropertyChangeListener l) {
859
            lib.removePropertyChangeListener(l);
860
        }
861
862
        public void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
863
            lib.setContent(volumeType, path);
864
        }
865
866
        public URL getLocation() {
867
            return area.getLocation();
868
        }
869
870
        public String getDisplayName() {
871
            return area.getDisplayName();
713
        }
872
        }
714
    }
873
    }
715
    
716
    private static Node buildTree (LibrariesModel model) {
717
        return new AbstractNode (new RootChildren (model));
718
    }
719
    
720
    
874
    
721
}
875
}
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/LibrariesCustomizerAction.java:1.5 (-1 / +27 lines)
Lines 40-45 Link Here
40
 */
40
 */
41
package org.netbeans.modules.project.libraries.ui;
41
package org.netbeans.modules.project.libraries.ui;
42
42
43
import java.awt.Dialog;
44
import org.openide.DialogDescriptor;
45
import org.openide.DialogDisplayer;
43
import org.openide.util.HelpCtx;
46
import org.openide.util.HelpCtx;
44
import org.openide.util.NbBundle;
47
import org.openide.util.NbBundle;
45
import org.openide.util.actions.CallableSystemAction;
48
import org.openide.util.actions.CallableSystemAction;
Lines 54-60 Link Here
54
    }
57
    }
55
58
56
    public void performAction() {
59
    public void performAction() {
57
        org.netbeans.api.project.libraries.LibrariesCustomizer.showCustomizer(null);
60
        showCustomizer();
58
    }
61
    }
59
62
60
    public String getName() {
63
    public String getName() {
Lines 68-72 Link Here
68
    protected boolean asynchronous () {
71
    protected boolean asynchronous () {
69
        return false;
72
        return false;
70
    }
73
    }
74
75
    /**
76
     * Shows libraries customizer displaying all currently open library managers.
77
     * @return true if user pressed OK and libraries were sucessfully modified
78
     */
79
    private static boolean showCustomizer () {
80
        AllLibrariesCustomizer  customizer =
81
                new AllLibrariesCustomizer();
82
        DialogDescriptor descriptor = new DialogDescriptor (customizer,
83
                NbBundle.getMessage(LibrariesCustomizerAction.class, "TXT_LibrariesManager"));
84
        Dialog dlg = DialogDisplayer.getDefault().createDialog(descriptor);
85
        try {
86
            dlg.setVisible(true);
87
            if (descriptor.getValue() == DialogDescriptor.OK_OPTION) {
88
                return customizer.apply();
89
            } else {
90
                return false;
91
            }
92
        } finally {
93
            dlg.dispose();
94
        }
95
    }
96
    
71
    
97
    
72
}
98
}
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/LibrariesModel.java:1.12 (-146 / +285 lines)
Lines 41-126 Link Here
41
41
42
package org.netbeans.modules.project.libraries.ui;
42
package org.netbeans.modules.project.libraries.ui;
43
43
44
44
import java.awt.EventQueue;
45
import java.beans.PropertyChangeEvent;
45
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeListener;
47
import java.beans.PropertyChangeSupport;
46
import java.io.IOException;
48
import java.io.IOException;
47
import java.util.*;
49
import java.net.URL;
48
50
import java.util.ArrayList;
49
51
import java.util.Collection;
52
import java.util.Collections;
53
import java.util.Comparator;
54
import java.util.HashMap;
55
import java.util.HashSet;
56
import java.util.List;
57
import java.util.Map;
58
import java.util.Set;
59
import java.util.TreeSet;
60
import java.util.logging.Level;
61
import java.util.logging.Logger;
62
import javax.swing.event.ChangeListener;
63
import org.netbeans.modules.project.libraries.LibraryAccessor;
50
import org.netbeans.spi.project.libraries.LibraryImplementation;
64
import org.netbeans.spi.project.libraries.LibraryImplementation;
51
import org.netbeans.spi.project.libraries.LibraryProvider;
65
import org.netbeans.spi.project.libraries.LibraryProvider;
52
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
66
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
67
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
68
import org.netbeans.spi.project.libraries.LibraryStorageArea;
53
import org.openide.util.Lookup;
69
import org.openide.util.Lookup;
54
import org.openide.util.LookupListener;
70
import org.openide.util.ChangeSupport;
55
import org.openide.util.LookupEvent;
71
import org.openide.util.NbBundle;
56
import org.openide.ErrorManager;
72
import org.openide.util.WeakListeners;
57
73
58
/**
74
public class LibrariesModel implements PropertyChangeListener {
59
 *
75
60
 * @author  tom
76
    public static final LibraryStorageArea GLOBAL_AREA = new LibraryStorageArea() {
61
 */
77
        public String getDisplayName() {
62
class LibrariesModel extends javax.swing.AbstractListModel implements PropertyChangeListener, LookupListener {
78
            return NbBundle.getMessage(LibrariesModel.class, "LBL_global");
63
79
        }
64
    private List<LibraryImplementation> actualLibraries;
80
        public URL getLocation() {
65
    private List<LibraryImplementation> addedLibraries;
81
            throw new AssertionError();
66
    private List<LibraryImplementation> removedLibraries;
82
        }
67
    private List<ProxyLibraryImplementation> changedLibraries;
83
    };
68
    private Collection<? extends LibraryProvider> currentStorages;
84
69
    private Map<LibraryImplementation,LibraryProvider> storageByLib;
85
    private static final Logger LOG = Logger.getLogger(LibrariesModel.class.getName());
70
    private Lookup.Result<LibraryProvider> lresult;
86
87
    /**
88
     * Set of areas which have been explicitly created/loaded in this IDE session (thus static).
89
     * Keep only URL, <em>not</em> LibraryStorageArea, to avoid memory leaks.
90
     * Could also be modified to persist a LRU in NbPreferences, etc.
91
     */
92
    public static final Set<URL> createdAreas = Collections.synchronizedSet(new HashSet<URL>());
93
94
    private final Map<LibraryImplementation,LibraryStorageArea> library2Area = new HashMap<LibraryImplementation,LibraryStorageArea>();
95
    private final Map<LibraryStorageArea,ArealLibraryProvider> area2Storage = new HashMap<LibraryStorageArea,ArealLibraryProvider>();
96
    private final Map<LibraryImplementation,LibraryProvider> storageByLib = new HashMap<LibraryImplementation,LibraryProvider>();
97
    private final Map<LibraryStorageArea,LibraryProvider> area2Provider = new HashMap<LibraryStorageArea,LibraryProvider>();
98
    private final Collection<LibraryImplementation> actualLibraries = new TreeSet<LibraryImplementation>(new LibrariesComparator());
99
    private final List<LibraryImplementation> addedLibraries;
100
    private final List<LibraryImplementation> removedLibraries;
101
    private final List<ProxyLibraryImplementation> changedLibraries;
71
    private WritableLibraryProvider writableProvider;
102
    private WritableLibraryProvider writableProvider;
103
    private final ChangeSupport cs = new ChangeSupport(this);
72
104
73
    /** Creates a new instance of LibrariesModel */
74
    public LibrariesModel () {
105
    public LibrariesModel () {
75
        this.addedLibraries = new ArrayList<LibraryImplementation>();
106
        this.addedLibraries = new ArrayList<LibraryImplementation>();
76
        this.removedLibraries = new ArrayList<LibraryImplementation>();
107
        this.removedLibraries = new ArrayList<LibraryImplementation>();
77
        this.changedLibraries = new ArrayList<ProxyLibraryImplementation>();
108
        this.changedLibraries = new ArrayList<ProxyLibraryImplementation>();
78
        this.currentStorages = Collections.emptySet();
109
        for (LibraryProvider lp : Lookup.getDefault().lookupAll(LibraryProvider.class)) {
79
        this.storageByLib = new HashMap<LibraryImplementation,LibraryProvider>();
110
            lp.addPropertyChangeListener(WeakListeners.propertyChange(this, lp));
80
        this.getLibraries ();
111
            if (writableProvider == null && lp instanceof WritableLibraryProvider) {
112
                writableProvider = (WritableLibraryProvider) lp;
113
            }
114
        }
115
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
116
            alp.addPropertyChangeListener(WeakListeners.propertyChange(this, alp));
117
        }
118
        this.computeLibraries();
81
    }
119
    }
82
    
120
    
83
    public Object getElementAt(int index) {
121
    public synchronized Collection<? extends LibraryImplementation> getLibraries() {
84
        if (index < 0 || index >= this.actualLibraries.size())
122
        return actualLibraries;
85
            return null;
123
    }
86
        return actualLibraries.get(index);
124
87
    }    
125
    public void addChangeListener(ChangeListener l) {
88
    
126
        cs.addChangeListener(l);
89
    public int getSize() {
127
    }
90
        return this.actualLibraries.size();
128
129
    public void removeChangeListener(ChangeListener l) {
130
        cs.removeChangeListener(l);
131
    }
132
133
    public LibraryStorageArea createArea() {
134
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
135
            LibraryStorageArea area = alp.createArea();
136
            if (area != null) {
137
                createdAreas.add(area.getLocation());
138
                area2Storage.put(area, alp);
139
                propertyChange(null); // recompute libraries & fire change
140
                return area;
141
            }
142
        }
143
        return null;
144
    }
145
146
    public LibraryImplementation createArealLibrary(String type, String name, LibraryStorageArea area) {
147
        LibraryImplementation impl = new DummyArealLibrary(type, name);
148
        library2Area.put(impl, area);
149
        return impl;
150
    }
151
152
    public Collection<? extends LibraryStorageArea> getAreas() {
153
        Set<LibraryStorageArea> areas = new HashSet<LibraryStorageArea>();
154
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
155
            for (LibraryStorageArea area : LibraryAccessor.getOpenAreas(alp)) {
156
                area2Storage.put(area, alp);
157
                areas.add(area);
158
            }
159
        }
160
        for (ArealLibraryProvider alp : Lookup.getDefault().lookupAll(ArealLibraryProvider.class)) {
161
            for (URL location : createdAreas) {
162
                LibraryStorageArea area = alp.loadArea(location);
163
                if (area != null) {
164
                    assert area.getLocation().equals(location) : "Bad location " + area.getLocation() + " does not match " + location + " from " + alp.getClass().getName();
165
                    area2Storage.put(area, alp);
166
                    areas.add(area);
167
                }
168
            }
169
        }
170
        return areas;
171
    }
172
173
    public LibraryStorageArea getArea(LibraryImplementation library) {
174
        LibraryStorageArea area = getAreaOrNull(library);
175
        return area != null ? area : GLOBAL_AREA;
176
    }
177
    private LibraryStorageArea getAreaOrNull(LibraryImplementation library) {
178
        if (library instanceof ProxyLibraryImplementation) {
179
            library = ((ProxyLibraryImplementation) library).getOriginal();
180
        }
181
        return library2Area.get(library);
91
    }
182
    }
92
183
93
    public void addLibrary (LibraryImplementation impl) {
184
    public void addLibrary (LibraryImplementation impl) {
94
        this.addedLibraries.add (impl);
185
        synchronized (this) {
95
        int index=0;
186
            addedLibraries.add(impl);
96
        Comparator<LibraryImplementation> c = new LibrariesComparator();
187
            actualLibraries.add(impl);
97
        for (; index < this.actualLibraries.size(); index++) {
98
            LibraryImplementation tmp = this.actualLibraries.get(index);
99
            if (c.compare(impl,tmp)<0)
100
                break;
101
        }
188
        }
102
        this.actualLibraries.add (index, impl);
189
        cs.fireChange();
103
        this.fireIntervalAdded (this,index,index);
104
    }
190
    }
105
191
106
    public void removeLibrary (LibraryImplementation impl) {
192
    public void removeLibrary (LibraryImplementation impl) {
107
        if (this.addedLibraries.contains(impl)) {
193
        synchronized (this) {
108
            this.addedLibraries.remove(impl);
194
            if (addedLibraries.contains(impl)) {
109
        }
195
                addedLibraries.remove(impl);
110
        else {
196
            } else {
111
            this.removedLibraries.add (((ProxyLibraryImplementation)impl).getOriginal());
197
                removedLibraries.add(((ProxyLibraryImplementation) impl).getOriginal());
198
            }
199
            actualLibraries.remove(impl);
112
        }
200
        }
113
        int index = this.actualLibraries.indexOf(impl);
201
        cs.fireChange();
114
        this.actualLibraries.remove(index);
115
        this.fireIntervalRemoved(this,index,index);
116
    }
202
    }
117
203
118
    public void modifyLibrary(ProxyLibraryImplementation impl) {
204
    public void modifyLibrary(ProxyLibraryImplementation impl) {
119
        if (!this.addedLibraries.contains (impl) && !this.changedLibraries.contains(impl)) {
205
        synchronized (this) {
120
            this.changedLibraries.add(impl);
206
            if (!addedLibraries.contains(impl) && !changedLibraries.contains(impl)) {
207
                changedLibraries.add(impl);
208
            }
121
        }
209
        }
122
        int index = this.actualLibraries.indexOf (impl);
210
        cs.fireChange();
123
        this.fireContentsChanged(this,index,index);
124
    }
211
    }
125
212
126
    public boolean isLibraryEditable (LibraryImplementation impl) {
213
    public boolean isLibraryEditable (LibraryImplementation impl) {
Lines 128-194 Link Here
128
            return true;
215
            return true;
129
        LibraryProvider provider = storageByLib.get
216
        LibraryProvider provider = storageByLib.get
130
                (((ProxyLibraryImplementation)impl).getOriginal());
217
                (((ProxyLibraryImplementation)impl).getOriginal());
131
        //Todo: Currently just one WritableLibraryProvider
218
        return provider == writableProvider || getAreaOrNull(impl) != null;
132
        //Todo: if changed, must be rewritten to handle it
133
        return (provider == this.writableProvider);
134
    }
219
    }
135
220
136
    public void apply () throws IOException {
221
    public void apply () throws IOException {
137
        //Todo: Currently just one WritableLibraryProvider
138
        //Todo: if changed, must be rewritten to handle it
139
        for (LibraryImplementation impl : removedLibraries) {
222
        for (LibraryImplementation impl : removedLibraries) {
140
            LibraryProvider storage = storageByLib.get(impl);
223
            LibraryProvider storage = storageByLib.get(impl);
141
            if (storage == this.writableProvider) {
224
            if (storage == this.writableProvider) {
142
                this.writableProvider.removeLibrary (impl);
225
                this.writableProvider.removeLibrary (impl);
143
            }
226
            } else {
144
            else {
227
                LibraryStorageArea area = getAreaOrNull(impl);
145
                ErrorManager.getDefault().log ("Can not find storage for library: "+impl.getName());    //NOI18N
228
                if (area != null) {
229
                    LibraryAccessor.remove(area2Storage.get(area), impl);
230
                } else {
231
                    throw new IOException("Cannot find storage for library: " + impl.getName()); // NOI18N
232
                }
146
            }
233
            }
147
        }
234
        }
148
        if (this.writableProvider != null) {
235
        for (LibraryImplementation impl : addedLibraries) {
149
            for (LibraryImplementation impl : addedLibraries) {
236
            LibraryStorageArea area = getAreaOrNull(impl);
237
            if (area != null) {
238
                ArealLibraryProvider alp = area2Storage.get(area);
239
                assert alp != null : area;
240
                LibraryAccessor.createLibrary(alp, impl.getType(), impl.getName(), area, ((DummyArealLibrary) impl).contents);
241
            } else if (writableProvider != null) {
150
                writableProvider.addLibrary(impl);
242
                writableProvider.addLibrary(impl);
243
            } else {
244
                throw new IOException("Cannot add libraries, no WritableLibraryProvider."); // NOI18N
151
            }
245
            }
152
        }
246
        }
153
        else {
154
            ErrorManager.getDefault().log("Cannot add libraries, no WritableLibraryProvider."); //NOI18N
155
        }
156
        for (ProxyLibraryImplementation proxy : changedLibraries) {
247
        for (ProxyLibraryImplementation proxy : changedLibraries) {
157
            LibraryProvider storage = storageByLib.get(proxy.getOriginal());
248
            LibraryImplementation orig = proxy.getOriginal();
249
            LibraryProvider storage = storageByLib.get(orig);
158
            if (storage == this.writableProvider) {
250
            if (storage == this.writableProvider) {
159
                this.writableProvider.updateLibrary (proxy.getOriginal(), proxy);
251
                this.writableProvider.updateLibrary(orig, proxy);
160
            }
252
            } else {
161
            else {
253
                LibraryStorageArea area = library2Area.get(orig);
162
                ErrorManager.getDefault().log ("Can not find storage for library: "+proxy.getOriginal().getName());  //NOI18N
254
                if (area != null) {
255
                    if (proxy.newContents != null) {
256
                        for (Map.Entry<String,List<URL>> entry : proxy.newContents.entrySet()) {
257
                            orig.setContent(entry.getKey(), entry.getValue());
258
                        }
259
                    }
260
                } else {
261
                    throw new IOException("Cannot find storage for library: " + orig.getName()); // NOI18N
262
                }
163
            }
263
            }
164
        }
264
        }
165
        cleanUp ();
166
    }
167
168
    public void cancel() {
169
        cleanUp ();
170
    }
171
172
    public void propertyChange(java.beans.PropertyChangeEvent evt) {
173
        this.storagesChanged();
174
    }
175
176
    public void resultChanged(LookupEvent ev) {
177
        this.storagesChanged();
178
    }
265
    }
179
266
180
    public void storagesChanged () {
267
    public void propertyChange(PropertyChangeEvent evt) {
181
        int oldSize;
268
        // compute libraries later in AWT thread and not in calling thread
182
        synchronized (this) {
269
        // to prevent deadlocks
183
            oldSize = this.actualLibraries == null ? 0 : this.actualLibraries.size();
270
        EventQueue.invokeLater(new Runnable() {
184
            getLibraries();
271
            public void run() {
185
        }
272
                computeLibraries();
186
        this.fireContentsChanged(this, 0, Math.max(oldSize,this.actualLibraries.size()));
273
                cs.fireChange();
274
            }
275
        });
187
    }
276
    }
188
277
189
    private LibraryImplementation findModified (LibraryImplementation impl) {
278
    private ProxyLibraryImplementation findModified (LibraryImplementation impl) {
190
        for (Iterator it = changedLibraries.iterator(); it.hasNext();) {
279
        for (ProxyLibraryImplementation proxy : changedLibraries) {
191
            ProxyLibraryImplementation proxy = (ProxyLibraryImplementation) it.next();
192
            if (proxy.getOriginal().equals (impl)) {
280
            if (proxy.getOriginal().equals (impl)) {
193
                return proxy;
281
                return proxy;
194
            }
282
            }
Lines 196-263 Link Here
196
        return null;
284
        return null;
197
    }
285
    }
198
286
199
    private synchronized void cleanUp () {
287
    private synchronized void computeLibraries() {
200
        this.addedLibraries.clear();
288
        actualLibraries.clear();
201
        this.removedLibraries.clear();
289
        for (LibraryProvider storage : Lookup.getDefault().lookupAll(LibraryProvider.class)) {
202
        this.changedLibraries.clear();
203
        for (LibraryProvider p : currentStorages) {
204
            p.removePropertyChangeListener (this);
205
        }
206
        this.currentStorages = Collections.emptySet();
207
    }
208
209
    private synchronized void getLibraries () {
210
        List<LibraryImplementation> libraries = new ArrayList<LibraryImplementation>();
211
        if (this.lresult == null) {
212
            //First time
213
            this.lresult = Lookup.getDefault().lookupResult(LibraryProvider.class);
214
            this.lresult.addLookupListener (this);
215
        }
216
        Collection<? extends LibraryProvider> instances = this.lresult.allInstances();
217
        Collection<LibraryProvider> toAdd = new HashSet<LibraryProvider>(instances);
218
        toAdd.removeAll(this.currentStorages);
219
        Collection<LibraryProvider> toRemove = new HashSet<LibraryProvider>(this.currentStorages);
220
        toRemove.removeAll (instances);
221
        this.currentStorages = instances;
222
        this.storageByLib.clear();
223
        for (LibraryProvider storage : instances) {
224
            //TODO: in case of more WritableLibraryProvider must be changed
225
            if (this.writableProvider == null && storage instanceof WritableLibraryProvider) {
226
                this.writableProvider = (WritableLibraryProvider) storage;
227
            }
228
            for (LibraryImplementation lib : storage.getLibraries()) {
290
            for (LibraryImplementation lib : storage.getLibraries()) {
229
                LibraryImplementation proxy = null;
291
                ProxyLibraryImplementation proxy = findModified(lib);
230
                if (removedLibraries.contains(lib)) {
292
                if (proxy != null) {
231
                    this.storageByLib.put (lib,storage);
293
                    actualLibraries.add(proxy);
232
                }
294
                } else {
233
                else if ((proxy = findModified (lib))!=null) {
295
                    actualLibraries.add(proxy = new ProxyLibraryImplementation(lib, this));
234
                    libraries.add (proxy);
235
                    this.storageByLib.put (lib,storage);
236
                }
237
                else {
238
                    libraries.add(new ProxyLibraryImplementation(lib,this));
239
                    this.storageByLib.put (lib,storage);
240
                }
296
                }
297
                storageByLib.put(lib, storage);
298
                LOG.log(Level.FINER, "computeLibraries: storage={0} lib={1} proxy={2}", new Object[] {storage, lib, proxy});
241
            }
299
            }
242
        }
300
        }
243
        libraries.addAll (this.addedLibraries);
301
        for (LibraryStorageArea area : getAreas()) {
244
        Collections.sort(libraries, new LibrariesComparator());
302
            ArealLibraryProvider alp = area2Storage.get(area);
245
303
            assert alp != null : area;
246
        for (LibraryProvider p : toRemove) {
304
            LibraryProvider prov = area2Provider.get(area);
247
            p.removePropertyChangeListener(this);
305
            if (prov == null) {
248
        }
306
                prov = LibraryAccessor.getLibraries(alp, area);
249
        for (LibraryProvider p : toAdd) {
307
                prov.addPropertyChangeListener(this); // need not be weak, we just created the source
250
            p.addPropertyChangeListener(this);
308
                area2Provider.put(area, prov);
309
            }
310
            for (LibraryImplementation lib : prov.getLibraries()) {
311
                ProxyLibraryImplementation proxy = findModified(lib);
312
                if (proxy != null) {
313
                    actualLibraries.add(proxy);
314
                } else {
315
                    actualLibraries.add(proxy = new ProxyLibraryImplementation(lib, this));
316
                }
317
                library2Area.put(lib, area);
318
                LOG.log(Level.FINER, "computeLibraries: alp={0} area={1} lib={2} proxy={3}", new Object[] {alp, area, lib, proxy});
319
            }
251
        }
320
        }
252
        this.actualLibraries = libraries;
321
        actualLibraries.addAll(addedLibraries);
322
        LOG.log(Level.FINE, "computeLibraries: actualLibraries={0} library2Area={1}", new Object[] {actualLibraries, library2Area});
253
    }
323
    }
254
324
255
    private static class LibrariesComparator implements Comparator<LibraryImplementation> {
325
    private static class LibrariesComparator implements Comparator<LibraryImplementation> {
256
        public int compare(LibraryImplementation lib1, LibraryImplementation lib2) {
326
        public int compare(LibraryImplementation lib1, LibraryImplementation lib2) {
257
            String name1 = LibrariesCustomizer.getLocalizedString(lib1.getLocalizingBundle(), lib1.getName());
327
            String name1 = LibrariesCustomizer.getLocalizedString(lib1.getLocalizingBundle(), lib1.getName());
258
            String name2 = LibrariesCustomizer.getLocalizedString(lib2.getLocalizingBundle(), lib2.getName());
328
            String name2 = LibrariesCustomizer.getLocalizedString(lib2.getLocalizingBundle(), lib2.getName());
259
            return name1.compareToIgnoreCase(name2);
329
            int r = name1.compareToIgnoreCase(name2);
260
        }        
330
            return r != 0 ? r : System.identityHashCode(lib1) - System.identityHashCode(lib2);
331
        }
332
    }
333
334
    private static final class DummyArealLibrary implements LibraryImplementation {
335
336
        private final String type, name;
337
        final Map<String,List<URL>> contents = new HashMap<String,List<URL>>();
338
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
339
340
        public DummyArealLibrary(String type, String name) {
341
            this.type = type;
342
            this.name = name;
343
        }
344
345
        public String getType() {
346
            return type;
347
        }
348
349
        public String getName() {
350
            return name;
351
        }
352
353
        public String getDescription() {
354
            return null;
355
        }
356
357
        public String getLocalizingBundle() {
358
            return null;
359
        }
360
361
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
362
            List<URL> content = contents.get(volumeType);
363
            if (content != null) {
364
                return content; 
365
            } else {
366
                return Collections.emptyList();
367
            }
368
        }
369
370
        public void setName(String name) {
371
            throw new UnsupportedOperationException();
372
        }
373
374
        public void setDescription(String text) {
375
            throw new UnsupportedOperationException();
376
        }
377
378
        public void setLocalizingBundle(String resourceName) {
379
            throw new UnsupportedOperationException();
380
        }
381
382
        public void addPropertyChangeListener(PropertyChangeListener l) {
383
            pcs.addPropertyChangeListener(l);
384
        }
385
386
        public void removePropertyChangeListener(PropertyChangeListener l) {
387
            pcs.removePropertyChangeListener(l);
388
        }
389
390
        public void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
391
            contents.put(volumeType, path);
392
            pcs.firePropertyChange(LibraryImplementation.PROP_CONTENT, null, null);
393
        }
394
395
        @Override
396
        public String toString() {
397
            return "DummyArealLibrary[" + name + "]"; // NOI18N
398
        }
399
261
    }
400
    }
262
401
263
}
402
}
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/NewLibraryPanel.form:1.7 (-3 / +4 lines)
Lines 1-14 Link Here
1
<?xml version="1.0" encoding="UTF-8" ?>
1
<?xml version="1.0" encoding="UTF-8" ?>
2
2
3
<Form version="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
3
<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
4
  <AccessibilityProperties>
4
  <AccessibilityProperties>
5
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
5
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
6
      <ResourceString bundle="org/netbeans/modules/project/libraries/ui/Bundle.properties" key="AD_NewLibraryPanel" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
6
      <ResourceString bundle="org/netbeans/modules/project/libraries/ui/Bundle.properties" key="AD_NewLibraryPanel" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
7
    </Property>
7
    </Property>
8
  </AccessibilityProperties>
8
  </AccessibilityProperties>
9
  <AuxValues>
9
  <AuxValues>
10
    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
10
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
11
    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
11
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
12
    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
12
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
13
    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
13
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
14
    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
14
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
15
    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
Lines 81-87 Link Here
81
    <Component class="javax.swing.JLabel" name="status">
82
    <Component class="javax.swing.JLabel" name="status">
82
      <Constraints>
83
      <Constraints>
83
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
84
        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
84
          <GridBagConstraints gridX="-1" gridY="-1" gridWidth="0" gridHeight="0" fill="1" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="12" insetsBottom="12" insetsRight="12" anchor="10" weightX="1.0" weightY="0.0"/>
85
          <GridBagConstraints gridX="0" gridY="3" gridWidth="0" gridHeight="0" fill="1" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="12" insetsBottom="12" insetsRight="12" anchor="10" weightX="1.0" weightY="0.0"/>
85
        </Constraint>
86
        </Constraint>
86
      </Constraints>
87
      </Constraints>
87
    </Component>
88
    </Component>
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/NewLibraryPanel.java:1.18 (-13 / +17 lines)
Lines 42-73 Link Here
42
package org.netbeans.modules.project.libraries.ui;
42
package org.netbeans.modules.project.libraries.ui;
43
43
44
import java.awt.Color;
44
import java.awt.Color;
45
import java.awt.Component;
45
import java.util.HashMap;
46
import java.util.HashMap;
46
import java.util.Map;
47
import java.util.Map;
47
import java.util.regex.Pattern;
48
import java.util.regex.Pattern;
49
import javax.swing.DefaultComboBoxModel;
50
import javax.swing.DefaultListCellRenderer;
51
import javax.swing.JList;
48
import org.openide.DialogDescriptor;
52
import org.openide.DialogDescriptor;
49
import org.openide.util.NbBundle;
53
import org.openide.util.NbBundle;
50
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
54
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
55
import org.netbeans.spi.project.libraries.LibraryStorageArea;
51
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
56
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
52
57
53
54
55
/**
56
 *
57
 * @author  tom
58
 */
59
public class NewLibraryPanel extends javax.swing.JPanel {
58
public class NewLibraryPanel extends javax.swing.JPanel {
60
59
61
    private LibrariesModel model;
60
    private LibrariesModel model;
62
    private Map<Integer,String> typeMap;
61
    private Map<Integer,String> typeMap;
62
    private LibraryStorageArea area;
63
63
64
    private DialogDescriptor dd;
64
    private DialogDescriptor dd;
65
65
66
    private static final Pattern VALID_LIBRARY_NAME = Pattern.compile("[-._a-zA-Z0-9]+"); // NOI18N
66
    private static final Pattern VALID_LIBRARY_NAME = Pattern.compile("[-._a-zA-Z0-9]+"); // NOI18N
67
67
68
    /** Creates new form NewLibraryPanel */
68
    public NewLibraryPanel (LibrariesModel model, String preselectedLibraryType, LibraryStorageArea area) {
69
    public NewLibraryPanel (LibrariesModel model, String preselectedLibraryType) {
70
        this.model = model;
69
        this.model = model;
70
        this.area = area;
71
        initComponents();
71
        initComponents();
72
        this.name.setColumns(25);
72
        this.name.setColumns(25);
73
        this.name.getDocument().addDocumentListener(new javax.swing.event.DocumentListener () {
73
        this.name.getDocument().addDocumentListener(new javax.swing.event.DocumentListener () {
Lines 84-90 Link Here
84
            }
84
            }
85
85
86
        });
86
        });
87
        this.initModel (preselectedLibraryType);
87
        initModel(preselectedLibraryType);
88
        Color c = javax.swing.UIManager.getColor("nb.errorForeground"); //NOI18N
88
        Color c = javax.swing.UIManager.getColor("nb.errorForeground"); //NOI18N
89
        if (c == null) {
89
        if (c == null) {
90
            c = new Color(89,79,191);  // RGB suggested by Bruce in #28466
90
            c = new Color(89,79,191);  // RGB suggested by Bruce in #28466
Lines 92-99 Link Here
92
        status.setForeground(c);
92
        status.setForeground(c);
93
    }
93
    }
94
    
94
    
95
    void setDialogDescriptor(DialogDescriptor dd) {
95
    public void setDialogDescriptor(DialogDescriptor dd) {
96
        assert this.dd == null;
96
        this.dd = dd;
97
        this.dd = dd;
98
        nameChanged();
97
    }
99
    }
98
    
100
    
99
    public String getLibraryType () {
101
    public String getLibraryType () {
Lines 110-116 Link Here
110
    }
112
    }
111
113
112
114
113
    private void initModel (String preselectedLibraryType) {
115
    private void initModel(String preselectedLibraryType) {
114
        this.typeMap = new HashMap<Integer,String>();
116
        this.typeMap = new HashMap<Integer,String>();
115
        this.name.setText (NbBundle.getMessage (NewLibraryPanel.class,"TXT_NewLibrary"));
117
        this.name.setText (NbBundle.getMessage (NewLibraryPanel.class,"TXT_NewLibrary"));
116
        LibraryTypeRegistry regs = LibraryTypeRegistry.getDefault();
118
        LibraryTypeRegistry regs = LibraryTypeRegistry.getDefault();
Lines 142-148 Link Here
142
            message = NbBundle.getMessage(NewLibraryPanel.class,"ERR_InvalidName");
144
            message = NbBundle.getMessage(NewLibraryPanel.class,"ERR_InvalidName");
143
        }
145
        }
144
        else {
146
        else {
145
            valid = LibrariesCustomizer.isValidName (model, name);
147
            valid = LibrariesCustomizer.isValidName(model, name, area);
146
            if (valid) {
148
            if (valid) {
147
                if (isReasonableAntProperty(name)) {
149
                if (isReasonableAntProperty(name)) {
148
                    message = " ";   //NOI18N
150
                    message = " ";   //NOI18N
Lines 174-180 Link Here
174
     * WARNING: Do NOT modify this code. The content of this method is
176
     * WARNING: Do NOT modify this code. The content of this method is
175
     * always regenerated by the Form Editor.
177
     * always regenerated by the Form Editor.
176
     */
178
     */
177
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
179
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
178
    private void initComponents() {
180
    private void initComponents() {
179
        java.awt.GridBagConstraints gridBagConstraints;
181
        java.awt.GridBagConstraints gridBagConstraints;
180
182
Lines 219-224 Link Here
219
        libraryType.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(NewLibraryPanel.class, "AD_LibraryType")); // NOI18N
221
        libraryType.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(NewLibraryPanel.class, "AD_LibraryType")); // NOI18N
220
222
221
        gridBagConstraints = new java.awt.GridBagConstraints();
223
        gridBagConstraints = new java.awt.GridBagConstraints();
224
        gridBagConstraints.gridx = 0;
225
        gridBagConstraints.gridy = 3;
222
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
226
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
223
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
227
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
224
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
228
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
(-)projects/libraries/src/org/netbeans/modules/project/libraries/ui/ProxyLibraryImplementation.java:1.5 (-4 / +4 lines)
Lines 51-56 Link Here
51
51
52
import org.netbeans.spi.project.libraries.LibraryImplementation;
52
import org.netbeans.spi.project.libraries.LibraryImplementation;
53
import org.openide.util.WeakListeners;
53
import org.openide.util.WeakListeners;
54
54
/**
55
/**
55
 *
56
 *
56
 * @author  tom
57
 * @author  tom
Lines 59-70 Link Here
59
60
60
    private final LibraryImplementation original;
61
    private final LibraryImplementation original;
61
    private final LibrariesModel model;
62
    private final LibrariesModel model;
62
    private Map<String,List<URL>> newContents;
63
    Map<String,List<URL>> newContents;
63
    private String newName;
64
    private String newName;
64
    private String newDescription;
65
    private String newDescription;
65
    private PropertyChangeSupport support;
66
    private PropertyChangeSupport support;
66
67
67
    /** Creates a new instance of ProxyLibraryImplementation */
68
    public ProxyLibraryImplementation (LibraryImplementation original, LibrariesModel model) {
68
    public ProxyLibraryImplementation (LibraryImplementation original, LibrariesModel model) {
69
        assert original != null && model != null;
69
        assert original != null && model != null;
70
        this.original = original;
70
        this.original = original;
Lines 167-174 Link Here
167
            return false;
167
            return false;
168
    }
168
    }
169
169
170
    public final String toString() {
170
    public @Override String toString() {
171
        return "Proxy for: " + this.original.toString();    //NOI18N
171
        return "Proxy[" + original + "]"; // NOI18N
172
    }
172
    }
173
173
174
}
174
}
(-)/dev/null (+124 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.spi.project.libraries;
21
22
import java.beans.PropertyChangeListener;
23
import java.io.IOException;
24
import java.net.URL;
25
import java.util.List;
26
import java.util.Map;
27
import java.util.Set;
28
29
/**
30
 * Library provider which can define libraries in particular areas.
31
 * There is no explicit method to save a library; setters on {@link LibraryImplementation} should do this.
32
 * @param A the type of storage area used by this provider
33
 * @param L the type of library created by this provider
34
 * @since org.netbeans.modules.project.libraries/1 1.15
35
 */
36
public interface ArealLibraryProvider<A extends LibraryStorageArea, L extends LibraryImplementation> {
37
38
    /**
39
     * Property to fire when {@link #getOpenAreas} might have changed.
40
     */
41
    String PROP_OPEN_AREAS = "openAreas"; // NOI18N
42
43
    /**
44
     * Adds a listener to {@link #PROP_OPEN_AREAS}.
45
     * @param listener a listener to add
46
     */
47
    void addPropertyChangeListener(PropertyChangeListener listener);
48
49
    /**
50
     * Removes a listener to {@link #PROP_OPEN_AREAS}.
51
     * @param listener a listener to remove
52
     */
53
    void removePropertyChangeListener(PropertyChangeListener listener);
54
55
    /**
56
     * Gets the runtime type of the area used by this provider.
57
     * @return the area type
58
     */
59
    Class<A> areaType();
60
61
    /**
62
     * Gets the runtime type of the libraries created by this provider.
63
     * @return the library type
64
     */
65
    Class<L> libraryType();
66
67
    /**
68
     * Creates or otherwise picks a storage area interactively.
69
     * This might actually create a fresh area, or just load an existing one,
70
     * or even do nothing (and return null).
71
     * The implementor is free to show a dialog here.
72
     * @return a new or existing storage area, or null
73
     */
74
    A createArea();
75
76
    /**
77
     * Loads a storage area (which may or may exist yet).
78
     * @param location an abstract storage location which may or may not be recognized by this provider
79
     * @return an area whose {@link LibraryStorageArea#getLocation} matches the provided location,
80
     *         or null if this type of location is not recognized by this provider
81
     */
82
    A loadArea(URL location);
83
84
    /**
85
     * Looks for areas which should be somehow listed as open.
86
     * For example, a provider which refers to library areas from project metadata
87
     * could list all areas referred to from currently open projects.
88
     * It is <em>not</em> necessary to include areas recently mentioned e.g. by {@link #createArea}.
89
     * @return a (possibly empty) collection of areas
90
     */
91
    Set<A> getOpenAreas();
92
93
    /**
94
     * Gets all libraries defined in a given area.
95
     * No two libraries in this area may share a given name (as in {@link LibraryImplementation#getName},
96
     * though it is permitted for libraries from different areas to have the same name.
97
     * Changes in the set of libraries defined in this area should be fired through {@link LibraryProvider#PROP_LIBRARIES}.
98
     * Since {@link IOException} is not thrown either from this method or from {@link LibraryProvider#getLibraries},
99
     * it is expected that any problems loading library definitions will be logged and that those libraries will be skipped.
100
     * @param area some storage area (which might not even exist yet, in which case the set of libraries will initially be empty)
101
     * @return a listenable set of libraries in this area
102
     *         (it is permitted to return distinct objects from call to call on the same area,
103
     *         i.e. no caching by the implementation is necessary)
104
     */
105
    LibraryProvider<L> getLibraries(A area);
106
107
    /**
108
     * Creates a new library.
109
     * @param type the kind of library to make, as in {@link LibraryTypeProvider#getLibraryType} or {@link LibraryImplementation#getType}
110
     * @param name the library name, as in {@link LibraryImplementation#getName}
111
     * @param area the location to define the library
112
     * @param contents initial volume contents (keys must be contained in the appropriate {@link LibraryTypeProvider#getSupportedVolumeTypes})
113
     * @return a new library with matching type, name, area, and contents
114
     * @throws IOException if an error occurs creating the library definition     */
115
    L createLibrary(String type, String name, A area, Map<String,List<URL>> contents) throws IOException;
116
117
    /**
118
     * Deletes an existing library.
119
     * @param library a library produced by this provider
120
     * @throws IOException if a problem can encountered deleting the library definition
121
     */
122
    void remove(L library) throws IOException;
123
124
}
(-)projects/libraries/src/org/netbeans/spi/project/libraries/LibraryFactory.java:1.2 (-2 / +1 lines)
Lines 58-68 Link Here
58
    private LibraryFactory() {
58
    private LibraryFactory() {
59
    }
59
    }
60
    
60
    
61
    
62
    /**
61
    /**
63
     * Creates Library for LibraryImplementation
62
     * Creates Library for LibraryImplementation
64
     * @param libraryImplementation the library SPI object
63
     * @param libraryImplementation the library SPI object
65
     * @return Library API instance
64
     * @return Library API instance, for which the {@link Library#getManager} will be {@link LibraryManager#getDefault}
66
     */
65
     */
67
    public static Library createLibrary (LibraryImplementation libraryImplementation) {
66
    public static Library createLibrary (LibraryImplementation libraryImplementation) {
68
        assert libraryImplementation != null;
67
        assert libraryImplementation != null;
(-)projects/libraries/src/org/netbeans/spi/project/libraries/LibraryProvider.java:1.6 (-6 / +9 lines)
Lines 38-43 Link Here
38
 * Version 2 license, then the option applies only if the new code is
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
39
 * made subject to such option by the copyright holder.
40
 */
40
 */
41
41
package org.netbeans.spi.project.libraries;
42
package org.netbeans.spi.project.libraries;
42
43
43
import java.beans.PropertyChangeListener;
44
import java.beans.PropertyChangeListener;
Lines 47-75 Link Here
47
 * Library storage is a source of libraries used by LibraryManager.
48
 * Library storage is a source of libraries used by LibraryManager.
48
 * LibraryManager allows existence of multiple LibraryProviders registered in
49
 * LibraryManager allows existence of multiple LibraryProviders registered in
49
 * the default lookup.
50
 * the default lookup.
51
 * @param L the type of implementation which will be produced by this provider
50
 */
52
 */
51
public interface LibraryProvider {
53
public interface LibraryProvider<L extends LibraryImplementation> {
52
54
53
    /**
55
    /**
54
     * Name of libraries property
56
     * Name of libraries property
55
     */
57
     */
56
    public static final String PROP_LIBRARIES = "libraries";        //NOI18N
58
    String PROP_LIBRARIES = "libraries"; // NOI18N
57
59
58
    /**
60
    /**
59
     * Returns libraries provided by the implemented provider.
61
     * Returns libraries provided by the implemented provider.
60
     * @return LibraryImplementation[] never return null, may return empty array.
62
     * @return (possibly empty but not null) list of libraries
61
     */
63
     */
62
    public LibraryImplementation[] getLibraries();
64
    L[] getLibraries();
63
65
64
    /**
66
    /**
65
     * Adds property change listener, the listener is notified when the libraries changed
67
     * Adds property change listener, the listener is notified when the libraries changed
66
     * @param listener
68
     * @param listener
67
     */
69
     */
68
    public void addPropertyChangeListener (PropertyChangeListener listener);
70
    void addPropertyChangeListener (PropertyChangeListener listener);
69
71
70
    /**
72
    /**
71
     * Removes property change listener
73
     * Removes property change listener
72
     * @param listener
74
     * @param listener
73
     */
75
     */
74
    public void removePropertyChangeListener (PropertyChangeListener listener);
76
    void removePropertyChangeListener (PropertyChangeListener listener);
77
75
}
78
}
(-)/dev/null (+46 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 * 
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 * 
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 * 
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.spi.project.libraries;
21
22
import java.net.URL;
23
24
/**
25
 * Abstract location where zero or more libraries are defined.
26
 * {@link Object#equals} and {@link Object#hashCode} are expected to be defined
27
 * such that object identity (within the implementing class) are driven by {@link #getLocation}.
28
 * @see ArealLibraryProvider
29
 * @since org.netbeans.modules.project.libraries/1 1.15
30
 */
31
public interface LibraryStorageArea {
32
33
    /**
34
     * Gets an associated storage location.
35
     * The contents of the URL (if it is even accessible) are unspecified.
36
     * @return an associated URL uniquely identifying this location
37
     */
38
    URL getLocation();
39
40
    /**
41
     * Gets a human-readable display label for this area.
42
     * @return a localized display name
43
     */
44
    String getDisplayName();
45
46
}
(-)projects/libraries/src/org/netbeans/spi/project/libraries/LibraryTypeProvider.java:1.8 (-2 / +5 lines)
Lines 75-80 Link Here
75
75
76
    /**
76
    /**
77
     * Creates a new empty library implementation.
77
     * Creates a new empty library implementation.
78
     * Generally will use {@link LibrariesSupport#createLibraryImplementation}.
79
     * This method is <strong>not</strong> used by {@link LibraryManager#createLibrary} except in the case of {@link LibraryManager#getDefault}.
78
     * @return the created library model, never null
80
     * @return the created library model, never null
79
     */
81
     */
80
    public LibraryImplementation createLibrary ();
82
    public LibraryImplementation createLibrary ();
Lines 85-90 Link Here
85
     * If the LibraryTypeProvider implementation requires clean of
87
     * If the LibraryTypeProvider implementation requires clean of
86
     * additional settings (e.g. remove properties in the build.properties)
88
     * additional settings (e.g. remove properties in the build.properties)
87
     * it should be done in this method.
89
     * it should be done in this method.
90
     * This method is <strong>not</strong> used by {@link LibraryManager#createLibrary} except in the case of {@link LibraryManager#getDefault}.
88
     * @param libraryImpl
91
     * @param libraryImpl
89
     */
92
     */
90
    public void libraryDeleted (LibraryImplementation libraryImpl);
93
    public void libraryDeleted (LibraryImplementation libraryImpl);
Lines 96-108 Link Here
96
     * If the LibraryTypeProvider implementation requires initialization of
99
     * If the LibraryTypeProvider implementation requires initialization of
97
     * additional settings (e.g. adding properties into the build.properties)
100
     * additional settings (e.g. adding properties into the build.properties)
98
     * it should be done in this method.
101
     * it should be done in this method.
99
     *
102
     * This method is <strong>not</strong> used by {@link LibraryManager#createLibrary} except in the case of {@link LibraryManager#getDefault}.
100
     */
103
     */
101
    public void libraryCreated (LibraryImplementation libraryImpl);
104
    public void libraryCreated (LibraryImplementation libraryImpl);
102
105
103
    /**
106
    /**
104
     * Returns customizer for given volume's type, or null if the volume is not customizable.
107
     * Returns customizer for given volume's type, or null if the volume is not customizable.
105
     * The object of the LibraryImplementation type is
108
     * The object of the LibraryImplementation type and optionally LibraryStorageArea type is
106
     * passed to the customizer's setObject method.
109
     * passed to the customizer's setObject method.
107
     * The customized object describes the library created by this
110
     * The customized object describes the library created by this
108
     * provider, but the customizer cannot assume that the customized
111
     * provider, but the customizer cannot assume that the customized
(-)projects/libraries/src/org/netbeans/spi/project/libraries/support/LibrariesSupport.java:1.5 (+135 lines)
Lines 40-49 Link Here
40
 */
40
 */
41
package org.netbeans.spi.project.libraries.support;
41
package org.netbeans.spi.project.libraries.support;
42
42
43
import java.io.File;
44
import java.net.MalformedURLException;
45
import java.net.URI;
46
import java.net.URISyntaxException;
47
import java.net.URL;
43
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
48
import org.netbeans.modules.project.libraries.LibraryTypeRegistry;
44
import org.netbeans.spi.project.libraries.LibraryImplementation;
49
import org.netbeans.spi.project.libraries.LibraryImplementation;
45
import org.netbeans.modules.project.libraries.DefaultLibraryImplementation;
50
import org.netbeans.modules.project.libraries.DefaultLibraryImplementation;
46
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
51
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
52
import org.openide.filesystems.FileObject;
53
import org.openide.filesystems.FileUtil;
54
import org.openide.filesystems.URLMapper;
55
import org.openide.util.Parameters;
47
56
48
/**
57
/**
49
 * SPI Support class.
58
 * SPI Support class.
Lines 85-88 Link Here
85
    public static LibraryTypeProvider[] getLibraryTypeProviders () {
94
    public static LibraryTypeProvider[] getLibraryTypeProviders () {
86
        return LibraryTypeRegistry.getDefault().getLibraryTypeProviders();
95
        return LibraryTypeRegistry.getDefault().getLibraryTypeProviders();
87
    }
96
    }
97
    
98
    /**
99
     * Properly converts possibly relative file to URL.
100
     * @param f file to convert; can be relative; cannot be null
101
     * @return url
102
     */
103
    public static URL convertFileToURL(File f) {
104
        try {
105
            if (f.isAbsolute()) {
106
                return f.toURI().toURL();
107
            } else {
108
                // create hierarchical relative URI (that is no schema)
109
                // to encode OS characters
110
                URI uri = new URI(null, null, f.getPath().replace('\\', '/'), null);
111
                return new URL("file", null, uri.getRawPath());
112
            }
113
114
        } catch (URISyntaxException ex) {
115
	    IllegalArgumentException y = new IllegalArgumentException();
116
	    y.initCause(ex);
117
	    throw y;
118
        } catch (MalformedURLException ex) {
119
	    IllegalArgumentException y = new IllegalArgumentException();
120
	    y.initCause(ex);
121
	    throw y;
122
        }
123
    }
124
    
125
    /**
126
     * Properly converts possibly relative URL to file.
127
     * @param url file URL to convert; can be relative; cannot be null
128
     * @return url
129
     */
130
    public static File convertURLToFile(URL url) {
131
        if (!"file".equals(url.getProtocol())) {
132
            throw new IllegalArgumentException("not file URL "+url); //NOI18N
133
        }
134
        try {
135
            if (isAbsoluteURL(url)) {
136
                return new File(new URI(url.toExternalForm()));
137
            } else {
138
                // workaround to decode URL path - created fake absolute URI 
139
                // just to construct File instance and properly decoded path:
140
                URI uri3 = new URI("file:/"+url.getPath());
141
                return new File(new File(uri3).getPath().substring(1));
142
            }
143
        } catch (URISyntaxException ex) {
144
	    IllegalArgumentException y = new IllegalArgumentException();
145
	    y.initCause(ex);
146
	    throw y;
147
        }
148
    }
149
150
    /**
151
     * Is given URL absolute?
152
     * 
153
     * @param url url to test; cannot be null
154
     * @return is absolute
155
     */
156
    public static boolean isAbsoluteURL(URL url) {
157
        if ("jar".equals(url.getProtocol())) { // NOI18N
158
            url = FileUtil.getArchiveFile(url);
159
        }
160
        return url.getPath().startsWith("/");
161
    }
162
    
163
    /**
164
     * Helper method to resolve (possibly relative) library content URL to FileObject.
165
     * 
166
     * @param libraryLocation library location file; can be null for global libraries
167
     * @param libraryEntry library entry to resolve
168
     * @return file object
169
     */
170
    public static FileObject resolveLibraryEntryFileObject(URL libraryLocation, URL libraryEntry) {
171
        URL u = resolveLibraryEntryURL(libraryLocation, libraryEntry);
172
        return URLMapper.findFileObject(u);
173
    }
174
    
175
    /**
176
     * Helper method to resolve (possibly relative) library content URL.
177
     * 
178
     * @param libraryLocation library location file; can be null for global libraries
179
     * @param libraryEntry library entry to resolve
180
     * @return absolute URL
181
     */
182
    public static URL resolveLibraryEntryURL(URL libraryLocation, URL libraryEntry) {
183
        Parameters.notNull("libraryEntry", libraryEntry); //NOI18N
184
        if (isAbsoluteURL(libraryEntry)) {
185
            return libraryEntry;
186
        } else {
187
            if (libraryLocation == null) {
188
                throw new IllegalArgumentException("cannot resolve relative URL without library location"); //NOI18N
189
            }
190
            if (!"file".equals(libraryLocation.getProtocol())) { //NOI18N
191
                throw new IllegalArgumentException("not file: protocol - "+libraryLocation.toExternalForm()); //NOI18N
192
            }
193
            File libLocation = new File(URI.create(libraryLocation.toExternalForm()));
194
            if (!libLocation.getName().endsWith(".properties")) { //NOI18N
195
                throw new IllegalArgumentException("library location must be a file - "+libraryLocation.toExternalForm()); //NOI18N
196
            }
197
            File libBase = libLocation.getParentFile();
198
            boolean archiveURL = false;
199
            if ("jar".equals(libraryEntry.getProtocol())) {
200
                libraryEntry = FileUtil.getArchiveFile(libraryEntry);
201
                archiveURL = true;
202
            }
203
            File f = convertURLToFile(libraryEntry);
204
            f = FileUtil.normalizeFile(new File(libBase, f.getPath()));
205
            URL u;
206
            try {
207
                u = f.toURI().toURL();
208
            } catch (MalformedURLException ex) {
209
                IllegalArgumentException y = new IllegalArgumentException();
210
                y.initCause(ex);
211
                throw y;
212
            }
213
            if (archiveURL) {
214
                u = FileUtil.getArchiveRoot(u);
215
            }
216
            return u;
217
        }
218
    }
219
220
    // TODO: add method which compares two libraries: compare content and file sizes and ...
221
    
222
    // TODO: move some of these methods to openide.FileUtil
88
}
223
}
(-)projects/libraries/test/.cvsignore:1.1 (-1 / +2 lines)
Lines 1-3 Link Here
1
coverage
1
lib
2
lib
2
work
3
results
3
results
4
work
(-)projects/libraries/test/unit/src/org/netbeans/api/project/libraries/LibraryManagerTest.java:1.8 (-195 / +87 lines)
Lines 41-64 Link Here
41
41
42
package org.netbeans.api.project.libraries;
42
package org.netbeans.api.project.libraries;
43
43
44
import java.beans.PropertyChangeEvent;
44
import static org.netbeans.modules.project.libraries.TestUtil.*;
45
import java.beans.PropertyChangeListener;
46
import java.beans.PropertyChangeSupport;
47
import java.io.IOException;
48
import java.net.MalformedURLException;
45
import java.net.MalformedURLException;
49
import java.net.URL;
46
import java.net.URL;
50
import java.util.ArrayList;
47
import java.util.ArrayList;
51
import java.util.Arrays;
48
import java.util.Arrays;
52
import java.util.Collections;
49
import java.util.Collections;
53
import java.util.HashMap;
54
import java.util.HashSet;
55
import java.util.List;
50
import java.util.List;
56
import java.util.Map;
57
import java.util.Set;
58
import java.util.StringTokenizer;
51
import java.util.StringTokenizer;
59
import org.netbeans.api.project.TestUtil;
60
import org.netbeans.junit.NbTestCase;
52
import org.netbeans.junit.NbTestCase;
61
import org.netbeans.modules.project.libraries.WritableLibraryProvider;
53
import org.netbeans.modules.project.libraries.ui.LibrariesModel;
62
import org.netbeans.spi.project.libraries.LibraryFactory;
54
import org.netbeans.spi.project.libraries.LibraryFactory;
63
import org.netbeans.spi.project.libraries.LibraryImplementation;
55
import org.netbeans.spi.project.libraries.LibraryImplementation;
64
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
56
import org.netbeans.spi.project.libraries.LibraryTypeProvider;
Lines 68-104 Link Here
68
import org.openide.loaders.DataFolder;
60
import org.openide.loaders.DataFolder;
69
import org.openide.loaders.InstanceDataObject;
61
import org.openide.loaders.InstanceDataObject;
70
import org.openide.util.lookup.Lookups;
62
import org.openide.util.lookup.Lookups;
71
import org.openide.util.lookup.Lookups;
63
import org.openide.util.test.MockLookup;
72
/**
64
import org.openide.util.test.MockPropertyChangeListener;
73
 *
65
74
 * @author  Tomas Zezula
75
 */
76
public class LibraryManagerTest extends NbTestCase {
66
public class LibraryManagerTest extends NbTestCase {
77
    
67
78
    private TestLibraryProvider lp;
68
    private WLP lp;
79
    
69
80
    private static final String LIBRARY_TYPE = "j2se";  //NOI18N
70
    private static final String LIBRARY_TYPE = "j2se";  //NOI18N
81
    private static final String[] VOLUME_TYPES = new String[] {
71
    private static final String[] VOLUME_TYPES = new String[] {
82
        "bin",
72
        "bin",
83
        "src",
73
        "src",
84
        "doc"
74
        "doc"
85
    };
75
    };
86
    
76
87
    /** Creates a new instance of LibraryManagerTest */
88
    public LibraryManagerTest (String testName) {
77
    public LibraryManagerTest (String testName) {
89
        super (testName);
78
        super (testName);
90
    }
79
    }
91
    
80
92
    protected void setUp() throws Exception {
81
    protected void setUp() throws Exception {
93
        super.setUp();
82
        super.setUp();
94
        lp = new TestLibraryProvider ();
83
        lp = new WLP();
95
        TestUtil.setLookup (Lookups.fixed(new Object[] {
84
        MockLookup.setLookup(Lookups.singleton(lp));
96
            lp
97
        }));
98
        registerLibraryTypeProvider();
85
        registerLibraryTypeProvider();
99
    }
86
    }
100
    
87
101
    
102
    private static void registerLibraryTypeProvider () throws Exception {
88
    private static void registerLibraryTypeProvider () throws Exception {
103
        StringTokenizer tk = new StringTokenizer("org-netbeans-api-project-libraries/LibraryTypeProviders","/");
89
        StringTokenizer tk = new StringTokenizer("org-netbeans-api-project-libraries/LibraryTypeProviders","/");
104
        FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
90
        FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
Lines 114-143 Link Here
114
            InstanceDataObject.create (DataFolder.findFolder(root),"TestLibraryTypeProvider",TestLibraryTypeProvider.class);
100
            InstanceDataObject.create (DataFolder.findFolder(root),"TestLibraryTypeProvider",TestLibraryTypeProvider.class);
115
        }
101
        }
116
    }
102
    }
117
    
103
118
    public void testGetLibraries () throws Exception {        
104
    public void testGetLibraries () throws Exception {
119
        LibraryManager lm = LibraryManager.getDefault();
105
        LibraryManager lm = LibraryManager.getDefault();
120
        TestListener tl = new TestListener ();
106
        MockPropertyChangeListener pcl = new MockPropertyChangeListener();
121
        lm.addPropertyChangeListener(tl);
107
        lm.addPropertyChangeListener(pcl);
122
        Library[] libs = lm.getLibraries();
108
        Library[] libs = lm.getLibraries();
123
        assertEquals ("Libraries count", 0, libs.length);
109
        assertEquals ("Libraries count", 0, libs.length);
124
        LibraryImplementation[] impls = createTestLibs ();
110
        LibraryImplementation[] impls = createTestLibs ();
125
        lp.setLibraries(impls);        
111
        lp.set(impls);
126
        libs = lm.getLibraries();
112
        libs = lm.getLibraries();
127
        assertEventsEquals(tl.getEventNames(), new String[] {LibraryManager.PROP_LIBRARIES});
113
        pcl.assertEvents(LibraryManager.PROP_LIBRARIES);
128
        tl.reset();
129
        assertEquals ("Libraries count", 2, libs.length);
114
        assertEquals ("Libraries count", 2, libs.length);
130
        assertLibsEquals (libs, impls);
115
        assertLibsEquals (libs, impls);
131
        lp.setLibraries(new LibraryImplementation[0]);        
116
        lp.set();
132
        assertEventsEquals(tl.getEventNames(), new String[] {LibraryManager.PROP_LIBRARIES});
117
        pcl.assertEvents(LibraryManager.PROP_LIBRARIES);
133
        tl.reset();
134
        libs = lm.getLibraries();
118
        libs = lm.getLibraries();
135
        assertEquals ("Libraries count", 0, libs.length);
119
        assertEquals ("Libraries count", 0, libs.length);
136
    }
120
    }
137
    
121
138
    public void testGetLibrary () throws Exception {
122
    public void testGetLibrary () throws Exception {
139
        LibraryImplementation[] impls = createTestLibs ();
123
        LibraryImplementation[] impls = createTestLibs ();
140
        lp.setLibraries(impls);        
124
        lp.set(impls);
141
        LibraryManager lm = LibraryManager.getDefault();
125
        LibraryManager lm = LibraryManager.getDefault();
142
        Library[] libs = lm.getLibraries();
126
        Library[] libs = lm.getLibraries();
143
        assertEquals ("Libraries count", 2, libs.length);
127
        assertEquals ("Libraries count", 2, libs.length);
Lines 151-160 Link Here
151
        lib = lm.getLibrary("Library3");
135
        lib = lm.getLibrary("Library3");
152
        assertNull ("Nonexisting library", lib);
136
        assertNull ("Nonexisting library", lib);
153
    }
137
    }
154
    
138
139
    @SuppressWarnings("deprecation")
155
    public void testAddRemoveLibrary () throws Exception {
140
    public void testAddRemoveLibrary () throws Exception {
156
        final LibraryImplementation[] impls = createTestLibs();
141
        final LibraryImplementation[] impls = createTestLibs();
157
        lp.setLibraries(impls);
142
        lp.set(impls);
158
        final LibraryManager lm = LibraryManager.getDefault();
143
        final LibraryManager lm = LibraryManager.getDefault();
159
        Library[] libs = lm.getLibraries();
144
        Library[] libs = lm.getLibraries();
160
        assertEquals ("Libraries count", 2, libs.length);
145
        assertEquals ("Libraries count", 2, libs.length);
Lines 175-185 Link Here
175
        assertEquals("Libraries count",2,libs.length);
160
        assertEquals("Libraries count",2,libs.length);
176
        assertLibsEquals (libs, impls);
161
        assertLibsEquals (libs, impls);
177
    }
162
    }
178
    
163
164
    public void testCreateRemoveLibrary() throws Exception {
165
        LibraryManager mgr = LibraryManager.getDefault();
166
        URL fooJar = mkJar("foo.jar");
167
        Library lib = mgr.createLibrary(LIBRARY_TYPE, "NewLib", Collections.singletonMap("bin", Arrays.asList(fooJar)));
168
        assertEquals(mgr, lib.getManager());
169
        assertEquals(Collections.singletonList(lib), Arrays.asList(mgr.getLibraries()));
170
        assertEquals(1, lp.libs.size());
171
        assertLibsEquals(new Library[] {lib}, lp.libs.toArray(new LibraryImplementation[1]));
172
        mgr.removeLibrary(lib);
173
        assertEquals(Collections.emptyList(), Arrays.asList(mgr.getLibraries()));
174
        assertEquals(0, lp.libs.size());
175
    }
176
177
    public void testArealLibraryManagers() throws Exception {
178
        ALP alp = new ALP();
179
        MockLookup.setLookup(Lookups.fixed(lp, alp));
180
        new LibrariesModel().createArea();
181
        Area home = new Area("home");
182
        Area away = new Area("away");
183
        alp.setOpen(home, away);
184
        List<String> locations = new ArrayList<String>(); // use list, not set, to confirm size also
185
        for (LibraryManager mgr : LibraryManager.getOpenManagers()) {
186
            URL loc = mgr.getLocation();
187
            locations.add(loc != null ? loc.toString() : "<none>");
188
        }
189
        Collections.sort(locations);
190
        assertEquals("[<none>, http://nowhere.net/away, http://nowhere.net/home, http://nowhere.net/new]", locations.toString());
191
        alp.setOpen();
192
        try {
193
            LibraryManager.forLocation(new URL("http://even-less-anywhere.net/"));
194
            fail();
195
        } catch (IllegalArgumentException x) {}
196
        LibraryManager mgr = LibraryManager.forLocation(home.getLocation());
197
        assertEquals(home.getLocation(), mgr.getLocation());
198
        assertEquals("home", mgr.getDisplayName());
199
        assertEquals(0, mgr.getLibraries().length);
200
        MockPropertyChangeListener pcl = new MockPropertyChangeListener();
201
        mgr.addPropertyChangeListener(pcl);
202
        URL fooJar = mkJar("foo.jar");
203
        Library lib = mgr.createLibrary(LIBRARY_TYPE, "NewLib", Collections.singletonMap("bin", Arrays.asList(fooJar)));
204
        assertEquals(mgr, lib.getManager());
205
        pcl.assertEvents(LibraryManager.PROP_LIBRARIES);
206
        assertEquals(Collections.singletonList(lib), Arrays.asList(mgr.getLibraries()));
207
        assertEquals(1, alp.libs.get(home).size());
208
        LibraryImplementation impl = alp.libs.get(home).iterator().next();
209
        assertEquals("NewLib", impl.getName());
210
        assertEquals(LIBRARY_TYPE, impl.getType());
211
        assertEquals(Arrays.asList(fooJar), impl.getContent("bin"));
212
        mgr.removeLibrary(lib);
213
        pcl.assertEvents(LibraryManager.PROP_LIBRARIES);
214
        assertEquals(Collections.emptyList(), Arrays.asList(mgr.getLibraries()));
215
        assertEquals(0, alp.libs.get(home).size());
216
    }
217
179
    static LibraryImplementation[] createTestLibs () throws MalformedURLException {
218
    static LibraryImplementation[] createTestLibs () throws MalformedURLException {
180
        LibraryImplementation[] impls = new LibraryImplementation[] {
219
        LibraryImplementation[] impls = {
181
            new TestLibraryImplementation (),
220
            LibrariesSupport.createLibraryImplementation(LIBRARY_TYPE, VOLUME_TYPES),
182
            new TestLibraryImplementation ()
221
            LibrariesSupport.createLibraryImplementation(LIBRARY_TYPE, VOLUME_TYPES),
183
        };
222
        };
184
        impls[0].setName ("Library1");
223
        impls[0].setName ("Library1");
185
        impls[1].setName ("Library2");
224
        impls[1].setName ("Library2");
Lines 189-195 Link Here
189
        impls[1].setContent("bin", Collections.singletonList(new URL("file:/lib/libest2.so")));
228
        impls[1].setContent("bin", Collections.singletonList(new URL("file:/lib/libest2.so")));
190
        return impls;
229
        return impls;
191
    }
230
    }
192
    
231
193
    static void assertLibsEquals (Library[] libs, LibraryImplementation[] impls) {
232
    static void assertLibsEquals (Library[] libs, LibraryImplementation[] impls) {
194
        assertEquals ("libs equals (size)", impls.length, libs.length);
233
        assertEquals ("libs equals (size)", impls.length, libs.length);
195
        for (int i=0; i< libs.length; i++) {
234
        for (int i=0; i< libs.length; i++) {
Lines 206-282 Link Here
206
            assertEquals ("libs equals (content doc)", ic, lc);
245
            assertEquals ("libs equals (content doc)", ic, lc);
207
        }
246
        }
208
    }
247
    }
209
    
248
210
    static void assertEventsEquals (List eventNames, String[] expectedName) {
211
        assertEquals ("Events equals", Arrays.asList(expectedName), eventNames);
212
    }
213
    
214
    
215
    static class TestLibraryProvider implements WritableLibraryProvider  {
216
        
217
        private PropertyChangeSupport support;
218
        private List<LibraryImplementation> libraries;
219
        
220
        public TestLibraryProvider () {
221
            this.support = new PropertyChangeSupport (this);
222
            this.libraries = new ArrayList<LibraryImplementation>();
223
        }
224
        
225
        public void removePropertyChangeListener(PropertyChangeListener listener) {
226
            this.support.removePropertyChangeListener(listener);
227
        }
228
229
        public void addPropertyChangeListener(PropertyChangeListener listener) {
230
            this.support.addPropertyChangeListener(listener);
231
        }
232
233
        public LibraryImplementation[] getLibraries() {
234
            return this.libraries.toArray(new LibraryImplementation[libraries.size()]);
235
        }                
236
        
237
        public void setLibraries (LibraryImplementation[] libraries) {
238
            this.libraries = new ArrayList<LibraryImplementation>(Arrays.asList(libraries));
239
            this.support.firePropertyChange(PROP_LIBRARIES,null,null);
240
        }
241
242
        public void addLibrary(LibraryImplementation library) throws IOException {
243
            this.libraries.add (library);
244
            this.support.firePropertyChange(PROP_LIBRARIES,null,null);
245
        }
246
247
        public void removeLibrary(LibraryImplementation library) throws IOException {
248
            this.libraries.remove (library);
249
            this.support.firePropertyChange(PROP_LIBRARIES,null,null);
250
        }
251
252
        public void updateLibrary(LibraryImplementation oldLibrary, LibraryImplementation newLibrary) throws IOException {
253
            this.libraries.remove(oldLibrary);
254
            this.libraries.add (newLibrary);
255
            this.support.firePropertyChange(PROP_LIBRARIES,null,null);
256
        }
257
        
258
    }
259
    
260
    static class TestListener implements PropertyChangeListener {
261
        
262
        private List<String> events = new ArrayList<String>();
263
        
264
        public void propertyChange(PropertyChangeEvent event) {
265
            this.events.add(event.getPropertyName());
266
        }                
267
        
268
        public void reset () {
269
            this.events.clear();
270
        }
271
        
272
        public List getEventNames () {
273
            return this.events;
274
        }
275
    }
276
    
277
    
278
    public static class TestLibraryTypeProvider implements LibraryTypeProvider {
249
    public static class TestLibraryTypeProvider implements LibraryTypeProvider {
279
            
250
280
251
281
        public String getDisplayName() {
252
        public String getDisplayName() {
282
            return LIBRARY_TYPE;
253
            return LIBRARY_TYPE;
Lines 308-391 Link Here
308
            return null;
279
            return null;
309
        }
280
        }
310
    }
281
    }
311
    
312
    static class TestLibraryImplementation implements LibraryImplementation {
313
        
314
        private static final Set<String> supportedTypes;
315
        
316
        private String name;
317
        private String description;        
318
        private Map<String,List<URL>> contents;
319
        private PropertyChangeSupport support;
320
        
321
        static {            
322
            supportedTypes = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(VOLUME_TYPES)));
323
        }
324
        
325
        public TestLibraryImplementation () {
326
            this.contents = new HashMap<String,List<URL>>();
327
            this.support = new PropertyChangeSupport (this);
328
        }
329
        
330
        public String getType() {
331
            return LIBRARY_TYPE;
332
        }
333
        
334
        public String getName() {
335
            return this.name;
336
        }
337
        
338
        public void setName(String name) {
339
            this.name = name;
340
            this.support.firePropertyChange(PROP_NAME, null, null);
341
        }
342
343
        public String getLocalizingBundle() {
344
            return null;
345
        }
346
        
347
        public void setLocalizingBundle(String resourceName) {  
348
        }
349
        
350
        public String getDescription() {
351
            return this.description;
352
        }
353
354
        public void setDescription(String text) {
355
            this.description = text;
356
            this.support.firePropertyChange(PROP_DESCRIPTION, null, null);
357
        }
358
359
        public List<URL> getContent(String volumeType) throws IllegalArgumentException {
360
            if (supportedTypes.contains(volumeType)) {
361
                List<URL> l = contents.get(volumeType);
362
                if (l == null) {
363
                    l = Collections.emptyList();
364
                }
365
                return Collections.unmodifiableList(l);
366
            }
367
            else {
368
                throw new IllegalArgumentException ();
369
            }
370
        }
371
        
372
        public void setContent(String volumeType, List<URL> path) throws IllegalArgumentException {
373
            if (supportedTypes.contains(volumeType)) {
374
                this.contents.put (volumeType, path);
375
                this.support.firePropertyChange(PROP_CONTENT, null, null);
376
            }
377
            else {
378
                throw new IllegalArgumentException ();
379
            }
380
        }
381
382
        public void removePropertyChangeListener(PropertyChangeListener l) {
383
            this.support.removePropertyChangeListener(l);
384
        }
385
282
386
        public void addPropertyChangeListener(PropertyChangeListener l) {
387
            this.support.addPropertyChangeListener(l);
388
        }              
389
    }
390
    
391
}
283
}
(-)projects/libraries/test/unit/src/org/netbeans/api/project/libraries/LibraryTest.java:1.5 (-21 / +14 lines)
Lines 41-104 Link Here
41
41
42
package org.netbeans.api.project.libraries;
42
package org.netbeans.api.project.libraries;
43
43
44
import static org.netbeans.modules.project.libraries.TestUtil.*;
44
import java.net.URL;
45
import java.net.URL;
45
import java.util.ArrayList;
46
import java.util.ArrayList;
46
import java.util.List;
47
import java.util.List;
47
import org.netbeans.api.project.TestUtil;
48
import org.netbeans.junit.NbTestCase;
48
import org.netbeans.junit.NbTestCase;
49
import org.netbeans.spi.project.libraries.LibraryImplementation;
49
import org.netbeans.spi.project.libraries.LibraryImplementation;
50
import org.netbeans.spi.project.libraries.LibraryProvider;
51
import org.openide.util.lookup.Lookups;
50
import org.openide.util.lookup.Lookups;
52
/**
51
import org.openide.util.test.MockLookup;
53
 *
52
import org.openide.util.test.MockPropertyChangeListener;
54
 * @author  Tomas Zezula
53
55
 */
56
public class LibraryTest extends NbTestCase {
54
public class LibraryTest extends NbTestCase {
57
55
58
    private LibraryManagerTest.TestLibraryProvider lp;
56
    private WLP lp;
59
57
60
    /** Creates a new instance of LibraryManagerTest */
61
    public LibraryTest (String testName) {
58
    public LibraryTest (String testName) {
62
        super (testName);
59
        super (testName);
63
    }
60
    }
64
    
61
    
65
    protected void setUp() throws Exception {
62
    protected void setUp() throws Exception {
66
        super.setUp();
63
        super.setUp();
67
        lp = new LibraryManagerTest.TestLibraryProvider ();
64
        lp = new WLP();
68
        TestUtil.setLookup (Lookups.fixed(new Object[] {lp}));
65
        MockLookup.setLookup(Lookups.singleton(lp));
69
    }
66
    }
70
    
67
    
71
    public void testGetLibraries () throws Exception {        
68
    public void testGetLibraries () throws Exception {        
72
        LibraryManager lm = LibraryManager.getDefault();
69
        LibraryManager lm = LibraryManager.getDefault();
73
        Library[] libs = lm.getLibraries();
70
        Library[] libs = lm.getLibraries();
74
        LibraryImplementation[] impls = LibraryManagerTest.createTestLibs ();
71
        LibraryImplementation[] impls = LibraryManagerTest.createTestLibs ();
75
        lp.setLibraries(impls);        
72
        lp.set(impls);
76
        libs = lm.getLibraries();
73
        libs = lm.getLibraries();
77
        assertEquals ("Libraries count", 2, libs.length);
74
        assertEquals ("Libraries count", 2, libs.length);
78
        LibraryManagerTest.assertLibsEquals (libs, impls);
75
        LibraryManagerTest.assertLibsEquals (libs, impls);
79
        LibraryManagerTest.TestListener tl = new LibraryManagerTest.TestListener ();
76
        MockPropertyChangeListener pcl = new MockPropertyChangeListener();
80
        libs[0].addPropertyChangeListener(tl);
77
        libs[0].addPropertyChangeListener(pcl);
81
        impls[0].setName("NewLibrary1");
78
        impls[0].setName("NewLibrary1");
82
        LibraryManagerTest.assertEventsEquals(tl.getEventNames(), new String[] {Library.PROP_NAME});
79
        pcl.assertEvents(Library.PROP_NAME);
83
        tl.reset();
84
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
80
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
85
        
81
        
86
        impls[0].setDescription("NewLibrary1Description");
82
        impls[0].setDescription("NewLibrary1Description");
87
        LibraryManagerTest.assertEventsEquals(tl.getEventNames(), new String[] {Library.PROP_DESCRIPTION});
83
        pcl.assertEvents(Library.PROP_DESCRIPTION);
88
        tl.reset();
89
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
84
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
90
        List<URL> urls = new ArrayList<URL>();
85
        List<URL> urls = new ArrayList<URL>();
91
        urls.add (new URL ("file:/lib/libnew1.so"));
86
        urls.add (new URL ("file:/lib/libnew1.so"));
92
        urls.add (new URL ("file:/lib/libnew2.so"));
87
        urls.add (new URL ("file:/lib/libnew2.so"));
93
        impls[0].setContent ("bin",urls);        
88
        impls[0].setContent ("bin",urls);        
94
        LibraryManagerTest.assertEventsEquals(tl.getEventNames(), new String[] {Library.PROP_CONTENT});
89
        pcl.assertEvents(Library.PROP_CONTENT);
95
        tl.reset();
96
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
90
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
97
        urls = new ArrayList<URL>();
91
        urls = new ArrayList<URL>();
98
        urls.add (new URL ("file:/src/new/src/"));
92
        urls.add (new URL ("file:/src/new/src/"));
99
        impls[0].setContent ("src",urls);        
93
        impls[0].setContent ("src",urls);        
100
        LibraryManagerTest.assertEventsEquals(tl.getEventNames(), new String[] {Library.PROP_CONTENT});
94
        pcl.assertEvents(Library.PROP_CONTENT);
101
        tl.reset();
102
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
95
        LibraryManagerTest.assertLibsEquals (new Library[] {libs[0]}, new LibraryImplementation[] {impls[0]});
103
    }    
96
    }    
104
    
97
    
(-)/dev/null (+245 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.modules.project.libraries;
21
22
import java.beans.PropertyChangeListener;
23
import java.beans.PropertyChangeSupport;
24
import java.io.IOException;
25
import java.net.MalformedURLException;
26
import java.net.URL;
27
import java.util.ArrayList;
28
import java.util.Arrays;
29
import java.util.HashMap;
30
import java.util.HashSet;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.Set;
34
import java.util.regex.Matcher;
35
import java.util.regex.Pattern;
36
import org.netbeans.spi.project.libraries.ArealLibraryProvider;
37
import org.netbeans.spi.project.libraries.LibraryImplementation;
38
import org.netbeans.spi.project.libraries.LibraryProvider;
39
import org.netbeans.spi.project.libraries.LibraryStorageArea;
40
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
41
import org.openide.util.WeakSet;
42
43
/**
44
 * Common support classes for unit tests in this module.
45
 */
46
public class TestUtil {
47
48
    private TestUtil() {}
49
50
    public static class NWLP implements LibraryProvider<LibraryImplementation> {
51
52
        public final List<LibraryImplementation> libs = new ArrayList<LibraryImplementation>();
53
        final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
54
55
        public void set(LibraryImplementation... nue) {
56
            libs.clear();
57
            libs.addAll(Arrays.asList(nue));
58
            pcs.firePropertyChange(PROP_LIBRARIES, null, null);
59
        }
60
61
        public LibraryImplementation[] getLibraries() {
62
            return libs.toArray(new LibraryImplementation[0]);
63
        }
64
65
        public void addPropertyChangeListener(PropertyChangeListener listener) {
66
            pcs.addPropertyChangeListener(listener);
67
        }
68
69
        public void removePropertyChangeListener(PropertyChangeListener listener) {
70
            pcs.removePropertyChangeListener(listener);
71
        }
72
73
    }
74
75
    public static final class WLP extends NWLP implements WritableLibraryProvider<LibraryImplementation> {
76
77
        public void addLibrary(LibraryImplementation library) throws IOException {
78
            libs.add(library);
79
            pcs.firePropertyChange(PROP_LIBRARIES, null, null);
80
        }
81
82
        public void removeLibrary(LibraryImplementation library) throws IOException {
83
            libs.remove(library);
84
            pcs.firePropertyChange(PROP_LIBRARIES, null, null);
85
        }
86
87
        public void updateLibrary(LibraryImplementation oldLibrary, LibraryImplementation newLibrary) throws IOException {
88
            libs.remove(oldLibrary);
89
            libs.add(newLibrary);
90
            pcs.firePropertyChange(PROP_LIBRARIES, null, null);
91
        }
92
93
    }
94
95
    public static final class Area implements LibraryStorageArea {
96
97
        final String id;
98
99
        public Area(String id) {
100
            this.id = id;
101
        }
102
103
        public URL getLocation() {
104
            try {
105
                return new URL("http://nowhere.net/" + id);
106
            } catch (MalformedURLException x) {
107
                throw new AssertionError(x);
108
            }
109
        }
110
111
        public String getDisplayName() {
112
            return id;
113
        }
114
115
        public boolean equals(Object obj) {
116
            return obj instanceof Area && ((Area) obj).id.equals(id);
117
        }
118
119
        public int hashCode() {
120
            return id.hashCode();
121
        }
122
123
        public @Override String toString() {
124
            return "Area[" + id + "]";
125
        }
126
127
    }
128
129
    public static final class ALP implements ArealLibraryProvider<Area,LibraryImplementation> {
130
131
        final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
132
        public final Map<Area,List<LibraryImplementation>> libs = new HashMap<Area,List<LibraryImplementation>>();
133
        final Set<LP> lps = new WeakSet<LP>();
134
        final Set<Area> open = new HashSet<Area>();
135
136
        public void addPropertyChangeListener(PropertyChangeListener listener) {
137
            pcs.addPropertyChangeListener(listener);
138
        }
139
140
        public void removePropertyChangeListener(PropertyChangeListener listener) {
141
            pcs.removePropertyChangeListener(listener);
142
        }
143
144
        public Class<Area> areaType() {
145
            return Area.class;
146
        }
147
148
        public Class<LibraryImplementation> libraryType() {
149
            return LibraryImplementation.class;
150
        }
151
152
        public Area createArea() {
153
            return new Area("new");
154
        }
155
156
        public Area loadArea(URL location) {
157
            Matcher m = Pattern.compile("http://nowhere\\.net/(.+)$").matcher(location.toExternalForm());
158
            if (m.matches()) {
159
                return new Area(m.group(1));
160
            } else {
161
                return null;
162
            }
163
        }
164
165
        public Set<Area> getOpenAreas() {
166
            return open;
167
        }
168
169
        public void setOpen(Area... areas) {
170
            open.clear();
171
            open.addAll(Arrays.asList(areas));
172
            pcs.firePropertyChange(PROP_OPEN_AREAS, null, null);
173
        }
174
175
        private class LP implements LibraryProvider<LibraryImplementation> {
176
177
            final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
178
            final Area area;
179
180
            LP(Area area) {
181
                this.area = area;
182
                lps.add(this);
183
            }
184
185
            public LibraryImplementation[] getLibraries() {
186
                if (libs.containsKey(area)) {
187
                    return libs.get(area).toArray(new LibraryImplementation[0]);
188
                } else {
189
                    return new LibraryImplementation[0];
190
                }
191
            }
192
193
            public void addPropertyChangeListener(PropertyChangeListener listener) {
194
                pcs.addPropertyChangeListener(listener);
195
            }
196
197
            public void removePropertyChangeListener(PropertyChangeListener listener) {
198
                pcs.removePropertyChangeListener(listener);
199
            }
200
201
        }
202
203
        public LibraryProvider<LibraryImplementation> getLibraries(Area area) {
204
            return new LP(area);
205
        }
206
207
        public LibraryImplementation createLibrary(String type, String name, Area area, Map<String,List<URL>> contents) throws IOException {
208
            LibraryImplementation lib = LibrariesSupport.createLibraryImplementation(type, contents.keySet().toArray(new String[0]));
209
            lib.setName(name);
210
            for (Map.Entry<String,List<URL>> entry : contents.entrySet()) {
211
                lib.setContent(entry.getKey(), entry.getValue());
212
            }
213
            List<LibraryImplementation> l = libs.get(area);
214
            if (l == null) {
215
                l = new ArrayList<LibraryImplementation>();
216
                libs.put(area, l);
217
            }
218
            l.add(lib);
219
            for (LP lp : lps) {
220
                if (lp.area.equals(area)) {
221
                    lp.pcs.firePropertyChange(LibraryProvider.PROP_LIBRARIES, null, null);
222
                }
223
            }
224
            return lib;
225
        }
226
227
        public void remove(LibraryImplementation library) throws IOException {
228
            for (Map.Entry<Area,List<LibraryImplementation>> entry : libs.entrySet()) {
229
                if (entry.getValue().remove(library)) {
230
                    for (LP lp : lps) {
231
                        if (lp.area.equals(entry.getKey())) {
232
                            lp.pcs.firePropertyChange(LibraryProvider.PROP_LIBRARIES, null, null);
233
                        }
234
                    }
235
                }
236
            }
237
        }
238
239
    }
240
241
    public static URL mkJar(String name) throws MalformedURLException {
242
        return new URL("jar:http://nowhere.net/" + name + "!/");
243
    }
244
245
}
(-)/dev/null (+186 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.modules.project.libraries.ui;
21
22
import static org.netbeans.modules.project.libraries.TestUtil.*;
23
import java.net.URL;
24
import java.util.Arrays;
25
import java.util.Collection;
26
import java.util.Collections;
27
import java.util.List;
28
import java.util.SortedSet;
29
import java.util.TreeSet;
30
import org.netbeans.junit.NbTestCase;
31
import org.netbeans.spi.project.libraries.LibraryImplementation;
32
import org.netbeans.spi.project.libraries.LibraryStorageArea;
33
import org.netbeans.spi.project.libraries.support.LibrariesSupport;
34
import org.openide.util.test.MockChangeListener;
35
import org.openide.util.test.MockLookup;
36
37
public class LibrariesModelTest extends NbTestCase {
38
39
    // XXX test:
40
    // editing global libs
41
    // library editability flag is correct
42
    // IOException thrown by providers handled reasonably
43
44
    public LibrariesModelTest(String n) {
45
        super(n);
46
    }
47
48
    private LibrariesModel model;
49
    private LibraryImplementation lib1, lib2, lib3;
50
    private URL jar1, jar2, jar3;
51
    private MockChangeListener cl;
52
    private WLP wlp;
53
    private NWLP nwlp;
54
    private ALP alp;
55
56
    @Override
57
    protected void setUp() throws Exception {
58
        super.setUp();
59
        wlp = new WLP();
60
        nwlp = new NWLP();
61
        alp = new ALP();
62
        MockLookup.setInstances(wlp, nwlp, alp);
63
        LibrariesModel.createdAreas.clear();
64
        model = new LibrariesModel();
65
        cl = new MockChangeListener();
66
        model.addChangeListener(cl);
67
        lib1 = mkLib("lib1");
68
        lib2 = mkLib("lib2");
69
        lib3 = mkLib("lib3");
70
        jar1 = mkJar("lib1.jar");
71
        jar2 = mkJar("lib2.jar");
72
        jar3 = mkJar("lib3.jar");
73
        cl.assertNoEvents();
74
        assertEquals(0, model.getLibraries().size());
75
    }
76
77
    public void testNWLP() throws Exception {
78
        nwlp.set(lib1, lib2);
79
        cl.assertEvent();
80
        assertEquals(2, model.getLibraries().size());
81
    }
82
83
    public void testWLP() throws Exception {
84
        model.addLibrary(lib1);
85
        cl.assertEvent();
86
        assertEquals(1, model.getLibraries().size());
87
        model.addLibrary(lib2);
88
        cl.assertEvent();
89
        assertEquals(2, model.getLibraries().size());
90
        model.removeLibrary(lib1);
91
        cl.assertEvent();
92
        assertEquals(1, model.getLibraries().size());
93
        model.apply();
94
        assertEquals(1, wlp.libs.size());
95
        LibraryImplementation lib = wlp.libs.iterator().next();
96
        assertEquals("lib2", lib.getName());
97
    }
98
99
    public void testAreas() throws Exception {
100
        assertEquals("[]", areas2S());
101
        alp.setOpen(new Area("o1"), new Area("o2"));
102
        cl.assertEvent();
103
        assertEquals("[o1, o2]", areas2S());
104
        assertEquals("new", model.createArea().getDisplayName());
105
        cl.assertEvent();
106
        assertEquals("[new, o1, o2]", areas2S());
107
    }
108
    private String areas2S() {
109
        SortedSet<String> names = new TreeSet<String>();
110
        for (LibraryStorageArea area : model.getAreas()) {
111
            names.add(area.getDisplayName());
112
        }
113
        return names.toString();
114
    }
115
116
    public void testArealLibs() throws Exception {
117
        Area a = new Area("home");
118
        alp.setOpen(a);
119
        LibraryImplementation lib1 = model.createArealLibrary("jar", "mylib1", a);
120
        assertEquals(a, model.getArea(lib1));
121
        model.addLibrary(lib1);
122
        LibraryImplementation lib2 = model.createArealLibrary("jar", "mylib2", a);
123
        model.addLibrary(lib2);
124
        model.removeLibrary(lib2);
125
        lib1.setContent("cp", Arrays.asList(jar1, jar2));
126
        model.apply();
127
        assertEquals(1, alp.libs.size());
128
        assertEquals(a, alp.libs.keySet().iterator().next());
129
        List<LibraryImplementation> libs = alp.libs.get(a);
130
        assertEquals(1, libs.size());
131
        LibraryImplementation lib = libs.iterator().next();
132
        assertEquals("mylib1", lib.getName());
133
        assertEquals(Arrays.asList(jar1, jar2), lib.getContent("cp"));
134
        assertEquals(a, model.getArea(lib));
135
        model = new LibrariesModel();
136
        assertEquals(1, model.getLibraries().size());
137
        lib = model.getLibraries().iterator().next();
138
        assertEquals(a, model.getArea(lib));
139
        lib.setContent("cp", Collections.singletonList(jar3));
140
        model.apply();
141
        assertEquals(1, alp.libs.size());
142
        assertEquals(a, alp.libs.keySet().iterator().next());
143
        libs = alp.libs.get(a);
144
        assertEquals(1, libs.size());
145
        lib = libs.iterator().next();
146
        assertEquals("mylib1", lib.getName());
147
        assertEquals(Collections.singletonList(jar3), lib.getContent("cp"));
148
        assertEquals(a, model.getArea(lib));
149
        model = new LibrariesModel();
150
        assertEquals(1, model.getLibraries().size());
151
        lib = model.getLibraries().iterator().next();
152
        model.removeLibrary(lib);
153
        model.apply();
154
        assertEquals(1, alp.libs.size());
155
        assertEquals(a, alp.libs.keySet().iterator().next());
156
        libs = alp.libs.get(a);
157
        assertEquals(0, libs.size());
158
        Area a2 = new Area("away");
159
        assertEquals(0, model.getLibraries().size());
160
        model.addLibrary(model.createArealLibrary("jar", "generic", a));
161
        model.addLibrary(model.createArealLibrary("jar", "generic", a2));
162
        assertEquals(2, model.getLibraries().size());
163
    }
164
165
    public void testLoadLibsAfterCreateArea() throws Exception {
166
        LibraryStorageArea a = model.createArea();
167
        model.addLibrary(model.createArealLibrary("jar", "foo", a));
168
        model.apply();
169
        LibrariesModel.createdAreas.clear();
170
        model = new LibrariesModel();
171
        cl = new MockChangeListener();
172
        model.addChangeListener(cl);
173
        assertEquals(a, model.createArea());
174
        cl.assertEvent();
175
        Collection<? extends LibraryImplementation> libs = model.getLibraries();
176
        assertEquals(1, libs.size());
177
        assertEquals("foo", libs.iterator().next().getName());
178
    }
179
180
    private LibraryImplementation mkLib(String name) {
181
        LibraryImplementation lib = LibrariesSupport.createLibraryImplementation("jar", new String[] {"cp"});
182
        lib.setName(name);
183
        return lib;
184
    }
185
186
}
(-)/dev/null (+114 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 * 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 * 
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 * 
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 * 
35
 * Contributor(s):
36
 * 
37
 * Portions Copyrighted 2007 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.spi.project.libraries.support;
41
42
import java.io.File;
43
import java.net.MalformedURLException;
44
import java.net.URL;
45
import org.netbeans.junit.NbTestCase;
46
import org.openide.filesystems.FileObject;
47
import org.openide.filesystems.FileUtil;
48
49
/**
50
 */
51
public class LibrariesSupportTest extends NbTestCase {
52
53
    public LibrariesSupportTest(String testName) {
54
        super(testName);
55
    }            
56
57
    @Override
58
    protected void setUp() throws Exception {
59
        super.setUp();
60
    }
61
62
    /**
63
     * Test of convertFileToURL method, of class LibrariesSupport.
64
     */
65
    public void testConvertFileToURL() {
66
        File f = new File("/aa/bb/c c.ext".replace('/', File.separatorChar));
67
        URL u = LibrariesSupport.convertFileToURL(f);
68
        assertEquals("file:/aa/bb/c%20c.ext", u.toExternalForm());
69
        f = new File("../zz/re l.ext".replace('/', File.separatorChar));
70
        u = LibrariesSupport.convertFileToURL(f);
71
        assertEquals("file:../zz/re%20l.ext", u.toExternalForm());
72
    }
73
74
    /**
75
     * Test of convertURLToFile method, of class LibrariesSupport.
76
     */
77
    public void testConvertURLToFile() throws MalformedURLException{
78
        URL u = new URL("file:/aa/bb/c%20c.ext");
79
        File f = LibrariesSupport.convertURLToFile(u);
80
        assertEquals("/aa/bb/c c.ext".replace('/', File.separatorChar), f.getPath());
81
        u = new URL("file:../zz/re%20l.ext");
82
        f = LibrariesSupport.convertURLToFile(u);
83
        assertEquals("../zz/re l.ext".replace('/', File.separatorChar), f.getPath());
84
    }
85
86
    /**
87
     * Test of isAbsoluteURL method, of class LibrariesSupport.
88
     */
89
    public void testIsAbsoluteURL() throws MalformedURLException{
90
        URL u = new URL("file", null, "/test/absolute");
91
        assertTrue(u.toExternalForm(), LibrariesSupport.isAbsoluteURL(u));
92
        u = new URL("file", null, "../relative");
93
        assertFalse(u.toExternalForm(), LibrariesSupport.isAbsoluteURL(u));
94
    }
95
96
    /**
97
     * Test of resolveLibraryEntryFileObject method, of class LibrariesSupport.
98
     */
99
    public void testResolveLibraryEntry() throws Exception {
100
        File f = new File(this.getWorkDir(), "knihovna.properties");
101
        File f2 = new File(this.getWorkDir(), "bertie.jar");
102
        f.createNewFile();
103
        f2.createNewFile();
104
        FileObject fo = LibrariesSupport.resolveLibraryEntryFileObject(
105
                f.toURI().toURL(), 
106
                new URL("file", null, "bertie.jar"));
107
        assertEquals(f2.getPath(), FileUtil.toFile(fo).getPath());
108
        fo = LibrariesSupport.resolveLibraryEntryFileObject(
109
                null, 
110
                f2.toURI().toURL());
111
        assertEquals(f2.getPath(), FileUtil.toFile(fo).getPath());
112
    }
113
114
}

Return to bug 44035