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

(-)openide/loaders/src/org/openide/loaders/DataLdrActions.java (+181 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.openide.loaders;
15
16
import java.beans.*;
17
import java.io.*;
18
import java.util.*;
19
20
import org.openide.ErrorManager;
21
import org.openide.cookies.InstanceCookie;
22
import org.openide.filesystems.*;
23
import org.openide.nodes.NodeOp;
24
import org.openide.util.Lookup;
25
import org.openide.util.NbBundle;
26
import org.openide.util.SharedClassObject;
27
import org.openide.util.Utilities;
28
import org.openide.util.actions.SystemAction;
29
import org.openide.util.io.SafeException;
30
31
/** Manages actions read and write for a given loader.
32
 *
33
 * @author Jaroslav Tulach
34
 */
35
final class DataLdrActions extends FolderInstance {
36
    /** Reference<DataLoader> to know for what loader we work */
37
    private java.lang.ref.Reference ref;
38
    /** last creating task */
39
    private org.openide.util.Task creation;
40
    /** processor to use */
41
    private static org.openide.util.RequestProcessor RP = new org.openide.util.RequestProcessor ("Loader Actions");
42
    
43
    public DataLdrActions (DataFolder f, DataLoader l) {
44
        super (f);
45
        
46
        this.ref = new java.lang.ref.WeakReference (l);
47
    }
48
    
49
    /** Asks the manager to store these actions to disk. Provided for
50
     * backward compatibility.
51
     */
52
    public synchronized void setActions (final SystemAction[] arr) {
53
        class DoTheWork implements Runnable, FileSystem.AtomicAction {
54
            private int state;
55
            
56
            /** The goal of this method is to make sure that all actions
57
             * will really be stored on the disk.
58
             */
59
            private void work () throws IOException {
60
                DataObject[] now = folder.getChildren ();
61
                HashMap nowToObj = new HashMap ();
62
                LinkedList sepObjs = new LinkedList ();
63
                for (int i = 0; i < now.length; i++) {
64
                    InstanceCookie ic = (InstanceCookie)now[i].getCookie (InstanceCookie.class);
65
                    if (ic != null) {
66
                        try {
67
                            Object instance = ic.instanceCreate ();
68
                            if (instance instanceof javax.swing.Action) {
69
                                nowToObj.put (instance, now[i]);
70
                                continue;
71
                            }
72
                            if (instance instanceof javax.swing.JSeparator) {
73
                                sepObjs.add (now[i]);
74
                                continue;
75
                            }
76
                        } catch (ClassNotFoundException ex) {
77
                            ErrorManager.getDefault ().notify (ex);
78
                        }
79
                    }
80
                }
81
                
82
                ArrayList order = new ArrayList ();
83
                
84
                for (int i = 0; i < arr.length; i++) {
85
                    DataObject obj = (DataObject)nowToObj.remove (arr[i]);
86
                    if (obj == null) {
87
                        if (arr[i] != null) {
88
                            obj = InstanceDataObject.create (folder, null, arr[i].getClass ());
89
                        } else {
90
                            if (!sepObjs.isEmpty ()) {
91
                                obj = (DataObject)sepObjs.removeFirst ();
92
                            } else {
93
                                obj = InstanceDataObject.create (folder, "Separator" + order.size (), javax.swing.JSeparator.class);
94
                            }
95
                        }
96
                    }
97
                    order.add (obj);
98
                }
99
                
100
                // these were there but are not there anymore
101
                for (Iterator it = nowToObj.values ().iterator (); it.hasNext (); ) {
102
                    DataObject obj = (DataObject)it.next ();
103
                    obj.delete ();
104
                }
105
                for (Iterator it = sepObjs.iterator (); it.hasNext (); ) {
106
                    DataObject obj = (DataObject)it.next ();
107
                    obj.delete ();
108
                }
109
                
110
                folder.setOrder ((DataObject[])order.toArray (new DataObject[0]));
111
            }
112
            
113
            public void run () {
114
                try {
115
                    switch (state) {
116
                        case 0:
117
                            state = 1;
118
                            folder.getPrimaryFile ().getFileSystem ().runAtomicAction (this);
119
                            break;
120
                        case 1:
121
                            work ();
122
                            break;
123
                    }
124
                } catch (IOException ex) {
125
                    ErrorManager.getDefault ().notify (ex);
126
                }
127
            }
128
        }
129
        
130
        DoTheWork dtw = new DoTheWork ();
131
        creation = RP.post (dtw);
132
    }
133
    
134
    
135
    /** Creates the actions and notifies the loader.
136
     */
137
    protected Object createInstance (org.openide.cookies.InstanceCookie[] cookies) throws java.io.IOException, ClassNotFoundException {
138
        ArrayList list = new ArrayList ();
139
        for (int i = 0; i < cookies.length; i++) {
140
            Object action = cookies[i].instanceCreate ();
141
            if (action instanceof javax.swing.Action) {
142
                list.add (action);
143
                continue;
144
            }
145
            if (action instanceof javax.swing.JSeparator) {
146
                list.add (null);
147
            }
148
        }
149
        
150
        DataLoader l = (DataLoader)ref.get ();
151
        if (l != null) {
152
            l.setSwingActions (list);
153
        }
154
        
155
        return list.toArray (new javax.swing.Action[0]);
156
    }
157
158
    /** Currently not recursive */
159
    protected org.openide.cookies.InstanceCookie acceptFolder (DataFolder df) {
160
        return null;
161
    }
162
163
    /** Creation in our own thread, so we can exclude storage modifications */
164
    protected org.openide.util.Task postCreationTask (Runnable run) {
165
        return RP.post (run);
166
    }
167
    
168
    public void waitFinished () {
169
        org.openide.util.Task t;
170
        synchronized (this) {
171
            t = creation;
172
        }
173
        
174
        if (t != null) {
175
            t.waitFinished ();
176
        }
177
        
178
        super.waitFinished ();
179
    }
180
    
181
}
(-)openide/loaders/src/org/openide/loaders/DataLoader.java (-10 / +128 lines)
Lines 49-54 Link Here
49
    public static final String PROP_ACTIONS = "actions"; // NOI18N
49
    public static final String PROP_ACTIONS = "actions"; // NOI18N
50
    /** property name of list of default actions */
50
    /** property name of list of default actions */
51
    private static final String PROP_DEF_ACTIONS = "defaultActions"; // NOI18N
51
    private static final String PROP_DEF_ACTIONS = "defaultActions"; // NOI18N
52
   /** key to hold reference to out action manager */
53
    private static final Object ACTION_MANAGER = new Object ();
52
    /** representation class, not public property */
54
    /** representation class, not public property */
53
    private static final Object PROP_REPRESENTATION_CLASS = new Object ();
55
    private static final Object PROP_REPRESENTATION_CLASS = new Object ();
54
    /** representation class name, not public property */
56
    /** representation class name, not public property */
Lines 133-149 Link Here
133
    *   actions
135
    *   actions
134
    */
136
    */
135
    public final SystemAction[] getActions () {
137
    public final SystemAction[] getActions () {
136
        SystemAction[] actions = (SystemAction[])getProperty (PROP_ACTIONS);
138
        javax.swing.Action[] arr = getSwingActions ();
137
        if ( actions == null ) {
139
        
138
            actions = (SystemAction[])getProperty (PROP_DEF_ACTIONS);
140
        ArrayList list = new ArrayList ();
141
        for (int i = 0; i < arr.length; i++) {
142
            if (arr[i] instanceof SystemAction || arr[i] == null) {
143
                list.add (arr[i]);
144
            }
145
        }
146
        
147
        return (SystemAction[])list.toArray (new SystemAction[0]);
148
    }
149
    
150
    /** Swing actions getter, used from DataNode */
151
    final javax.swing.Action[] getSwingActions () {
152
        DataLdrActions mgr = findManager ();
153
        if (mgr != null) {
154
            Object actions;
155
            try {
156
                actions = mgr.instanceCreate ();
157
            } catch (IOException ex) {
158
                ErrorManager.getDefault ().notify (ex);
159
                actions = null;
160
            } catch (ClassNotFoundException ex) {
161
                ErrorManager.getDefault ().notify (ex);
162
                actions = null;
163
            }
164
        
165
            return (javax.swing.Action[])actions;
166
        } else {
167
            // old behaviour, that stores actions in properties
168
            SystemAction[] actions = (SystemAction[])getProperty (PROP_ACTIONS);
139
            if ( actions == null ) {
169
            if ( actions == null ) {
140
                actions = defaultActions();
170
                actions = (SystemAction[])getProperty (PROP_DEF_ACTIONS);
141
                putProperty (PROP_DEF_ACTIONS, actions, false);
171
                if ( actions == null ) {
142
            }        
172
                    actions = defaultActions();
173
                    putProperty (PROP_DEF_ACTIONS, actions, false);
174
                }
175
            }
176
            return actions;
143
        }
177
        }
144
        return actions;
145
    }
178
    }
146
179
        
180
    
181
    /** Identifies the name of context in layer files where the 
182
     * loader wishes to store its own actions and also read them.
183
     * In principle any {@link javax.swing.Action} instance can be registered
184
     * in the context and it will be visible in the default DataNode
185
     * for data object created by this loader. Only SystemAction can however
186
     * be manipulated from DataLoader getActions/setActions methods.
187
     * <p>
188
     * The default implementation returns null to indicate that no
189
     * layer reading should be used
190
     *
191
     * @return the string name of the context on layer files to read/write acitons to
192
     */
193
    protected String actionsContext () {
194
        return null;
195
    }
196
    
147
    /** Get default actions.
197
    /** Get default actions.
148
    * @return array of default system actions or <CODE>null</CODE> if this loader
198
    * @return array of default system actions or <CODE>null</CODE> if this loader
149
    * does not have any actions.
199
    * does not have any actions.
Lines 160-165 Link Here
160
        return actions;
210
        return actions;
161
    }
211
    }
162
    
212
    
213
    /** Actions manager.
214
     */
215
    private final DataLdrActions findManager () {
216
        Object manager = getProperty (ACTION_MANAGER);
217
        if (manager instanceof Class) {
218
            return null;
219
        }
220
        DataLdrActions mgr = (DataLdrActions)manager;
221
        boolean newlyCreated = false;
222
        if (mgr == null) {
223
            String context = actionsContext ();
224
            if (context == null) {
225
                // mark we have no context
226
                putProperty (ACTION_MANAGER, getClass ());
227
                return null;
228
            }
229
            
230
            FileObject fo = Repository.getDefault ().getDefaultFileSystem ().findResource (context);
231
            if (fo == null) {
232
                fo = Repository.getDefault ().getDefaultFileSystem ().getRoot ();
233
                try {
234
                    fo = FileUtil.createFolder (fo, context);
235
236
                } catch (IOException ex) {
237
                    ErrorManager.getDefault ().notify (ex);
238
                }
239
                newlyCreated = true;
240
            }
241
            
242
            mgr = new DataLdrActions (DataFolder.findFolder (fo), this);
243
            if (newlyCreated) {
244
                SystemAction[] arr = defaultActions ();
245
                if (arr != null) {
246
                    mgr.setActions (arr);
247
                }
248
            }
249
            putProperty (ACTION_MANAGER, mgr);
250
        }
251
        return mgr;
252
    }
253
    
254
    /** Allows the friend code (package and tests) to wait while actions
255
     * are synchronized with the state of disk.
256
     */
257
    final void waitForActions () {
258
        DataLdrActions mgr = findManager ();
259
        if (mgr != null) {
260
            mgr.waitFinished ();
261
        }
262
    }
263
    
163
    /** Set actions.
264
    /** Set actions.
164
    * <p>Note that this method is public, not protected, so it is possible for anyone
265
    * <p>Note that this method is public, not protected, so it is possible for anyone
165
    * to modify the loader's popup actions externally (after finding the loader
266
    * to modify the loader's popup actions externally (after finding the loader
Lines 172-178 Link Here
172
    * @see #getActions
273
    * @see #getActions
173
    */
274
    */
174
    public final void setActions (SystemAction[] actions) {
275
    public final void setActions (SystemAction[] actions) {
175
        putProperty (PROP_ACTIONS, actions, true);
276
        DataLdrActions mgr = findManager ();
277
        if (mgr != null) {
278
            mgr.setActions (actions);
279
        } else {
280
            putProperty (PROP_ACTIONS, actions, true);
281
        }
282
    }
283
    
284
    /** Assigns this loader new array of swing actions.
285
     * @param arr List<Action>
286
     */
287
    final void setSwingActions (List/*<Action>*/ arr) {
288
        firePropertyChange (PROP_ACTIONS, null, null);
176
    }
289
    }
177
290
178
    /** Get the current display name of this loader.
291
    /** Get the current display name of this loader.
Lines 349-358 Link Here
349
                }
462
                }
350
                
463
                
351
                try {
464
                try {
465
                    ClassLoader loader = (ClassLoader)Lookup.getDefault().lookup(ClassLoader.class);
466
                    if (loader == null) {
467
                        loader = getClass ().getClassLoader ();
468
                    }
469
                    
352
                    Class c = Class.forName (
470
                    Class c = Class.forName (
353
                        Utilities.translate((String)arr[i]),
471
                        Utilities.translate((String)arr[i]),
354
                        false, // why resolve?? --jglick
472
                        false, // why resolve?? --jglick
355
                        (ClassLoader)Lookup.getDefault().lookup(ClassLoader.class)
473
                        loader
356
                    );
474
                    );
357
                    SystemAction ac = SystemAction.get (c);
475
                    SystemAction ac = SystemAction.get (c);
358
                    
476
                    
(-)openide/loaders/src/org/openide/loaders/DataNode.java (+17 lines)
Lines 302-307 Link Here
302
    * @see DataLoader#getActions
302
    * @see DataLoader#getActions
303
    * @return array of actions or <code>null</code>
303
    * @return array of actions or <code>null</code>
304
    */
304
    */
305
    public Action[] getActions (boolean context) {
306
        if (systemActions == null) {
307
            systemActions = createActions ();
308
        }
309
310
        if (systemActions != null) {
311
            return systemActions;
312
        }
313
314
        return obj.getLoader ().getSwingActions ();
315
    }
316
317
    /** Get actions for this data object.
318
    * @deprecated Use getActions(boolean)
319
    * @return array of actions or <code>null</code>
320
    */
305
    public SystemAction[] getActions () {
321
    public SystemAction[] getActions () {
306
        if (systemActions == null) {
322
        if (systemActions == null) {
307
            systemActions = createActions ();
323
            systemActions = createActions ();
Lines 314-319 Link Here
314
        return obj.getLoader ().getActions ();
330
        return obj.getLoader ().getActions ();
315
    }
331
    }
316
332
333
    
317
    /** Get default action. In the current implementation the 
334
    /** Get default action. In the current implementation the 
318
    *<code>null</code> is returned in case the underlying data 
335
    *<code>null</code> is returned in case the underlying data 
319
    * object is a template. The templates should not have any default 
336
    * object is a template. The templates should not have any default 
(-)openide/test/unit/src/org/openide/loaders/DataLoaderGetActionsCompatibilityTest.java (+260 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.openide.loaders;
15
16
import junit.textui.TestRunner;
17
18
import org.openide.filesystems.*;
19
import org.openide.util.Lookup;
20
import java.io.IOException;
21
import java.util.*;
22
import org.netbeans.junit.*;
23
import java.beans.PropertyChangeListener;
24
import javax.swing.Action;
25
import org.openide.util.io.NbMarshalledObject;
26
27
/** Check how the default behaviour of DataLoader without overriden
28
 * actionsContext works.
29
 *
30
 * @author Jaroslav Tulach 
31
 */
32
public class DataLoaderGetActionsCompatibilityTest extends NbTestCase {
33
    /** sample data object */
34
    private DataObject obj;
35
    /** its node */
36
    private org.openide.nodes.Node node;
37
    /** monitor sfs */
38
    private PCL sfs;
39
40
    public DataLoaderGetActionsCompatibilityTest (String name) {
41
        super(name);
42
    }
43
    
44
    public static void main(String[] args) {
45
        if (args.length == 1) {
46
            TestRunner.run (new DataLoaderGetActionsCompatibilityTest (args[0]));
47
        } else {
48
            TestRunner.run(new NbTestSuite(DataLoaderGetActionsCompatibilityTest.class));
49
        }
50
    }
51
52
    /**
53
     * Sets up the testing environment by creating testing folders
54
     * on the system file system.
55
     */
56
    protected void setUp () throws Exception {
57
        System.setProperty ("org.openide.util.Lookup", "org.openide.loaders.DataLoaderGetActionsCompatibilityTest$Lkp");
58
        assertEquals ("Our lookup is installed", Lookup.getDefault ().getClass (), Lkp.class);
59
        
60
        MyDL loader = (MyDL)MyDL.getLoader (MyDL.class);
61
62
        FileSystem dfs = Repository.getDefault().getDefaultFileSystem();
63
        dfs.refresh (true);        
64
        
65
        FileObject fo = FileUtil.createData (dfs.getRoot (), "a.txt");
66
        obj = DataObject.find (fo);
67
        
68
        assertEquals ("The correct loader", loader, obj.getLoader ());
69
        
70
        node = obj.getNodeDelegate ();    
71
        
72
        sfs = new PCL ();
73
        dfs.addFileChangeListener (sfs);
74
    }
75
    
76
    /**
77
     * Deletes the folders created in method setUp().
78
     */
79
    protected void tearDown() throws Exception {
80
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[0]);
81
        
82
        int l = node.getActions (false).length;
83
        if (l != 0) {
84
            fail ("Not empty actions at the end!!!");
85
        }
86
        Repository.getDefault ().getDefaultFileSystem ().removeFileChangeListener (sfs);
87
88
        // no suspicious activity on getDefaultFileSystem
89
        sfs.assertEvent (0, null);
90
    }
91
    
92
    public void testDefaultActionContextReturnsNull () {
93
        assertNull (obj.getLoader ().actionsContext ());
94
    }
95
    
96
    public void testDefaultActionsUsedWhenCreatedForTheFirstTime () throws Exception {
97
        SndDL loader = (SndDL)SndDL.getLoader (SndDL.class);
98
        
99
        org.openide.util.actions.SystemAction[] arr = loader.getActions ();
100
        
101
        assertEquals (
102
            "Arrays of actions are the same", 
103
            java.util.Arrays.asList (loader.defaultActions ()),
104
            java.util.Arrays.asList (arr)
105
        );
106
    }
107
108
    /** Test to check that the deserialization of actions works as expected.
109
     */
110
    public void testNoDeserializationOfActions () throws Exception {
111
        assertEquals("No actions at the start", 0, node.getActions(false).length);
112
        
113
        PCL pcl = new PCL ();
114
        obj.getLoader ().addPropertyChangeListener (pcl);
115
        
116
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[] {
117
                org.openide.util.actions.SystemAction.get (org.openide.actions.PropertiesAction.class)
118
        });
119
        
120
        pcl.assertEvent (1, "actions");
121
        
122
        Action [] res = node.getActions(false);
123
        assertEquals("There should be exactly one action.", 1, res.length);
124
        
125
        NbMarshalledObject m = new NbMarshalledObject (obj.getLoader ());
126
        
127
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[0]);
128
129
        pcl.assertEvent (2, "actions");
130
        assertEquals("No actions after setting empty array", 0, node.getActions(false).length);
131
        
132
        assertEquals ("Loader deserialized", obj.getLoader (), m.get ());
133
        res = node.getActions(false);
134
        assertEquals("One action", 1, res.length);
135
        assertEquals (
136
            "and that is the property action", 
137
            org.openide.util.actions.SystemAction.get (org.openide.actions.PropertiesAction.class),
138
            res[0]
139
        );
140
        
141
        obj.getLoader ().removePropertyChangeListener (pcl);
142
    }
143
    
144
    /** Loader that does not override the actionsContext.
145
     */
146
    private static class MyDL extends UniFileLoader {
147
        public MyDL () {
148
            super ("org.openide.loaders.DataObject");
149
            getExtensions ().addExtension ("txt");
150
        }
151
        
152
        protected org.openide.loaders.MultiDataObject createMultiObject (FileObject primaryFile) throws org.openide.loaders.DataObjectExistsException, IOException {
153
            
154
            
155
            
156
            return new MultiDataObject (primaryFile, this);
157
        }
158
        
159
        protected org.openide.util.actions.SystemAction[] defaultActions () {
160
            return new org.openide.util.actions.SystemAction[0];
161
        }
162
        
163
    } // end of MyDL
164
    
165
    //
166
    // Our fake lookup
167
    //
168
    public static final class Lkp extends org.openide.util.lookup.AbstractLookup {
169
        public Lkp () throws Exception {
170
            this (new org.openide.util.lookup.InstanceContent ());
171
        }
172
        
173
        private Lkp (org.openide.util.lookup.InstanceContent ic) throws Exception {
174
            super (ic);
175
            
176
            TestUtilHid.destroyLocalFileSystem (Lkp.class.getName ());
177
            ic.add (new Repository (TestUtilHid.createLocalFileSystem (Lkp.class.getName (), new String[0])));
178
            ic.add (new Pool ());
179
//            ic.add (new EM ());
180
        }
181
    }
182
    
183
    
184
    private static final class Pool extends DataLoaderPool {
185
        
186
        protected java.util.Enumeration loaders () {
187
            return org.openide.util.Enumerations.singleton (
188
                DataLoader.getLoader(MyDL.class)
189
            );
190
        }
191
        
192
    } // end of Pool
193
194
    private final class PCL implements org.openide.filesystems.FileChangeListener, java.beans.PropertyChangeListener {
195
        int cnt;
196
        String name;
197
198
        public void propertyChange (java.beans.PropertyChangeEvent ev) {
199
            name = ev.getPropertyName();
200
            cnt++;
201
        }
202
        
203
        public void assertEvent (int cnt, String name) {
204
            obj.getLoader ().waitForActions ();
205
206
            if (cnt != this.cnt) {
207
                fail ("Excepted more changes then we got: expected: " + cnt + " we got: " + this.cnt + " with name: " + this.name);
208
            }
209
        }
210
211
        public void fileAttributeChanged(org.openide.filesystems.FileAttributeEvent fe) {
212
            cnt++;
213
            name = "fileAttributeChanged";
214
        }
215
216
        public void fileChanged(org.openide.filesystems.FileEvent fe) {
217
            cnt++;
218
            name = "fileChanged";
219
        }
220
221
        public void fileDataCreated(org.openide.filesystems.FileEvent fe) {
222
            cnt++;
223
            name = "fileDataCreated";
224
        }
225
226
        public void fileDeleted(org.openide.filesystems.FileEvent fe) {
227
            cnt++;
228
            name = "fileDeleted";
229
        }
230
231
        public void fileFolderCreated(org.openide.filesystems.FileEvent fe) {
232
            cnt++;
233
            name = "fileFolderCreated";
234
        }
235
236
        public void fileRenamed(org.openide.filesystems.FileRenameEvent fe) {
237
            cnt++;
238
            name = "fileRenamed";
239
        }
240
    } // end of PCL
241
    
242
    public static final class SndDL extends MyDL {
243
        public SndDL () {
244
            getExtensions ().addExtension ("bla");
245
        }
246
        
247
        protected org.openide.util.actions.SystemAction[] defaultActions () {
248
            return new org.openide.util.actions.SystemAction[] {
249
                org.openide.util.actions.SystemAction.get (org.openide.actions.CutAction.class),
250
                null,
251
                org.openide.util.actions.SystemAction.get (org.openide.actions.CopyAction.class),
252
                null,
253
                org.openide.util.actions.SystemAction.get (org.openide.actions.DeleteAction.class),
254
                
255
            };
256
        }
257
        
258
    }
259
    
260
}
(-)openide/test/unit/src/org/openide/loaders/DataLoaderGetActionsTest.java (+347 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.openide.loaders;
15
16
import junit.textui.TestRunner;
17
18
import org.openide.filesystems.*;
19
import org.openide.util.Lookup;
20
import java.io.IOException;
21
import java.util.*;
22
import org.netbeans.junit.*;
23
import java.beans.PropertyChangeListener;
24
import javax.swing.Action;
25
import org.openide.util.io.NbMarshalledObject;
26
27
/** Tests the proposed behaviour of DataLoader.getActions that is going 
28
 * to read its values from layer.
29
 *
30
 * @author Jaroslav Tulach (taken from openidex/enode by David Strupl)
31
 */
32
public class DataLoaderGetActionsTest extends NbTestCase {
33
    /** root folder FileObject */
34
    private FileObject root;
35
    /** sample data object */
36
    private DataObject obj;
37
    /** its node */
38
    private org.openide.nodes.Node node;
39
40
    public DataLoaderGetActionsTest (String name) {
41
        super(name);
42
    }
43
    
44
    public static void main(String[] args) {
45
        if (args.length == 1) {
46
            TestRunner.run (new DataLoaderGetActionsTest (args[0]));
47
        } else {
48
            TestRunner.run(new NbTestSuite(DataLoaderGetActionsTest.class));
49
        }
50
    }
51
52
    /**
53
     * Sets up the testing environment by creating testing folders
54
     * on the system file system.
55
     */
56
    protected void setUp () throws Exception {
57
        System.setProperty ("org.openide.util.Lookup", "org.openide.loaders.DataLoaderGetActionsTest$Lkp");
58
        assertEquals ("Our lookup is installed", Lookup.getDefault ().getClass (), Lkp.class);
59
        
60
        MyDL loader = (MyDL)MyDL.getLoader (MyDL.class);
61
62
        FileSystem dfs = Repository.getDefault().getDefaultFileSystem();
63
        dfs.refresh (true);        
64
        root = FileUtil.createFolder (dfs.getRoot (), loader.actionsContext ());
65
        
66
        
67
        FileObject fo = FileUtil.createData (dfs.getRoot (), "a.txt");
68
        obj = DataObject.find (fo);
69
        
70
        assertEquals ("The correct loader", loader, obj.getLoader ());
71
        
72
        node = obj.getNodeDelegate ();    
73
    }
74
    
75
    /**
76
     * Deletes the folders created in method setUp().
77
     */
78
    protected void tearDown() throws Exception {
79
        FileObject[] arr = root.getChildren ();
80
        for (int i = 0; i < arr.length; i++) {
81
            arr[i].delete();
82
        }
83
        int l = node.getActions (false).length;
84
        if (l != 0) {
85
            System.err.println("Not empty actions at the end!!!");
86
        }
87
    }
88
    
89
    /**
90
     * This test tests the presence of declarative actions from
91
     * system file system without the hierarchical flag set (the ExtensibleNode
92
     * instance is created with constructor ExtensibleNode("test", false).
93
     * The tests performs following steps:
94
     * <OL><LI> Create an instance of ExtensibleNode with folder set to "test"
95
     *     <LI> No actions should be returned by getActions since the "test" folder
96
     *          is not there
97
     *     <LI> Create one action in the testing folder
98
     *     <LI> The action should be visible in the result of getActions
99
     *     <LI> After deleting the action from the folder the action should
100
     *          not be returned from getActions().
101
     * </OL>
102
     */
103
    public void testCreateAndDeleteAction() throws Exception {
104
        assertEquals("No actions at the start", 0, node.getActions(false).length);
105
        FileObject test = root;
106
        
107
        PCL pcl = new PCL ();
108
        obj.getLoader ().addPropertyChangeListener (pcl);
109
        
110
        FileObject a1 = test.createData("org-openide-actions-PropertiesAction.instance");
111
        
112
        pcl.assertEvent (1, "actions");
113
        
114
        Action [] res = node.getActions(false);
115
        assertEquals("There should be exactly one action.", 1, res.length);
116
        a1.delete();
117
118
        pcl.assertEvent (2, "actions");
119
        assertEquals("No actions after deleting", 0, node.getActions(false).length);
120
        
121
        obj.getLoader ().removePropertyChangeListener (pcl);
122
    }
123
    
124
    /**
125
     * An attempt to create a simple stress test. Just calls
126
     * the <code>testCreateAndDeleteAction</code> 100 times.
127
     */
128
    public void testRepetitiveDeleting() throws Exception {
129
        for (int i = 0; i < 10; i++) {
130
            testCreateAndDeleteAction();
131
        }
132
    }
133
    
134
    /**
135
     * This test should test behaviour of the getActions method when
136
     * there is some alien object specified in the configuration folder.
137
     * The testing object is of type Integer (instead of javax.swing.Action).
138
     */
139
    public void testWrongActionObjectInConfig() throws Exception {
140
        assertEquals("No actions at the start", 0, node.getActions(false).length);
141
        FileObject test = root;
142
        FileObject a1 = test.createData("java-lang-String.instance");
143
        Action [] res = node.getActions(false);
144
        assertEquals("There should be zero actions.", 0, res.length);        
145
    }
146
    
147
    /**
148
     * This test checks whether the JSeparator added from the configuration
149
     * file is reflected in the resulting popup.
150
     * The tests performs following steps:
151
     * <OL><LI> Create an instance of ExtensibleNode with folder set to "test"
152
     *     <LI> No actions should be returned by getActions since the "test" folder
153
     *          is not there
154
     *     <LI> Create two actions in the testing folder separated by JSeparator
155
     *     <LI> getActions should return 3 elements - null element for the separator
156
     *     <LI> Popup is created from the actions array - the null element
157
     *              should be replaced by a JSeparator again
158
     * </OL>
159
     */
160
    public void testAddingSeparators() throws Exception {
161
        org.openide.nodes.Node en1 = node;
162
        assertEquals("No actions at the start", 0, en1.getActions(false).length);
163
        FileObject test = root;
164
        FileObject a1 = test.createData("1[org-openide-actions-PropertiesAction].instance");
165
        FileObject sep = test.createData("2[javax-swing-JSeparator].instance");
166
        FileObject a2 = test.createData("3[org-openide-actions-CutAction].instance");
167
        javax.swing.Action[] actions = en1.getActions(false);
168
        assertEquals("Actions array should contain 3 elements", 3, actions.length);
169
        assertNull("separator should create null element in the array", actions[1]);
170
        javax.swing.JPopupMenu jp = org.openide.util.Utilities.actionsToPopup(actions, org.openide.util.lookup.Lookups.singleton(en1));
171
        assertEquals("Popup should contain 3 components", 3, jp.getComponentCount());
172
        assertTrue("Separator should be second", jp.getComponent(1) instanceof javax.swing.JSeparator);
173
    }
174
175
    /** Test to see whether a compatibility behaviour is still kept. E.g.
176
     * if one adds actions using DataLoader.setActions they really will be 
177
     * there.
178
     */
179
    public void testCompatibilityIsPropagatedToDisk () throws Exception {
180
        assertEquals("No actions at the start", 0, node.getActions(false).length);
181
        FileObject test = root;
182
        
183
        PCL pcl = new PCL ();
184
        obj.getLoader ().addPropertyChangeListener (pcl);
185
        
186
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[] {
187
                org.openide.util.actions.SystemAction.get (org.openide.actions.PropertiesAction.class)
188
        });
189
        
190
        pcl.assertEvent (1, "actions");
191
        
192
        Action [] res = node.getActions(false);
193
        assertEquals("There should be exactly one action.", 1, res.length);
194
        assertEquals("One file created", 1, test.getChildren ().length);
195
        
196
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[0]);
197
198
        pcl.assertEvent (2, "actions");
199
        assertEquals("No actions after deleting", 0, node.getActions(false).length);
200
        
201
        assertEquals("file disappeared", 0, test.getChildren ().length);
202
        obj.getLoader ().removePropertyChangeListener (pcl);
203
    }
