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

(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/Bundle.properties (-5 / +2 lines)
Lines 41-57 Link Here
41
LBL_Customizer_Title=Project Properties - {0}
41
LBL_Customizer_Title=Project Properties - {0}
42
42
43
# Configuration node labels
43
# Configuration node labels
44
Projects/org-netbeans-modules-java-j2seproject/Customizer/BuildCategory=Build
44
LBL_Config_BuildCategory=Build
45
Projects/org-netbeans-modules-java-j2seproject/Customizer/WebServiceCategory=Web Services
45
LBL_Config_Application=Application
46
Projects/org-netbeans-modules-java-j2seproject/Customizer/Application=Application
47
LBL_Config_Libraries=Libraries
46
LBL_Config_Libraries=Libraries
48
LBL_Config_Sources=Sources
47
LBL_Config_Sources=Sources
49
LBL_Config_Build=Compiling
48
LBL_Config_Build=Compiling
50
LBL_Config_Jar=Packaging
49
LBL_Config_Jar=Packaging
51
LBL_Config_Javadoc=Documenting
50
LBL_Config_Javadoc=Documenting
52
LBL_Config_Run=Run
51
LBL_Config_Run=Run
53
LBL_Config_WebServiceClients=Web Service Clients
54
LBL_Config_WebServices=JAX-RPC Web Services
55
52
56
# Panels
53
# Panels
57
54
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/J2SECompositePanelProvider.java (+33 lines)
Lines 131-160 Link Here
131
131
132
    }
132
    }
133
133
134
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
135
        projectType="org-netbeans-modules-java-j2seproject",
136
        position=100
137
    )
134
    public static J2SECompositePanelProvider createSources() {
138
    public static J2SECompositePanelProvider createSources() {
135
        return new J2SECompositePanelProvider(SOURCES);
139
        return new J2SECompositePanelProvider(SOURCES);
136
    }
140
    }
137
141
142
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
143
        projectType="org-netbeans-modules-java-j2seproject",
144
        position=200
145
    )
138
    public static J2SECompositePanelProvider createLibraries() {
146
    public static J2SECompositePanelProvider createLibraries() {
139
        return new J2SECompositePanelProvider(LIBRARIES);
147
        return new J2SECompositePanelProvider(LIBRARIES);
140
    }
148
    }
141
149
150
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
151
        projectType="org-netbeans-modules-java-j2seproject",
152
        category="BuildCategory",
153
        position=100
154
    )
142
    public static J2SECompositePanelProvider createBuild() {
155
    public static J2SECompositePanelProvider createBuild() {
143
        return new J2SECompositePanelProvider(BUILD);
156
        return new J2SECompositePanelProvider(BUILD);
144
    }
157
    }
145
158
159
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
160
        projectType="org-netbeans-modules-java-j2seproject",
161
        category="BuildCategory",
162
        position=200
163
    )
146
    public static J2SECompositePanelProvider createJar() {
164
    public static J2SECompositePanelProvider createJar() {
147
        return new J2SECompositePanelProvider(JAR);
165
        return new J2SECompositePanelProvider(JAR);
148
    }
166
    }
149
167
168
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
169
        projectType="org-netbeans-modules-java-j2seproject",
170
        category="BuildCategory",
171
        position=300
172
    )
150
    public static J2SECompositePanelProvider createJavadoc() {
173
    public static J2SECompositePanelProvider createJavadoc() {
151
        return new J2SECompositePanelProvider(JAVADOC);
174
        return new J2SECompositePanelProvider(JAVADOC);
152
    }
175
    }
153
176
177
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
178
        projectType="org-netbeans-modules-java-j2seproject",
179
        position=400
180
    )
154
    public static J2SECompositePanelProvider createRun() {
181
    public static J2SECompositePanelProvider createRun() {
155
        return new J2SECompositePanelProvider(RUN);
182
        return new J2SECompositePanelProvider(RUN);
156
    }
183
    }
157
    
184
    
185
    @ProjectCustomizer.CompositeCategoryProvider.Registration(
186
        projectType="org-netbeans-modules-java-j2seproject",
187
        category="Application",
188
        position=500,
189
        categoryLabel="#LBL_Config_Application"
190
    )
