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

(-)b3bbc4d76b98 (+53 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
7
The contents of this file are subject to the terms of either the GNU
8
General Public License Version 2 only ("GPL") or the Common
9
Development and Distribution License("CDDL") (collectively, the
10
"License"). You may not use this file except in compliance with the
11
License. You can obtain a copy of the License at
12
http://www.netbeans.org/cddl-gplv2.html
13
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
14
specific language governing permissions and limitations under the
15
License.  When distributing the software, include this License Header
16
Notice in each file and include the License file at
17
nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
18
particular file as subject to the "Classpath" exception as provided
19
by Sun in the GPL Version 2 section of the License file that
20
accompanied this code. If applicable, add the following below the
21
License Header, with the fields enclosed by brackets [] replaced by
22
your own identifying information:
23
"Portions Copyrighted [year] [name of copyright owner]"
24
25
Contributor(s):
26
27
The Original Software is NetBeans. The Initial Developer of the Original
28
Software is Sun Microsystems, Inc. Portions Copyright 2002 Sun
29
Microsystems, Inc. All Rights Reserved.
30
31
If you wish your version of this file to be governed by only the CDDL
32
or only the GPL Version 2, indicate your decision by adding
33
"[Contributor] elects to include this software in this distribution
34
under the [CDDL or GPL Version 2] license." If you do not indicate a
35
single choice of license, a recipient has the option to distribute
36
your version of this file under either the CDDL, the GPL Version 2 or
37
to extend the choice of license to its licensees as provided above.
38
However, if you add GPL Version 2 code and therefore, elected the GPL
39
Version 2 license, then the option applies only if the new code is
40
made subject to such option by the copyright holder.
41
-->
42
43
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
44
45
<HTML>
46
  <HEAD>
47
    <TITLE>org.netbeans.api.settings package</TITLE>
48
  </HEAD>
49
  <BODY>
50
      This package provides annotations to simplify use of
51
      <a href="http://top/org/netbeans/spi/settings/doc-files/api.html">convertors</a>.
52
  </BODY>
53
</HTML>
(-)b3bbc4d76b98 (+47 lines)
Added Link Here
1
2
package org.netbeans.api.settings;
3
4
import java.lang.annotation.ElementType;
5
import java.lang.annotation.Retention;
6
import java.lang.annotation.RetentionPolicy;
7
import java.lang.annotation.Target;
8
import java.util.Properties;
9
10
/** Annotation to attach to object that is wishing to support conversion from
11
 * and to {@link Properties}. More info about the format and protocol
12
 * <a href="../../spi/settings/doc-files/api.html#xmlprops">is available</a> in separate document,
13
 * here is the shortest possible howto:
14
 * <pre>
15
 * <code>@</code>ConvertAsProperties(dtd="-//Your Org//Your Setting//EN")
16
 * <font class="type">public class</font> YourObject {
17
 *   <font class="type">public</font> YourObject() {} // public constructor is a must
18
 *   <font class="type">void</font> <font class="function-name">readProperties</font>(java.util.<font class="type">Properties</font> <font class="variable-name">p</font>) {
19
 *     // do the read
20
 *   }
21
 *   <font class="type">void</font> <font class="function-name">writeProperties</font>(java.util.<font class="type">Properties</font> <font class="variable-name">p</font>) {
22
 *     // handle the store
23
 *   }
24
 * }
25
 * </pre>
26
 *
27
 * @author Jaroslav Tulach <jtulach@netbeans.org>
28
 * @since 1.18
29
 */
30
@Retention(RetentionPolicy.SOURCE)
31
@Target(ElementType.TYPE)
32
public @interface ConvertAsProperties {
33
    /** Public ID of the XML file that results in creation of the
34
     * annotated type and to which the annotated type can be converted.
35
     * @return public ID of the file's DTD
36
     */
37
    String dtd();
38
    /** Shall every change in the object result in save? Or shall the
39
     * object just be marked as dirty?
40
     */
41
    boolean autostore() default true;
42
    /** An array of properties that are ignored without marking the object
43
     * as dirty or saving it.
44
     * @return array of property names or "all" to ignore all properties
45
     */
46
    String[] ignoreChanges() default {};
47
}
(-)b3bbc4d76b98 (+262 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.settings.convertors;
43
44
import java.util.Set;
45
import javax.annotation.processing.Processor;
46
import javax.annotation.processing.RoundEnvironment;
47
import javax.annotation.processing.SupportedAnnotationTypes;
48
import javax.annotation.processing.SupportedSourceVersion;
49
import javax.lang.model.SourceVersion;
50
import javax.lang.model.element.Element;
51
import javax.lang.model.element.ExecutableElement;
52
import javax.lang.model.element.Modifier;
53
import javax.lang.model.element.TypeElement;
54
import javax.lang.model.type.TypeMirror;
55
import javax.lang.model.util.ElementFilter;
56
import org.netbeans.api.settings.ConvertAsProperties;
57
import org.openide.filesystems.annotations.LayerBuilder.File;
58
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
59
import org.openide.filesystems.annotations.LayerGenerationException;
60
import org.openide.util.lookup.ServiceProvider;
61
import org.xml.sax.SAXException;
62
import org.xml.sax.helpers.DefaultHandler;
63
64
/** Processor to hide all the complexities of settings layer registration.
65
 *
66
 * @author Jaroslav Tulach <jtulach@netbeans.org>
67
 */
68
@ServiceProvider(service=Processor.class)
69
@SupportedSourceVersion(SourceVersion.RELEASE_6)
70
@SupportedAnnotationTypes("org.netbeans.api.settings.ConvertAsProperties")//NOI18N
71
public class ConvertorProcessor extends LayerGeneratingProcessor {
72
73
74
    @Override
75
    protected boolean handleProcess(
76
        Set<? extends TypeElement> annotations,
77
        RoundEnvironment env
78
    ) throws LayerGenerationException {
79
        for (Element e : env.getElementsAnnotatedWith(ConvertAsProperties.class)) {
80
            ConvertAsProperties reg = e.getAnnotation(ConvertAsProperties.class);
81
82
            String[] convElem = instantiableClassOrMethod(e, null);
83
            final String dtd = reg.dtd();
84
85
            String dtdCode = convertPublicId(dtd);
86
            System.err.println("dtd: " + dtd);
87
            System.err.println("mod: " + dtdCode);
88
89
                /*
90
            <folder name="xml">
91
             <folder name="entities">
92
              <folder name="NetBeans_org_netbeans_modules_settings_xtest">
93
                <file name="DTD_XML_FooSetting_1_0" url="nbres:/org/netbeans/modules/settings/resources/properties-1_0.dtd">
94
                    <attr name="hint.originalPublicID" stringvalue="-//NetBeans org.netbeans.modules.settings.xtest//DTD XML FooSetting 1.0//EN"/>
95
                 */
96
            layer(e).file("xml/entities" + dtdCode).
97
                url("nbres:/org/netbeans/modules/settings/resources/properties-1_0.dtd").
98
                stringvalue("hint.originalPublicID", dtd).write();
99
       /*
100
        <folder name="memory">
101
            <folder name="org">
102
                <folder name="netbeans">
103
                    <folder name="modules">
104
                        <folder name="settings">
105
                            <folder name="convertors">
106
                                <file name="FooSetting">
107
                                    <attr name="settings.providerPath"
108
                                    stringvalue="xml/lookups/NetBeans_org_netbeans_modules_settings_xtest/DTD_XML_FooSetting_1_0.instance"/>
109
           */
110
            layer(e).file("xml/memory/" + convElem[0].replace('.', '/')).
111
                stringvalue("settings.providerPath", "xml/lookups/" + dtdCode + ".instance").
112
                write();
113
114
       /*
115
        <folder name="lookups">
116
            <folder name="NetBeans_org_netbeans_modules_settings_xtest">
117
                <file name="DTD_XML_FooSetting_1_0.instance">
118
                    <attr name="instanceCreate" methodvalue="org.netbeans.api.settings.Factory.create"/>
119
                    <attr name="settings.convertor" methodvalue="org.netbeans.api.settings.Factory.properties"/>
120
                    <attr name="settings.instanceClass" stringvalue="org.netbeans.modules.settings.convertors.FooSetting"/>
121
                    <attr name="settings.instanceOf" stringvalue="org.netbeans.modules.settings.convertors.FooSetting"/>
122
                </file>
123
            </folder>
124
        */
125
            File f = layer(e).file("xml/lookups" + dtdCode + ".instance").
126
                methodvalue("instanceCreate", "org.netbeans.api.settings.Factory", "create").
127
                methodvalue("settings.convertor", "org.netbeans.api.settings.Factory", "properties").
128
                stringvalue("settings.instanceClass", convElem[0]).
129
                stringvalue("settings.instanceOf", convElem[0]).
130
                boolvalue("xmlproperties.preventStoring", !reg.autostore());
131
            commaSeparated(f, reg.ignoreChanges()).write();
132
        }
133
        return false;
134
    }
135
136
    /** Copied from FileEntityResolver from o.n.core module.
137
     */
138
    @SuppressWarnings("fallthrough")
139
    private static String convertPublicId (String publicID) {
140
        char[] arr = publicID.toCharArray ();
141
142
143
        int numberofslashes = 0;
144
        int state = 0;
145
        int write = 0;
146
        OUT: for (int i = 0; i < arr.length; i++) {
147
            char ch = arr[i];
148
149
            switch (state) {
150
            case 0:
151
                // initial state
152
                if (ch == '+' || ch == '-' || ch == 'I' || ch == 'S' || ch == 'O') {
153
                    // do not write that char
154
                    continue;
155
                }
156
                // switch to regular state
157
                state = 1;
158
                // fallthru
159
            case 1:
160
                // regular state expecting any character
161
                if (ch == '/') {
162
                    state = 2;
163
                    if (++numberofslashes == 3) {
164
                        // last part of the ID, exit
165
                        break OUT;
166
                    }
167
                    arr[write++] = '/';
168
                    continue;
169
                }
170
                break;
171
            case 2:
172
                // previous character was /
173
                if (ch == '/') {
174
                    // ignore second / and write nothing
175
                    continue;
176
                }
177
                state = 1;
178
                break;
179
            }
180
181
            // write the char into the array
182
            if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
183
                arr[write++] = ch;
184
            } else {
185
                arr[write++] = '_';
186
            }
187
        }
188
189
        return new String (arr, 0, write);
190
    }
191
192
    private static File commaSeparated(File f, String[] arr) {
193
        if (arr.length == 0) {
194
            return f;
195
        }
196
197
        StringBuilder sb = new StringBuilder();
198
        String sep = "";
199
        for (String s : arr) {
200
            sb.append(sep);
201
            sb.append(s);
202
            sep = ",";
203
        }
204
        return f.stringvalue("xmlproperties.ignoreChanges", sb.toString());
205
    }
206
207
    private String[] instantiableClassOrMethod(Element e, Class type) throws IllegalArgumentException, LayerGenerationException {
208
        TypeMirror typeMirror = type != null ? processingEnv.getElementUtils().getTypeElement(type.getName().replace('$', '.')).asType() : null;
209
        switch (e.getKind()) {
210
            case CLASS: {
211
                String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e).toString();
212
                if (e.getModifiers().contains(Modifier.ABSTRACT)) {
213
                    throw new LayerGenerationException(clazz + " must not be abstract", e);
214
                }
215
                {
216
                    boolean hasDefaultCtor = false;
217
                    for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
218
                        if (constructor.getParameters().isEmpty()) {
219
                            hasDefaultCtor = true;
220
                            break;
221
                        }
222
                    }
223
                    if (!hasDefaultCtor) {
224
                        throw new LayerGenerationException(clazz + " must have a no-argument constructor", e);
225
                    }
226
                }
227
                if (typeMirror != null && !processingEnv.getTypeUtils().isAssignable(e.asType(), typeMirror)) {
228
                    throw new LayerGenerationException(clazz + " is not assignable to " + typeMirror, e);
229
                }
230
                return new String[] {clazz, null};
231
            }
232
            case METHOD: {
233
                String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) e.getEnclosingElement()).toString();
234
                String method = e.getSimpleName().toString();
235
                if (!e.getModifiers().contains(Modifier.STATIC)) {
236
                    throw new LayerGenerationException(clazz + "." + method + " must be static", e);
237
                }
238
                if (!((ExecutableElement) e).getParameters().isEmpty()) {
239
                    throw new LayerGenerationException(clazz + "." + method + " must not take arguments", e);
240
                }
241
                if (typeMirror != null && !processingEnv.getTypeUtils().isAssignable(((ExecutableElement) e).getReturnType(), typeMirror)) {
242
                    throw new LayerGenerationException(clazz + "." + method + " is not assignable to " + typeMirror, e);
243
                }
244
                return new String[] {clazz, method};
245
            }
