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

(-)a/openide.loaders/src/org/openide/loaders/InstanceDataObject.java (+2 lines)
Lines 1191-1196 Link Here
1191
        /** Uses cache to remember list of classes to them this object is
1191
        /** Uses cache to remember list of classes to them this object is
1192
        * assignable.
1192
        * assignable.
1193
        */
1193
        */
1194
        @Override
1194
        public Class instanceClass() throws IOException, ClassNotFoundException {
1195
        public Class instanceClass() throws IOException, ClassNotFoundException {
1195
            return super.instanceClass (customClassLoader);
1196
            return super.instanceClass (customClassLoader);
1196
        }
1197
        }
Lines 1198-1203 Link Here
1198
        /** Uses the cache to answer this question without loading the class itself, if the
1199
        /** Uses the cache to answer this question without loading the class itself, if the
1199
        * cache exists.
1200
        * cache exists.
1200
        */
1201
        */
1202
        @Override
1201
        public boolean instanceOf (Class type) {
1203
        public boolean instanceOf (Class type) {
1202
            // try the life object if any
1204
            // try the life object if any
1203
            FileObject fo = entry ().getFile ();
1205
            FileObject fo = entry ().getFile ();
(-)a/openide.loaders/test/unit/src/org/openide/awt/MenuBarTest.java (+66 lines)
Lines 41-51 Link Here
41
41
42
package org.openide.awt;
42
package org.openide.awt;
43
43
44
import java.awt.event.ActionEvent;
44
import java.awt.event.ContainerEvent;
45
import java.awt.event.ContainerEvent;
45
import java.awt.event.ContainerListener;
46
import java.awt.event.ContainerListener;
46
import java.io.IOException;
47
import java.io.IOException;
48
import java.io.PrintWriter;
49
import java.io.StringWriter;
50
import java.net.URL;
47
import java.util.ArrayList;
51
import java.util.ArrayList;
48
import java.util.logging.Level;
52
import java.util.logging.Level;
53
import javax.swing.AbstractAction;
49
import javax.swing.JMenu;
54
import javax.swing.JMenu;
50
import org.netbeans.junit.Log;
55
import org.netbeans.junit.Log;
51
import org.netbeans.junit.NbTestCase;
56
import org.netbeans.junit.NbTestCase;
Lines 56-63 Link Here
56
import org.openide.filesystems.FileObject;
61
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileUtil;
62
import org.openide.filesystems.FileUtil;
58
import org.openide.filesystems.Repository;
63
import org.openide.filesystems.Repository;
64
import org.openide.filesystems.XMLFileSystem;
59
import org.openide.nodes.Node;
65
import org.openide.nodes.Node;
60
import org.openide.util.HelpCtx;
66
import org.openide.util.HelpCtx;
67
import org.openide.util.Utilities;
61
import org.openide.util.actions.CallbackSystemAction;
68
import org.openide.util.actions.CallbackSystemAction;
62
69
63
/**
70
/**
Lines 75-85 Link Here
75
        super(testName);
82
        super(testName);
76
    }
83
    }
77
    
84
    
85
    @Override
78
    protected Level logLevel() {
86
    protected Level logLevel() {
79
        return Level.FINE;
87
        return Level.FINE;
80
    }
88
    }
81
89
90
    @Override
82
    protected void setUp() throws Exception {
91
    protected void setUp() throws Exception {
92
        CreateOnlyOnceAction.instancesCount = 0;
93
83
        FileObject fo = FileUtil.createFolder(
94
        FileObject fo = FileUtil.createFolder(
84
            Repository.getDefault().getDefaultFileSystem().getRoot(),
95
            Repository.getDefault().getDefaultFileSystem().getRoot(),
85
            "Folder" + getName()
96
            "Folder" + getName()
Lines 89-94 Link Here
89
        mb.waitFinished();
100
        mb.waitFinished();
90
    }
101
    }
91
102
103
    @Override
92
    protected void tearDown() throws Exception {
104
    protected void tearDown() throws Exception {
93
    }
105
    }
94
    
106
    
Lines 239-244 Link Here
239
            fail("There were warnings about the use of invalid nodes: " + seq);
251
            fail("There were warnings about the use of invalid nodes: " + seq);
240
        }
252
        }
241
    }
253
    }
254
255
    public void testActionIsCreatedOnlyOnce_13195() throws Exception {
256
        doActionIsCreatedOnlyOnce_13195("Menu");
257
    }
258
259
    public void testActionIsCreatedOnlyOnceWithNewValue() throws Exception {
260
        doActionIsCreatedOnlyOnce_13195("MenuWithNew");
261
    }
262
263
    private void doActionIsCreatedOnlyOnce_13195(String name) throws Exception {
264
        // crate XML FS from data
265
        String[] stringLayers = new String [] { "/org/openide/awt/data/testActionOnlyOnce.xml" };
266
        URL[] layers = new URL[stringLayers.length];
267
268
        for (int cntr = 0; cntr < layers.length; cntr++) {
269
            layers[cntr] = Utilities.class.getResource(stringLayers[cntr]);
270
        }
271
272
        XMLFileSystem system = new XMLFileSystem();
273
        system.setXmlUrls(layers);
274
275
        // build menu
276
        DataFolder dataFolder = DataFolder.findFolder(system.findResource(name));
277
        MenuBar menuBar = new MenuBar(dataFolder);
278
        menuBar.waitFinished();
279
280
        if (CreateOnlyOnceAction.instancesCount != 1) {
281
            // ensure that only one instance of action was created
282
            fail("Action created only once, but was: " + CreateOnlyOnceAction.instancesCount + "\n" + CreateOnlyOnceAction.w);
283
        }
284
    }
242
    
285
    
243
    public void componentAdded(ContainerEvent e) {
286
    public void componentAdded(ContainerEvent e) {
244
        add++;
287
        add++;
Lines 265-268 Link Here
265
        
308
        
266
        
309
        
267
    }
310
    }
311
312
    public static class CreateOnlyOnceAction extends AbstractAction {
313
314
        static int instancesCount = 0;
315
        static StringWriter w = new StringWriter();
316
        private static PrintWriter pw = new PrintWriter(w);
317
318
        public static synchronized CreateOnlyOnceAction create() {
319
            new Exception("created for " + (++instancesCount) + " time").printStackTrace(pw);
320
            return new CreateOnlyOnceAction();
321
        }
322
323
        public void actionPerformed(ActionEvent e) {
324
            // no op
325
        }
326
327
        private CreateOnlyOnceAction() {
328
            putValue(NAME, "TestAction");
329
        }
330
331
    }
332
333
268
}
334
}
(-)84c01928718d (+71 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
7
8
The contents of this file are subject to the terms of either the GNU
9
General Public License Version 2 only ("GPL") or the Common
10
Development and Distribution License("CDDL") (collectively, the
11
"License"). You may not use this file except in compliance with the
12
License. You can obtain a copy of the License at
13
http://www.netbeans.org/cddl-gplv2.html
14
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
specific language governing permissions and limitations under the
16
License.  When distributing the software, include this License Header
17
Notice in each file and include the License file at
18
nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun in the GPL Version 2 section of the License file that
21
accompanied this code. If applicable, add the following below the
22
License Header, with the fields enclosed by brackets [] replaced by
23
your own identifying information:
24
"Portions Copyrighted [year] [name of copyright owner]"
25
26
Contributor(s):
27
28
The Original Software is NetBeans. The Initial Developer of the Original
29
Software is Sun Microsystems, Inc. Portions Copyright 2002 Sun
30
Microsystems, Inc. All Rights Reserved.
31
32
If you wish your version of this file to be governed by only the CDDL
33
or only the GPL Version 2, indicate your decision by adding
34
"[Contributor] elects to include this software in this distribution
35
under the [CDDL or GPL Version 2] license." If you do not indicate a
36
single choice of license, a recipient has the option to distribute
37
your version of this file under either the CDDL, the GPL Version 2 or
38
to extend the choice of license to its licensees as provided above.
39
However, if you add GPL Version 2 code and therefore, elected the GPL
40
Version 2 license, then the option applies only if the new code is
41
made subject to such option by the copyright holder.
42
-->
43
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
44
45
<filesystem>
46
    
47
    <folder name="Actions">
48
        <folder name="Other">
49
           <file name="org-openide-awt-MenuBarTest$CreateOnlyOnceAction.instance">
50
                <attr name="instanceCreate" methodvalue="org.openide.awt.MenuBarTest$CreateOnlyOnceAction.create"/>
51
            </file>
52
           <file name="New.instance">
53
                <attr name="instanceCreate" newvalue="org.openide.awt.MenuBarTest$CreateOnlyOnceAction"/>
54
            </file>
55
        </folder>
56
    </folder>
57
    
58
    <folder name="Menu">
59
        <file name="org-openide-awt-MenuBarTest$CreateOnlyOnceAction.shadow">
60
            <attr name="originalFile" stringvalue="Actions/Other/org-openide-awt-MenuBarTest$CreateOnlyOnceAction.instance"/>
61
            <attr name="position" intvalue="0"/>
62
        </file>
63
    </folder>
64
    <folder name="MenuWithNew">
65
        <file name="org-openide-awt-MenuBarTest$CreateOnlyOnceAction.shadow">
66
            <attr name="originalFile" stringvalue="Actions/Other/New.instance"/>
67
            <attr name="position" intvalue="0"/>
68
        </file>
69
    </folder>
70
    
71
</filesystem>
(-)a/openide.filesystems/src/org/openide/filesystems/XMLMapAttr.java (-8 / +57 lines)
Lines 190-201 Link Here
190
        }
190
        }
191
191
192
        Object retVal = null;
192
        Object retVal = null;
193
193
        if (attr == null && "instanceClass".equals(attrName)) {
194
        try {
194
            attr = (Attr) map.get("instanceCreate");
195
            retVal = (attr == null) ? attr : attr.get(params);
195
            retVal = attr.getType(params);
196
        } catch (Exception e) {
196
        } else {
197
            ExternalUtil.annotate(e, "attrName = " + attrName); //NOI18N                                                 
197
            try {
198
            throw e;
198
                retVal = (attr == null) ? attr : attr.get(params);
199
            } catch (Exception e) {
200
                ExternalUtil.annotate(e, "attrName = " + attrName); //NOI18N
201
                throw e;
202
            }
199
        }
203
        }
200
204
201
        if (retVal instanceof ModifiedAttribute) {
205
        if (retVal instanceof ModifiedAttribute) {
Lines 733-738 Link Here
733
            }
737
            }
734
        }
738
        }
735
739
740
        final Class<?> getType(Object[] params) {
741
            try {
742
                if (obj != null) {
743
                    return obj.getClass();
744
                }
745
                switch (keyIndex) {
746
                    case 0:
747
                        return Byte.class;
748
                    case 1:
749
                        return Short.class;
750
                    case 2:
751
                        return Integer.class;
752
                    case 3:
753
                        return Long.class;
754
                    case 4:
755
                        return Float.class;
756
                    case 5:
757
                        return Double.class;
758
                    case 6:
759
                        return Boolean.class;
760
                    case 7:
761
                        return Character.class;
762
                    case 8:
763
                        return value.getClass();
764
                    case 9:
765
                        Method m = (Method) methodValue(value, params, true);
766
                        return m == null ? null : m.getReturnType();
767
                    case 10:
768
                        return null; // return decodeValue(value);
769
                    case 11:
770
                        return URL.class;
771
                    case 12:
772
                        return ExternalUtil.findClass(Utilities.translate(value));
773
                    case 13:
774
                        return String.class;
775
                }
776
            } catch (Exception ex) {
777
                Exceptions.printStackTrace(ex);
778
            }
779
            return null;
780
        }
781
736
        /** Returns class name of value object.*/
782
        /** Returns class name of value object.*/
737
        final String getClassName() {
783
        final String getClassName() {
738
            if (obj != null) {
784
            if (obj != null) {
Lines 870-876 Link Here
870
                        return value;
916
                        return value;
871
917
872
                    case 9:
918
                    case 9:
873
                        return methodValue(value, params);
919
                        return methodValue(value, params,false);
874
920
875
                    case 10:
921
                    case 10:
876
                        return decodeValue(value);
922
                        return decodeValue(value);
Lines 907-913 Link Here
907
         * @param params only 2 parametres will be used
953
         * @param params only 2 parametres will be used
908
         * @return   Object or null
954
         * @return   Object or null
909
         */
955
         */
910
        private final Object methodValue(String value, Object[] params)
956
        private final Object methodValue(String value, Object[] params, boolean justMethod)
911
        throws Exception {
957
        throws Exception {
912
            int sepIdx = value.lastIndexOf('.');
958
            int sepIdx = value.lastIndexOf('.');
913
959
Lines 957-962 Link Here
957
                        Method method = cls.getDeclaredMethod(methodName, paramArray[i]);
1003
                        Method method = cls.getDeclaredMethod(methodName, paramArray[i]);
958
1004
959
                        if (method != null) {
1005
                        if (method != null) {
1006
                            if (justMethod) {
1007
                                return method;
1008
                            }
960
                            method.setAccessible(true);
1009
                            method.setAccessible(true);
961
1010
962
                            return method.invoke(null, objArray);
1011
                            return method.invoke(null, objArray);
(-)1205560caab1 (+63 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 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 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.openide.filesystems;
41
42
/**
43
 *
44
 * @author Jaroslav Tulach <jtulach@netbeans.org>
45
 */
46
public class Count implements Runnable {
47
    static int cnt;
48
49
    public Count() {
50
        cnt++;
51
    }
52
53
    public static Count create() {
54
        return new Count();
55
    }
56
57
    public static Runnable exec() {
58
        return new Count();
59
    }
60
61
    public void run() {
62
    }
63
}
(-)a/openide.filesystems/test/unit/src/org/openide/filesystems/XMLFileSystemTestHid.java (+76 lines)
Lines 294-299 Link Here
294
        assertEquals(fo2.lastModified().getTime(), f2.lastModified());        
294
        assertEquals(fo2.lastModified().getTime(), f2.lastModified());        
295
        assertFalse(fo2.lastModified().equals(fo.lastModified()));        
295
        assertFalse(fo2.lastModified().equals(fo.lastModified()));        
296
        
296
        
297
    }
298
299
300
    public void testNoInstanceCreatedWithNewValue() throws Exception {
301
        Count.cnt = 0;
302
        File f = writeFile("layer.xml",
303
                "<filesystem>\n" +
304
                "<folder name='TestModule'>\n" +
305
                "<file name='sample.txt' >" +
306
                "  <attr name='instanceCreate' newvalue='org.openide.filesystems.Count'/>" +
307
                "</file>\n" +
308
                "</folder>\n" +
309
                "</filesystem>\n"
310
                );
311
312
        xfs = FileSystemFactoryHid.createXMLSystem(getName(), this, f.toURL());
313
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
314
        assertNotNull(fo);
315
        
316
        Object clazz = fo.getAttribute("instanceClass");
317
        assertEquals("No instance of Count created", 0, Count.cnt);
318
        assertEquals("Yet right class guessed", Count.class, clazz);
319
        Object instance = fo.getAttribute("instanceCreate");
320
        assertEquals("One instance of Count created", 1, Count.cnt);
321
        assertNotNull("Returned", instance);
322
        assertEquals("Right class", Count.class, instance.getClass());
323
    }
324
325
    public void testNoInstanceCreatedWithMethodValue1() throws Exception {
326
        Count.cnt = 0;
327
        File f = writeFile("layer.xml",
328
                "<filesystem>\n" +
329
                "<folder name='TestModule'>\n" +
330
                "<file name='sample.txt' >" +
331
                "  <attr name='instanceCreate' methodvalue='org.openide.filesystems.Count.create'/>" +
332
                "</file>\n" +
333
                "</folder>\n" +
334
                "</filesystem>\n"
335
                );
336
337
        xfs = FileSystemFactoryHid.createXMLSystem(getName(), this, f.toURL());
338
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
339
        assertNotNull(fo);
340
341
        Object clazz = fo.getAttribute("instanceClass");
342
        assertEquals("No instance of Count created", 0, Count.cnt);
343
        assertEquals("Yet right class guessed", Count.class, clazz);
344
        Object instance = fo.getAttribute("instanceCreate");
345
        assertEquals("One instance of Count created", 1, Count.cnt);
346
        assertNotNull("Returned", instance);
347
        assertEquals("Right class", Count.class, instance.getClass());
348
    }
349
350
    public void testNoInstanceCreatedWithMethodValue2() throws Exception {
351
        Count.cnt = 0;
352
        File f = writeFile("layer.xml",
353
                "<filesystem>\n" +
354
                "<folder name='TestModule'>\n" +
355
                "<file name='sample.txt' >" +
356
                "  <attr name='instanceCreate' methodvalue='org.openide.filesystems.Count.exec'/>" +
357
                "</file>\n" +
358
                "</folder>\n" +
359
                "</filesystem>\n"
360
                );
361
362
        xfs = FileSystemFactoryHid.createXMLSystem(getName(), this, f.toURL());
363
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
364
        assertNotNull(fo);
365
366
        Object clazz = fo.getAttribute("instanceClass");
367
        assertEquals("No instance of Count created", 0, Count.cnt);
368
        assertEquals("Only Runnable guessed as that is the return type of the method", Runnable.class, clazz);
369
        Object instance = fo.getAttribute("instanceCreate");
370
        assertEquals("One instance of Count created", 1, Count.cnt);
371
        assertNotNull("Returned", instance);
372
        assertEquals("Right class", Count.class, instance.getClass());
297
    }
373
    }
298
374
299
    
375
    
(-)a/core.startup/src/org/netbeans/core/startup/layers/BinaryFS.java (-2 / +42 lines)
Lines 367-372 Link Here
367
        public Object getAttribute(String attrName) {
367
        public Object getAttribute(String attrName) {
368
            initialize();
368
            initialize();
369
            AttrImpl attr = attrs.get(attrName);
369
            AttrImpl attr = attrs.get(attrName);
370
            if (attr == null && attrName.startsWith("class:")) {
371
                attr = attrs.get(attrName.substring(6));
372
                return attr == null ? null : attr.getType(this);
373
            }
374
370
            return (attr != null) ? attr.getValue(this, attrName) : null;
375
            return (attr != null) ? attr.getValue(this, attrName) : null;
371
        }
376
        }
372
        
377
        
Lines 482-488 Link Here
482
                    case 9: // urlvalue
487
                    case 9: // urlvalue
483
                        return new URL(value);
488
                        return new URL(value);
484
                    case 10: // methodvalue
489
                    case 10: // methodvalue
485
                        return methodValue (value,foProvider,attrName);
490
                        return methodValue (value,foProvider,attrName, false);
486
                    case 11: // newvalue
491
                    case 11: // newvalue
487
                        Class<?> cls =  findClass (value);
492
                        Class<?> cls =  findClass (value);
488
                        // special support for singletons
493
                        // special support for singletons
Lines 506-514 Link Here
506
            }
511
            }
507
            return null; // problem getting the value...
512
            return null; // problem getting the value...
508
        }
513
        }
514
        public Object getType( BFSBase foProvider) {
515
            try {
516
                switch(index) {
517
                    case 0: return Byte.class;
518
                    case 1: return Short.class;
519
                    case 2: return Integer.class;
520
                    case 3: return Long.class;
521
                    case 4: return Float.class;
522
                    case 5: return Double.class;
523
                    case 6: return Boolean.class;
524
                    case 7: return Character.class;
525
                    case 8: return String.class;
526
                    case 9: return URL.class;
527
                    case 10: // methodvalue
528
                        Method m = (Method)methodValue (value,foProvider,null, true);
529
                        return m == null ? null : m.getReturnType();
530
                    case 11: // newvalue
531
                        return findClass (value);
532
                    case 12: // serialvalue
533
                        return null;
534
                    case 13: // bundle value
535
                        return String.class;
536
                    default:
537
                        throw new IllegalStateException("Bad index: " + index); // NOI18N
538
                }
539
            } catch (Exception exc) {
540
                Exceptions.attachMessage(exc, "value = " + value + " from " + foProvider.getPath()); //NOI18N
541
                Logger.getLogger(BinaryFS.class.getName()).log(Level.WARNING, null, exc);
542
            }
543
            return null; // problem getting the value...
544
        }
509
545
510
        /** Constructs new attribute as Object. Used for dynamic creation: methodvalue. */
546
        /** Constructs new attribute as Object. Used for dynamic creation: methodvalue. */
511
        private Object methodValue(String method, BFSBase foProvider, String attr) throws Exception {
547
        private Object methodValue(String method, BFSBase foProvider, String attr, boolean onlyMethod) throws Exception {
512
            int i = method.lastIndexOf('.');
548
            int i = method.lastIndexOf('.');
513
            if (i != -1) {
549
            if (i != -1) {
514
                // Cf. XMLMapAttr.Attr.methodValue:
550
                // Cf. XMLMapAttr.Attr.methodValue:
Lines 537-542 Link Here
537
                            values[j] = wrapToMap(foProvider.getFileObjectForAttr());
573
                            values[j] = wrapToMap(foProvider.getFileObjectForAttr());
538
                        }
574
                        }
539
                    }
575
                    }
576
                    if (onlyMethod) {
577
                        return m;
578
                    }
579
540
                    m.setAccessible(true); //otherwise cannot invoke private
580
                    m.setAccessible(true); //otherwise cannot invoke private
541
                    return m.invoke(null, values);
581
                    return m.invoke(null, values);
542
                }
582
                }
(-)a/openide.filesystems/apichanges.xml (+24 lines)
Lines 46-51 Link Here
46
        <apidef name="filesystems">Filesystems API</apidef>
46
        <apidef name="filesystems">Filesystems API</apidef>
47
    </apidefs>
47
    </apidefs>
48
    <changes>
48
    <changes>
49
        <change id="getAttribute.class">
50
            <api name="filesystems"/>
51
            <summary>XMLFileSystem attributes can be queried for instance class</summary>
52
            <version major="7" minor="12"/>
53
            <date day="20" month="8" year="2008"/>
54
            <author login="jskrivanek"/>
55
            <compatibility addition="yes"/>
56
            <description>
57
                <p>
58
                    If you are interested just in the class of an attribute, but
59
                    without creating its instance, use <code>fileObject.getAttribute("class:attrName")</code>.
60
                    This instructs the <a href="@TOP@/org/openide/filesystems/XMLFileSystem.html">XMLFileSystem</a>
61
                    to scan its XML files for definition of <code>attrName</code>
62
                    attribute and <i>guess</i> its class. The <i>guessing</i> is
63
                    usually easy, just for <code>methodvalue</code> types, the system
64
                    needs to use some kind of heuristic: it locates the
65
                    appropriate factory method and returns its return type. This may
66
                    not be the actual type of the returned object at the end, but
67
                    it seems as the best guess without instantiating it.
68
                </p>
69
            </description>
70
            <class package="org.openide.filesystems" name="XMLFileSystem"/>
71
            <issue number="131951"/>
72
        </change>
49
        <change id="testable-declarative-resolvers">
73
        <change id="testable-declarative-resolvers">
50
            <api name="filesystems"/>
74
            <api name="filesystems"/>
51
            <summary>Declarative MIME resolvers now available in standalone mode</summary>
75
            <summary>Declarative MIME resolvers now available in standalone mode</summary>
(-)a/openide.filesystems/arch.xml (-1 / +13 lines)
Lines 357-363 Link Here
357
        </question>
357
        </question>
358
-->
358
-->
359
<answer id="exec-component">
359
<answer id="exec-component">
360
No.
360
<api name="getAttribute.class" category="stable" group="property" type="export">
361
    If you are interested just in the class of an 
362
    <a href="@TOP@/org/openide/filesystems/FileObject.html">FileObject</a> attribute, but
363
    without creating its instance, use <code>fileObject.getAttribute("class:attrName")</code>.
364
    This instructs the <a href="@TOP@/org/openide/filesystems/XMLFileSystem.html">XMLFileSystem</a>
365
    to scan its XML files for definition of <code>attrName</code>
366
    attribute and <i>guess</i> its class. The <i>guessing</i> is
367
    usually easy, just for <code>methodvalue</code> types, the system
368
    needs to use some kind of heuristic: it locates the
369
    appropriate factory method and returns its return type. This may
370
    not be the actual type of the returned object at the end, but
371
    it seems as the best guess without instantiating it.
372
</api>
361
</answer>
373
</answer>
362
374
363
375
(-)a/openide.filesystems/nbproject/project.properties (-1 / +1 lines)
Lines 43-46 Link Here
43
javadoc.main.page=org/openide/filesystems/doc-files/api.html
43
javadoc.main.page=org/openide/filesystems/doc-files/api.html
44
javadoc.arch=${basedir}/arch.xml
44
javadoc.arch=${basedir}/arch.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
46
spec.version.base=7.11.0
46
spec.version.base=7.12.0
(-)a/openide.filesystems/src/org/openide/filesystems/XMLMapAttr.java (-2 / +2 lines)
Lines 190-197 Link Here
190
        }
190
        }
191
191
192
        Object retVal = null;
192
        Object retVal = null;
193
        if (attr == null && "instanceClass".equals(attrName)) {
193
        if (attr == null && origAttrName.startsWith("class:")) { // NOI18N
194
            attr = (Attr) map.get("instanceCreate");
194
            attr = (Attr) map.get(origAttrName.substring(6));
195
            retVal = attr.getType(params);
195
            retVal = attr.getType(params);
196
        } else {
196
        } else {
197
            try {
197
            try {
(-)a/openide.filesystems/test/unit/src/org/openide/filesystems/XMLFileSystemTestHid.java (-3 / +56 lines)
Lines 313-319 Link Here
313
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
313
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
314
        assertNotNull(fo);
314
        assertNotNull(fo);
315
        
315
        
316
        Object clazz = fo.getAttribute("instanceClass");
316
        Object clazz = fo.getAttribute("class:instanceCreate");
317
        assertEquals("No instance of Count created", 0, Count.cnt);
317
        assertEquals("No instance of Count created", 0, Count.cnt);
318
        assertEquals("Yet right class guessed", Count.class, clazz);
318
        assertEquals("Yet right class guessed", Count.class, clazz);
319
        Object instance = fo.getAttribute("instanceCreate");
319
        Object instance = fo.getAttribute("instanceCreate");
Lines 338-344 Link Here
338
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
338
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
339
        assertNotNull(fo);
339
        assertNotNull(fo);
340
340
341
        Object clazz = fo.getAttribute("instanceClass");
341
        Object clazz = fo.getAttribute("class:instanceCreate");
342
        assertEquals("No instance of Count created", 0, Count.cnt);
342
        assertEquals("No instance of Count created", 0, Count.cnt);
343
        assertEquals("Yet right class guessed", Count.class, clazz);
343
        assertEquals("Yet right class guessed", Count.class, clazz);
344
        Object instance = fo.getAttribute("instanceCreate");
344
        Object instance = fo.getAttribute("instanceCreate");
Lines 363-369 Link Here
363
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
363
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
364
        assertNotNull(fo);
364
        assertNotNull(fo);
365
365
366
        Object clazz = fo.getAttribute("instanceClass");
366
        Object clazz = fo.getAttribute("class:instanceCreate");
367
        assertEquals("No instance of Count created", 0, Count.cnt);
367
        assertEquals("No instance of Count created", 0, Count.cnt);
368
        assertEquals("Only Runnable guessed as that is the return type of the method", Runnable.class, clazz);
368
        assertEquals("Only Runnable guessed as that is the return type of the method", Runnable.class, clazz);
369
        Object instance = fo.getAttribute("instanceCreate");
369
        Object instance = fo.getAttribute("instanceCreate");
Lines 372-377 Link Here
372
        assertEquals("Right class", Count.class, instance.getClass());
372
        assertEquals("Right class", Count.class, instance.getClass());
373
    }
373
    }
374
374
375
    public void testClassBoolean() throws Exception {
376
        doPrimitiveTypeTest("boolvalue='true'", Boolean.class);
377
    }
378
379
    public void testClassByte() throws Exception {
380
        doPrimitiveTypeTest("bytevalue='1'", Byte.class);
381
    }
382
383
    public void testClassInt() throws Exception {
384
        doPrimitiveTypeTest("intvalue='1'", Integer.class);
385
    }
386
387
    public void testClassShort() throws Exception {
388
        doPrimitiveTypeTest("shortvalue='1'", Short.class);
389
    }
390
391
    public void testClassLong() throws Exception {
392
        doPrimitiveTypeTest("longvalue='1'", Long.class);
393
    }
394
    public void testClassDouble() throws Exception {
395
        doPrimitiveTypeTest("doublevalue='1.0'", Double.class);
396
    }
397
    public void testClassFloat() throws Exception {
398
        doPrimitiveTypeTest("floatvalue='1.0'", Float.class);
399
    }
400
    public void testClassString() throws Exception {
401
        doPrimitiveTypeTest("stringvalue='1'", String.class);
402
    }
403
    public void testClassURL() throws Exception {
404
        doPrimitiveTypeTest("urlvalue='http://www.netbeans.org'", URL.class);
405
    }
406
407
    private void doPrimitiveTypeTest(String value, Class<?> expClass) throws Exception {
408
        File f = writeFile("layer.xml",
409
                "<filesystem>\n" +
410
                "<folder name='TestModule'>\n" +
411
                "<file name='sample.txt' >" +
412
                "  <attr name='instanceCreate' " + value + "/>" +
413
                "</file>\n" +
414
                "</folder>\n" +
415
                "</filesystem>\n"
416
                );
417
418
        xfs = FileSystemFactoryHid.createXMLSystem(getName(), this, f.toURL());
419
        FileObject fo = xfs.findResource ("TestModule/sample.txt");
420
        assertNotNull(fo);
421
422
        Object clazz = fo.getAttribute("class:instanceCreate");
423
        assertEquals("Only Runnable guessed as that is the return type of the method", expClass, clazz);
424
        Object instance = fo.getAttribute("instanceCreate");
425
        assertNotNull("Returned", instance);
426
        assertEquals("Right class", expClass, instance.getClass());
427
    }
375
    
428
    
376
    
429
    
377
    private File writeFile(String name, String content) throws IOException {
430
    private File writeFile(String name, String content) throws IOException {
(-)a/openide.loaders/src/org/openide/loaders/InstanceDataObject.java (+8 lines)
Lines 1147-1157 Link Here
1147
        private static String getClassName(FileObject fo) {
1147
        private static String getClassName(FileObject fo) {
1148
            // first of all try "instanceClass" property of the primary file
1148
            // first of all try "instanceClass" property of the primary file
1149
            Object attr = fo.getAttribute (EA_INSTANCE_CLASS);
1149
            Object attr = fo.getAttribute (EA_INSTANCE_CLASS);
1150
            if (attr instanceof Class) {
1151
                return ((Class)attr).getName();
1152
            }
1150
            if (attr instanceof String) {
1153
            if (attr instanceof String) {
1151
                return Utilities.translate((String) attr);
1154
                return Utilities.translate((String) attr);
1152
            } else if (attr != null) {
1155
            } else if (attr != null) {
1153
                err.warning(
1156
                err.warning(
1154
                    "instanceClass was a " + attr.getClass().getName()); // NOI18N
1157
                    "instanceClass was a " + attr.getClass().getName()); // NOI18N
1158
            }
1159
            
1160
            attr = fo.getAttribute ("class:" + EA_INSTANCE_CREATE);
1161
            if (attr instanceof Class) {
1162
                return ((Class)attr).getName();
1155
            }
1163
            }
1156
1164
1157
            attr = fo.getAttribute (EA_INSTANCE_CREATE);
1165
            attr = fo.getAttribute (EA_INSTANCE_CREATE);
(-)a/openide.loaders/test/unit/src/org/openide/awt/MenuBarTest.java (-5 / +8 lines)
Lines 52-57 Link Here
52
import java.util.logging.Level;
52
import java.util.logging.Level;
53
import javax.swing.AbstractAction;
53
import javax.swing.AbstractAction;
54
import javax.swing.JMenu;
54
import javax.swing.JMenu;
55
import javax.swing.SwingUtilities;
55
import org.netbeans.junit.Log;
56
import org.netbeans.junit.Log;
56
import org.netbeans.junit.NbTestCase;
57
import org.netbeans.junit.NbTestCase;
57
import org.openide.actions.OpenAction;
58
import org.openide.actions.OpenAction;
Lines 90-95 Link Here
90
    @Override
91
    @Override
91
    protected void setUp() throws Exception {
92
    protected void setUp() throws Exception {
92
        CreateOnlyOnceAction.instancesCount = 0;
93
        CreateOnlyOnceAction.instancesCount = 0;
94
        CreateOnlyOnceAction.w = new StringWriter();
95
        CreateOnlyOnceAction.pw = new PrintWriter(CreateOnlyOnceAction.w);
93
96
94
        FileObject fo = FileUtil.createFolder(
97
        FileObject fo = FileUtil.createFolder(
95
            Repository.getDefault().getDefaultFileSystem().getRoot(),
98
            Repository.getDefault().getDefaultFileSystem().getRoot(),
Lines 282-288 Link Here
282
            fail("Action created only once, but was: " + CreateOnlyOnceAction.instancesCount + "\n" + CreateOnlyOnceAction.w);
285
            fail("Action created only once, but was: " + CreateOnlyOnceAction.instancesCount + "\n" + CreateOnlyOnceAction.w);
283
        }
286
        }
284
    }
287
    }
285
    
288
286
    public void componentAdded(ContainerEvent e) {
289
    public void componentAdded(ContainerEvent e) {
287
        add++;
290
        add++;
288
    }
291
    }
Lines 312-322 Link Here
312
    public static class CreateOnlyOnceAction extends AbstractAction {
315
    public static class CreateOnlyOnceAction extends AbstractAction {
313
316
314
        static int instancesCount = 0;
317
        static int instancesCount = 0;
315
        static StringWriter w = new StringWriter();
318
        static StringWriter w;
316
        private static PrintWriter pw = new PrintWriter(w);
319
        static PrintWriter pw;
317
320
318
        public static synchronized CreateOnlyOnceAction create() {
321
        public static synchronized CreateOnlyOnceAction create() {
319
            new Exception("created for " + (++instancesCount) + " time").printStackTrace(pw);
320
            return new CreateOnlyOnceAction();
322
            return new CreateOnlyOnceAction();
321
        }
323
        }
322
324
Lines 324-330 Link Here
324
            // no op
326
            // no op
325
        }
327
        }
326
328
327
        private CreateOnlyOnceAction() {
329
        public CreateOnlyOnceAction() {
330
            new Exception("created for " + (++instancesCount) + " time").printStackTrace(pw);
328
            putValue(NAME, "TestAction");
331
            putValue(NAME, "TestAction");
329
        }
332
        }
330
333

Return to bug 131951