204
    
205
    /** Test to check that the deserialization of actions is completely ignored.
206
     */
207
    public void testNoDeserializationOfActions () throws Exception {
208
        assertEquals("No actions at the start", 0, node.getActions(false).length);
209
        FileObject test = root;
210
        
211
        PCL pcl = new PCL ();
212
        obj.getLoader ().addPropertyChangeListener (pcl);
213
        
214
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[] {
215
                org.openide.util.actions.SystemAction.get (org.openide.actions.PropertiesAction.class)
216
        });
217
        
218
        pcl.assertEvent (1, "actions");
219
        
220
        Action [] res = node.getActions(false);
221
        assertEquals("There should be exactly one action.", 1, res.length);
222
        assertEquals("One file created", 1, test.getChildren ().length);
223
        
224
        NbMarshalledObject m = new NbMarshalledObject (obj.getLoader ());
225
        
226
        obj.getLoader ().setActions (new org.openide.util.actions.SystemAction[0]);
227
228
        pcl.assertEvent (2, "actions");
229
        assertEquals("No actions after deleting", 0, node.getActions(false).length);
230
        
231
        assertEquals("file disappeared", 0, test.getChildren ().length);
232
        
233
        assertEquals ("Loader deserialized", obj.getLoader (), m.get ());
234
        assertEquals("Still no actions", 0, node.getActions(false).length);