158
    public static J2SECompositePanelProvider createApplication() {
191
    public static J2SECompositePanelProvider createApplication() {
159
        return new J2SECompositePanelProvider(APPLICATION);
192
        return new J2SECompositePanelProvider(APPLICATION);
160
    }
193
    }
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/package-info.java (+48 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 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 2009 Sun Microsystems, Inc.
38
 */
39
40
@ProjectCustomizer.CompositeCategoryProvider.Registration(
41
    projectType="org-netbeans-modules-java-j2seproject",
42
    category="BuildCategory",
43
    position=300,
44
    categoryLabel="#LBL_Config_BuildCategory"
45
)
46
package org.netbeans.modules.java.j2seproject.ui.customizer;
47
48
import org.netbeans.spi.project.ui.support.ProjectCustomizer;
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/ui/resources/layer.xml (-39 lines)
Lines 93-137 Link Here
93
    </folder>
93
    </folder>
94
    <folder name="Projects">
94
    <folder name="Projects">
95
        <folder name="org-netbeans-modules-java-j2seproject">
95
        <folder name="org-netbeans-modules-java-j2seproject">
96
            <folder name="Customizer">
97
                <file name="Sources.instance">
98
                    <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createSources"/>
99
                    <attr name="position" intvalue="100"/>
100
                </file>
101
                <file name="Libraries.instance">
102
                    <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createLibraries"/>
103
                    <attr name="position" intvalue="200"/>
104
                </file>
105
                <folder name="BuildCategory">
106
                    <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.java.j2seproject.ui.customizer.Bundle"/>
107
                    <attr name="position" intvalue="300"/>
108
                    <file name="Build.instance">
109
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createBuild"/>
110
                        <attr name="position" intvalue="100"/>
111
                    </file>
112
                    <file name="Jar.instance">
113
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createJar"/>
114
                        <attr name="position" intvalue="200"/>
115
                    </file>
116
                    <file name="Javadoc.instance">
117
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createJavadoc"/>
118
                        <attr name="position" intvalue="300"/>
119
                    </file>
120
                </folder>
121
                <file name="Run.instance">
122
                    <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createRun"/>
123
                    <attr name="position" intvalue="400"/>
124
                </file>
125
                <folder name="Application">
126
                    <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.java.j2seproject.ui.customizer.Bundle"/>
127
                    <attr name="position" intvalue="500"/>
128
                    <file name="Self.instance">
129
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.j2seproject.ui.customizer.J2SECompositePanelProvider.createApplication"/>
130
                        <attr name="position" intvalue="0"/>
131
                    </file>
132
                </folder>
133
            </folder>
134
            
135
            <folder name="Nodes">
96
            <folder name="Nodes">
136
                <file name="org-netbeans-modules-java-api-common-project-ui-JavaSourceNodeFactory.instance">
97
                <file name="org-netbeans-modules-java-api-common-project-ui-JavaSourceNodeFactory.instance">
137
                    <attr name="position" intvalue="200"/>
98
                    <attr name="position" intvalue="200"/>
(-)a/openide.filesystems/src/org/openide/filesystems/annotations/LayerBuilder.java (-9 / +33 lines)
Lines 90-96 Link Here
90
     * @return a file builder
90
     * @return a file builder
91
     */
91
     */
92
    public File file(String path) {
92
    public File file(String path) {
93
        File f = new File(path);
93
        File f = new File(path, false);
94
        unwrittenFiles.add(f);
95
        return f;
96
    }
97
98
    /**
99
     * Adds a folder to the layer.
100
     * You need to {@link File#write} it in order to finalize the effect.
101
     * <p>Normally just using {@link #file} suffices, since parent folders are
102
     * created as needed, but you may use this method if you wish to create a folder
103
     * (possibly with some attributes) without necessarily creating any children.
104
     * @param path the full path to the desired folder in resource format, e.g. {@code "Menu/File"}
105
     * @return a file builder
106
     * @since XXX
107
     */
108
    public File folder(String path) {
109
        File f = new File(path, true);
94
        unwrittenFiles.add(f);
110
        unwrittenFiles.add(f);
95
        return f;
111
        return f;
96
    }
112
    }
Lines 209-220 Link Here
209
    public final class File {
225
    public final class File {
210
226
211
        private final String path;
227
        private final String path;
228
        private final boolean folder;
212
        private final Map<String,String[]> attrs = new LinkedHashMap<String,String[]>();
229
        private final Map<String,String[]> attrs = new LinkedHashMap<String,String[]>();
213
        private String contents;
230
        private String contents;
214
        private String url;
231
        private String url;
215
232
216
        File(String path) {
233
        File(String path, boolean folder) {
217
            this.path = path;
234
            this.path = path;
235
            this.folder = folder;
218
        }
236
        }
219
237
220
        /**
238
        /**
Lines 231-237 Link Here
231
         * @return this builder
249
         * @return this builder
232
         */
250
         */
233
        public File contents(String contents) {
251
        public File contents(String contents) {
234
            if (this.contents != null || url != null || contents == null) {
252
            if (this.contents != null || url != null || contents == null || folder) {
235
                throw new IllegalArgumentException();
253
                throw new IllegalArgumentException();
236
            }
254
            }
237
            this.contents = contents;
255
            this.contents = contents;
Lines 245-251 Link Here
245
         * @return this builder
263
         * @return this builder
246
         */
264
         */
247
        public File url(String url) {
265
        public File url(String url) {
248
            if (contents != null || this.url != null || url == null) {
266
            if (contents != null || this.url != null || url == null || folder) {
249
                throw new IllegalArgumentException();
267
                throw new IllegalArgumentException();
250
            }
268
            }
251
            this.url = url;
269
            this.url = url;
Lines 524-532 Link Here
524
        }
542
        }
525
543
526
        /**
544
        /**
527
         * Writes the file to the layer.
545
         * Writes the file or folder to the layer.
528
         * Any intervening parent folders are created automatically.
546
         * Any intervening parent folders are created automatically.
529
         * If the file already exists, the old copy is replaced.
547
         * If the file already exists, the old copy is replaced (not true in case of a folder).
530
         * @return the originating layer builder, in case you want to add another file
548
         * @return the originating layer builder, in case you want to add another file
531
         */
549
         */
532
        public LayerBuilder write() {
550
        public LayerBuilder write() {
Lines 547-556 Link Here
547
            }
565
            }
548
            String piece = pieces[pieces.length - 1];
566
            String piece = pieces[pieces.length - 1];
549
            org.w3c.dom.Element file = find(e,piece);
567
            org.w3c.dom.Element file = find(e,piece);
550
            if (file != null) {
568
            if (folder) {
551
                e.removeChild(file);
569
                if (file == null) {
570
                    file = (org.w3c.dom.Element) e.appendChild(doc.createElement("folder"));
571
                }
572
            } else {
573
                if (file != null) {
574
                    e.removeChild(file);
575
                }
576
                file = (org.w3c.dom.Element) e.appendChild(doc.createElement("file"));
552
            }
577
            }
553
            file = (org.w3c.dom.Element) e.appendChild(doc.createElement("file"));
554
            file.setAttribute("name", piece);
578
            file.setAttribute("name", piece);
555
            for (Map.Entry<String,String[]> entry : attrs.entrySet()) {
579
            for (Map.Entry<String,String[]> entry : attrs.entrySet()) {
556
                org.w3c.dom.Element attr = (org.w3c.dom.Element) file.appendChild(doc.createElement("attr"));
580
                org.w3c.dom.Element attr = (org.w3c.dom.Element) file.appendChild(doc.createElement("attr"));
(-)a/openide.filesystems/test/unit/src/org/openide/filesystems/annotations/LayerBuilderTest.java (+10 lines)
Lines 135-138 Link Here
135
                "</file></filesystem>", dump());
135
                "</file></filesystem>", dump());
136
    }
136
    }
137
137
138
    public void testFolders() throws Exception {
139
        b.file("x/y").write();
140
        b.folder("x/z").stringvalue("a", "v").write();
141
        b.folder("x").write();
142
        assertEquals("<filesystem><folder name='x'>" +
143
                "<file name='y'/>" +
144
                "<folder name='z'><attr name='a' stringvalue='v'/></folder>" +
145
                "</folder></filesystem>", dump());
146
    }
147
138
}
148
}
(-)a/projectuiapi/src/org/netbeans/modules/project/uiapi/CompositeCategoryProviderAnnotationProcessor.java (+109 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 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 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.modules.project.uiapi;
41
42
import java.util.Set;
43
import javax.annotation.processing.Processor;
44
import javax.annotation.processing.RoundEnvironment;
45
import javax.annotation.processing.SupportedAnnotationTypes;
46
import javax.annotation.processing.SupportedSourceVersion;
47
import javax.lang.model.SourceVersion;
48
import javax.lang.model.element.Element;
49
import javax.lang.model.element.ElementKind;
50
import javax.lang.model.element.TypeElement;
51
import org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider;
52
import org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider.Registration;
53
import org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider.Registrations;
54
import org.openide.filesystems.annotations.LayerBuilder.File;
55
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
56
import org.openide.filesystems.annotations.LayerGenerationException;
57
import org.openide.util.lookup.ServiceProvider;
58
59
@ServiceProvider(service=Processor.class)
60
@SupportedSourceVersion(SourceVersion.RELEASE_6)
61
@SupportedAnnotationTypes({
62
    "org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider.Registration",
63
    "org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider.Registrations"
64
})
65
public class CompositeCategoryProviderAnnotationProcessor extends LayerGeneratingProcessor {
66
67
    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
68
        if (roundEnv.processingOver()) {
69
            return false;
70
        }
71
        for (Element e : roundEnv.getElementsAnnotatedWith(Registration.class)) {
72
            handle(e, e.getAnnotation(Registration.class));
73
        }
74
        for (Element e : roundEnv.getElementsAnnotatedWith(Registrations.class)) {
75
            for (Registration r : e.getAnnotation(Registrations.class).value()) {
76
                handle(e, r);
77
            }
78
        }
79
        return true;
80
    }
81
82
    private void handle(Element e, Registration r) throws LayerGenerationException {
83
        String path = "Projects/" + r.projectType() + "/Customizer";
84
        if (r.category().length() > 0) {
85
            path += "/" + r.category();
86
        }
87
        boolean addsFolder = r.categoryLabel().length() > 0;
88
        if (addsFolder) {
89
            handleFolder(path, e, r);
90
        }
91
        if (e.getKind() == ElementKind.PACKAGE) {
92
            if (!addsFolder) {
93
                throw new LayerGenerationException("Must specify categoryLabel", e);
94
            }
95
        } else {
96
            File f = layer(e).instanceFile(path, addsFolder ? "Self" : null, CompositeCategoryProvider.class);
97
            f.position(addsFolder ? 0 : r.position());
98
            f.write();
99
        }
100
    }
101
102
    private void handleFolder(String path, Element e, Registration r) throws LayerGenerationException {
103
        if (r.category().length() == 0) {
104
            throw new LayerGenerationException("Must specify category", e);
105
        }
106
        layer(e).folder(path).bundlevalue("displayName", r.categoryLabel()).position(r.position()).write();
107
    }
108
109
}
(-)a/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java (-4 / +66 lines)
Lines 45-50 Link Here
45
import java.awt.Image;
45
import java.awt.Image;
46
import java.awt.event.ActionListener;
46
import java.awt.event.ActionListener;
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.lang.annotation.ElementType;
49
import java.lang.annotation.Retention;
50
import java.lang.annotation.RetentionPolicy;
51
import java.lang.annotation.Target;
48
import java.util.ArrayList;
52
import java.util.ArrayList;
49
import java.util.Collections;
53
import java.util.Collections;
50
import java.util.HashMap;
54
import java.util.HashMap;
Lines 288-298 Link Here
288
292
289
    /**
293
    /**
290
     * Interface for creation of Customizer categories and their respective UI panels.
294
     * Interface for creation of Customizer categories and their respective UI panels.
291
     * Implementations are to be registered in System FileSystem via module layers. Used by the
295
     * Used by {@link ProjectCustomizer#createCustomizerDialog(String,Lookup,String,ActionListener,HelpCtx)}.
292
     * {@link ProjectCustomizer#createCustomizerDialog(String,Lookup,String,ActionListener,HelpCtx)}
296
     * <p>The panel/category created by the provider can get notified that the customizer got
293
     * The panel/category created by the provider can get notified that the customizer got
297
     * closed by setting an <code>ActionListener</code> to
294
     * closed by setting an <code>ActionListener</code> to 
295
     * {@link ProjectCustomizer.Category#setOkButtonListener}.
298
     * {@link ProjectCustomizer.Category#setOkButtonListener}.
299
     * <p>Implementations can be registered using {@link Registration}.
300
     * Otherwise they can be manually registered in a tree structure in the system filesystem.
296
     * UI Component can be defined for category folder that is represented as node with subnodes in the category
301
     * UI Component can be defined for category folder that is represented as node with subnodes in the category
297
     * tree of project customizer. The file that defines the instance class in layer for such category
302
     * tree of project customizer. The file that defines the instance class in layer for such category
298
     * must be named {@code Self}. Such a provider will not have the {@link #createCategory} method called
303
     * must be named {@code Self}. Such a provider will not have the {@link #createCategory} method called
Lines 322-327 Link Here
322
         * for the project type you want to integrate your panel into.
327
         * for the project type you want to integrate your panel into.
323
         */
328
         */
324
        JComponent createComponent (Category category, Lookup context );
329
        JComponent createComponent (Category category, Lookup context );
330
331
        /**
332
         * Used to register customizer panels.
333
         * There are three ways this annotation can be used:
334
         * <ol>
335
         * <li>Register a "leaf" panel with no children.
336
         *     {@link #category} can be omitted for a top-level panel;
337
         *     if specified, the panel is placed in the named subcategory.
338
         *     {@link #categoryLabel} should not be specified.
339
         *     The annotation must be placed on a class or factory method implementing {@link CompositeCategoryProvider}.
340
         * <li>Register a category folder with no panel.
341
         *     {@link #category} must be specified; the last path component is the
342
         *     folder being defined, and any previous components are parent folders.
343
         *     {@link #categoryLabel} must be specified.
344
         *     The annotation must be placed on some package declaration (in {@code package-info.java}).
345
         * <li>Register a category folder also with its own panel (i.e. {@code Self}).
346
         *     {@link #category} and {@link #categoryLabel} must be specified as for #2,
347
         *     but the annotation must be on a provider implementation as for #1.
348
         * </ol>
349
         * To represent hierarchies of panels, the {@link #category} of a #1 can
350
         * match the {@link #category} of a #2 or #3, and the {@link #category} of a #2 or #3
351
         * preceding the last {@code /} can match the {@link #category} of another #2 or #3.
352
         * <p>Multiple registrations may be made in one place using {@link Registrations}.
353
         * @since XXX
354
         */
355
        @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PACKAGE})