246
            default:
247
                throw new IllegalArgumentException("Annotated element is not loadable as an instance: " + e);
248
        }
249
    }
250
251
    private static final class Parser extends DefaultHandler {
252
253
        @Override
254
        public void notationDecl(String name, String publicId, String systemId) throws SAXException {
255
            super.notationDecl(name, publicId, systemId);
256
            System.err.println("pub: " + publicId);
257
            System.err.println("sys: " + systemId);
258
            System.err.println("name: " + name);
259
        }
260
261
    }
262
}
(-)b3bbc4d76b98 (+93 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 2002 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.settings.convertors;
43
44
import java.io.*;
45
46
import java.util.Properties;
47
import org.netbeans.junit.NbTestCase;
48
49
50
import org.netbeans.api.settings.ConvertAsProperties;
51
import org.netbeans.spi.settings.Convertor;
52
53
import org.openide.filesystems.FileObject;
54
import org.openide.filesystems.Repository;
55
56
/** Checks usage of annotation to assign XML properties convertor.
57
 *
58
 * @author Jaroslav Tulach
59
 */
60
public final class XMLPropertiesConvertorAnnotationTest extends NbTestCase {
61
    /** Creates a new instance of XMLPropertiesConvertorTest */
62
    public XMLPropertiesConvertorAnnotationTest(String name) {
63
        super(name);
64
    }
65
    
66
    public void testReadWrite() throws Exception {
67
        FileObject dtdFO = Repository.getDefault().getDefaultFileSystem().
68
            findResource("/xml/lookups/NetBeans_org_netbeans_modules_settings_xtest/DTD_XML_FooSetting_2_0.instance");
69
        assertNotNull("Provider not found", dtdFO);
70
        Convertor c = XMLPropertiesConvertor.create(dtdFO);
71
        AnnoFoo foo = new AnnoFoo();
72
        foo.setProperty1("xxx");
73
        CharArrayWriter caw = new CharArrayWriter(1024);
74
        c.write(caw, foo);
75
        caw.flush();
76
        caw.close();
77
        CharArrayReader car = new CharArrayReader(caw.toCharArray());
78
        Object obj = c.read(car);
79
        assertEquals(foo, obj);
80
    }
81
82
    @ConvertAsProperties(
83
        dtd="-//NetBeans org.netbeans.modules.settings.xtest//DTD XML FooSetting 2.0//EN"
84
    )
85
    public static class AnnoFoo extends FooSetting {
86
        public void readProperties(Properties p) {
87
            this.setProperty1(p.getProperty("p1"));
88
        }
89
        public void writeProperties(Properties p) {
90
            p.setProperty("p1", this.getProperty1());
91
        }
92
    }
93
}

Return to bug 155962