235
        
236
        obj.getLoader ().removePropertyChangeListener (pcl);
237
    }
238
    
239
    public void testDefaultActionsUsedWhenCreatedForTheFirstTime () throws Exception {
240
        SndDL loader = (SndDL)SndDL.getLoader (SndDL.class);
241
        
242
        org.openide.util.actions.SystemAction[] arr = loader.getActions ();
243
        
244
        assertEquals (
245
            "Arrays of actions are the same", 
246
            java.util.Arrays.asList (loader.defaultActions ()),
247
            java.util.Arrays.asList (arr)
248
        );
249
    }
250
    
251
    private static class MyDL extends UniFileLoader {
252
        public MyDL () {
253
            super ("org.openide.loaders.DataObject");
254
            getExtensions ().addExtension ("txt");
255
        }
256
        
257
        /** Returns the name of the folder to read the actions from
258
         */
259
        protected String actionsContext () {
260
            return "test";
261
        }
262
        
263
        protected org.openide.loaders.MultiDataObject createMultiObject (FileObject primaryFile) throws org.openide.loaders.DataObjectExistsException, IOException {
264
            
265
            
266
            
267
            return new MultiDataObject (primaryFile, this);
268
        }
269
        
270
        protected org.openide.util.actions.SystemAction[] defaultActions () {
271
            return new org.openide.util.actions.SystemAction[0];
272
        }
273
        
274
    } // end of MyDL