356
        @Retention(RetentionPolicy.SOURCE)
357
        @interface Registration {
358
            /**
359
             * Project type to associate with, such as {@code org-netbeans-modules-java-j2seproject}.
360
             * The {@code folderPath} passed to {@link ProjectCustomizer#createCustomizerDialog(String,Lookup,String,ActionListener,HelpCtx)}
361
             * should be {@code Projects/<projectType>/Customizer}.
362
             */
363
            String projectType();
364
            /**
365
             * Category folder (perhaps multiple components separated by {@code /})
366
             * in which to place this panel or which is the name of this panel folder.
367
             */
368
            String category() default "";
369
            /**
370
             * Display name when defining a category folder.
371
             * Can use {@code pkg.of.Bundle#key_name} syntax.
372
             */
373
            String categoryLabel() default "";
374
            /**
375
             * Position of this panel or subfolder within its folder.
376
             */
377
            int position() default Integer.MAX_VALUE;
378
        }
379
        /**
380
         * Used in case multiple registrations are needed in one place.
381
         */
382
        @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PACKAGE})
383
        @Retention(RetentionPolicy.SOURCE)
384
        @interface Registrations {
385
            Registration[] value();
386
        }
325
    }
387
    }
326
    
388
    
327
    /** Describes category of properties to be customized by given component
389
    /** Describes category of properties to be customized by given component
(-)a/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerTest.java (-11 / +16 lines)
Lines 57-63 Link Here
57
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileUtil;
58
import org.openide.filesystems.FileUtil;
59
import org.openide.loaders.DataFolder;
59
import org.openide.loaders.DataFolder;
60
import org.openide.loaders.InstanceDataObject;
61
import org.openide.util.HelpCtx;
60
import org.openide.util.HelpCtx;
62
import org.openide.util.Lookup;
61
import org.openide.util.Lookup;
63
62
Lines 107-122 Link Here
107
        //   - Three     | three
106
        //   - Three     | three
108
        // + Category #2 |
107
        // + Category #2 |
109
        //   - Four      | four
108
        //   - Four      | four
110
        InstanceDataObject.create(DataFolder.findFolder(customizerFO), null, TestCCP1.class).getPrimaryFile().setAttribute("position", 100);
111
        FileObject catFO = customizerFO.createFolder("Category1");
112
        catFO.setAttribute("displayName", "Category #1");
113
        catFO.setAttribute("position", 200);
114
        InstanceDataObject.create(DataFolder.findFolder(catFO), "Self", TestCCP2.class);
115
        InstanceDataObject.create(DataFolder.findFolder(catFO), null, TestCCP3.class);
116
        catFO = customizerFO.createFolder("Category2");
117
        catFO.setAttribute("displayName", "Category #2");
118
        catFO.setAttribute("position", 300);
119
        InstanceDataObject.create(DataFolder.findFolder(catFO), null, TestCCP4.class);
120
        DelegateCategoryProvider dcp = new DelegateCategoryProvider(DataFolder.findFolder(customizerFO), null);
109
        DelegateCategoryProvider dcp = new DelegateCategoryProvider(DataFolder.findFolder(customizerFO), null);
121
        Category categories[] = dcp.readCategories(DataFolder.findFolder(customizerFO));
110
        Category categories[] = dcp.readCategories(DataFolder.findFolder(customizerFO));
122
        assertNotNull(categories);
111
        assertNotNull(categories);
Lines 156-161 Link Here
156
            return c;
145
            return c;
157
        }
146
        }
158
    }
147
    }
148
    @CompositeCategoryProvider.Registration(
149
        projectType="test",
150
        position=100)
159
    public static class TestCCP1 extends TestCCP {
151
    public static class TestCCP1 extends TestCCP {
160
        public TestCCP1() {
152
        public TestCCP1() {
161
            super("one");
153
            super("one");
Lines 164-169 Link Here
164
            return Category.create("one", "One", null);
156
            return Category.create("one", "One", null);
165
        }
157
        }
166
    }
158
    }
159
    @CompositeCategoryProvider.Registration(
160
        projectType="test",
161
        category="Category1",
162
        categoryLabel="Category #1",
163
        position=200)
167
    public static class TestCCP2 extends TestCCP {
164
    public static class TestCCP2 extends TestCCP {
168
        public TestCCP2() {
165
        public TestCCP2() {
169
            super("two");
166
            super("two");
Lines 172-177 Link Here
172
            throw new AssertionError("Self");
169
            throw new AssertionError("Self");
173
        }
170
        }
174
    }
171
    }
172
    @CompositeCategoryProvider.Registration(
173
        projectType="test",
174
        category="Category1",
175
        position=100)
175
    public static class TestCCP3 extends TestCCP {
176
    public static class TestCCP3 extends TestCCP {
176
        public TestCCP3() {
177
        public TestCCP3() {
177
            super("three");
178
            super("three");
Lines 180-185 Link Here
180
            return Category.create("three", "Three", null);
181
            return Category.create("three", "Three", null);
181
        }
182
        }
182
    }
183
    }
184
    @CompositeCategoryProvider.Registration(
185
        projectType="test",
186
        category="Category2",
187
        position=100)
183
    public static class TestCCP4 extends TestCCP {
188
    public static class TestCCP4 extends TestCCP {
184
        public TestCCP4() {
189
        public TestCCP4() {
185
            super("four");
190
            super("four");
(-)a/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/package-info.java (+47 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 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 2009 Sun Microsystems, Inc.
38
 */
39
40
@CompositeCategoryProvider.Registration(
41
    projectType="test",
42
    category="Category2",
43
    categoryLabel="Category #2",
44
    position=300)
45
package org.netbeans.spi.project.ui.support;
46
47
import org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider;

Return to bug 171029