275
    
276
    //
277
    // Our fake lookup
278
    //
279
    public static final class Lkp extends org.openide.util.lookup.AbstractLookup {
280
        public Lkp () throws Exception {
281
            this (new org.openide.util.lookup.InstanceContent ());
282
        }
283
        
284
        private Lkp (org.openide.util.lookup.InstanceContent ic) throws Exception {
285
            super (ic);
286
            
287
            TestUtilHid.destroyLocalFileSystem (Lkp.class.getName ());
288
            ic.add (new Repository (TestUtilHid.createLocalFileSystem (Lkp.class.getName (), new String[0])));
289
            ic.add (new Pool ());
290
//            ic.add (new EM ());
291
        }
292
    }
293
    
294
    
295
    private static final class Pool extends DataLoaderPool {
296
        
297
        protected java.util.Enumeration loaders () {
298
            return new org.openide.util.enum.SingletonEnumeration (
299
                DataLoader.getLoader(MyDL.class)
300
            );
301
        }
302
        
303
    } // end of Pool
304
305
    private final class PCL 
306
    implements java.beans.PropertyChangeListener {
307
        int cnt;
308
        String name;
309
310
        public void propertyChange (java.beans.PropertyChangeEvent ev) {
311
            name = ev.getPropertyName();
312
            cnt++;
313
        }
314
        
315
        public void assertEvent (int cnt, String name) {
316
            obj.getLoader ().waitForActions ();
317
318
            if (cnt > this.cnt) {
319
                fail ("Excepted more changes then we got: expected: " + cnt + " we got: " + this.cnt);
320
            }
321
            assertEquals ("same name", name, this.name);
322
        }
323
    } // end of PCL
324
    
325
    public static final class SndDL extends MyDL {
326
        public SndDL () {
327
            getExtensions ().addExtension ("bla");
328
        }
329
        
330
        protected org.openide.util.actions.SystemAction[] defaultActions () {
331
            return new org.openide.util.actions.SystemAction[] {
332
                org.openide.util.actions.SystemAction.get (org.openide.actions.CutAction.class),
333
                null,
334
                org.openide.util.actions.SystemAction.get (org.openide.actions.CopyAction.class),
335
                null,
336
                org.openide.util.actions.SystemAction.get (org.openide.actions.DeleteAction.class),
337
                
338
            };
339
        }
340
        
341
        protected String actionsContext () {
342
            return "2ndtestdir";
343
        }
344
        
345
    }
346
    
347
}

Return to bug 45137