Index: loaders/src/org/openide/loaders/DataLoader.java =================================================================== RCS file: /cvs/openide/loaders/src/org/openide/loaders/DataLoader.java,v --- loaders/src/org/openide/loaders/DataLoader.java 7 Jan 2004 13:19:49 -0000 1.4 +++ loaders/src/org/openide/loaders/DataLoader.java 18 Jun 2004 13:34:38 -0000 @@ -16,6 +16,7 @@ import java.beans.*; import java.io.*; import java.util.*; +import javax.swing.Action; import org.openide.ErrorManager; import org.openide.filesystems.*; @@ -47,6 +48,9 @@ public static final String PROP_DISPLAY_NAME = "displayName"; // NOI18N /** property name of list of actions */ public static final String PROP_ACTIONS = "actions"; // NOI18N + /** property to store Action[] */ + private static final Object REAL_ACTIONS = new Object (); + /** property name of list of default actions */ private static final String PROP_DEF_ACTIONS = "defaultActions"; // NOI18N /** representation class, not public property */ @@ -123,6 +127,24 @@ return (String)getProperty (PROP_REPRESENTATION_CLASS_NAME); } + /** All actions, even swing ones associated with the loader. + */ + final Action[] getSwingActions () { + Action[] actions = (Action[])getProperty (PROP_ACTIONS); + if (actions == null) { + actions = (Action[])getProperty (REAL_ACTIONS); + } + if ( actions == null ) { + actions = (SystemAction[])getProperty (PROP_DEF_ACTIONS); + if ( actions == null ) { + actions = defaultActions(); + putProperty (PROP_DEF_ACTIONS, actions, false); + } + } + return actions; + } + + /** Get actions. * These actions are used to compose * a popup menu for the data object. Also these actions should @@ -133,15 +155,14 @@ * actions */ public final SystemAction[] getActions () { - SystemAction[] actions = (SystemAction[])getProperty (PROP_ACTIONS); - if ( actions == null ) { - actions = (SystemAction[])getProperty (PROP_DEF_ACTIONS); - if ( actions == null ) { - actions = defaultActions(); - putProperty (PROP_DEF_ACTIONS, actions, false); - } + ArrayList list = new ArrayList (); + Action[] swingActions = getSwingActions (); + for (int i = 0; i < swingActions.length; i++) { + if (swingActions[i] == null || swingActions[i] instanceof SystemAction) { + list.add (swingActions[i]); + } } - return actions; + return (SystemAction[])list.toArray (new SystemAction[0]); } /** Get default actions. @@ -174,6 +195,11 @@ public final void setActions (SystemAction[] actions) { putProperty (PROP_ACTIONS, actions, true); } + + public final void setActions (javax.swing.Action[] actions) { + putProperty (REAL_ACTIONS, actions); + firePropertyChange (PROP_ACTIONS, null, getActions ()); + } /** Get the current display name of this loader. * @return display name @@ -289,7 +315,11 @@ public void writeExternal (ObjectOutput oo) throws IOException { oo.writeObject( new Integer(LOADER_VERSION) ); - SystemAction[] arr = (SystemAction[])getProperty (PROP_ACTIONS); + Action[] arr = (Action[])getProperty (PROP_ACTIONS); + if (arr == null) { + arr = (Action[])getProperty (REAL_ACTIONS); + } + if (arr == null) { oo.writeObject (null); } else { @@ -299,7 +329,12 @@ if (arr[i] == null) { names.add (null); } else { - names.add (arr[i].getClass ().getName ()); + if (arr[i] instanceof SystemAction) { + names.add (arr[i].getClass ().getName ()); + } else { + // the action itself + names.add (arr[i]); + } } } oo.writeObject (names.toArray ()); @@ -348,6 +383,11 @@ continue; } + if (arr[i] instanceof Action) { + ll.add (arr[i]); + continue; + } + try { Class c = Class.forName ( Utilities.translate((String)arr[i]), @@ -373,7 +413,7 @@ } if (main == null && !isdefault) { // Whole action list was successfully read. - setActions ((SystemAction[])ll.toArray(new SystemAction[ll.size()])); + setActions ((Action[])ll.toArray(new Action[ll.size()])); } // Else do not try to override the default action list if it is incomplete anyway. } Index: loaders/src/org/openide/loaders/DataNode.java =================================================================== RCS file: /cvs/openide/loaders/src/org/openide/loaders/DataNode.java,v --- loaders/src/org/openide/loaders/DataNode.java 9 Jun 2004 20:33:53 -0000 1.14 +++ loaders/src/org/openide/loaders/DataNode.java 18 Jun 2004 13:34:38 -0000 @@ -302,6 +302,22 @@ * @see DataLoader#getActions * @return array of actions or null */ + public Action[] getActions (boolean context) { + if (systemActions == null) { + systemActions = createActions (); + } + + if (systemActions != null) { + return systemActions; + } + + return obj.getLoader ().getSwingActions (); + } + + /** Get actions for this data object. + * @deprecated Use getActions(boolean) + * @return array of actions or null + */ public SystemAction[] getActions () { if (systemActions == null) { systemActions = createActions (); @@ -314,6 +330,7 @@ return obj.getLoader ().getActions (); } + /** Get default action. In the current implementation the *null is returned in case the underlying data * object is a template. The templates should not have any default Index: test/unit/src/org/openide/loaders/DataNodeTest.java =================================================================== RCS file: /cvs/openide/test/unit/src/org/openide/loaders/DataNodeTest.java,v --- test/unit/src/org/openide/loaders/DataNodeTest.java 16 Oct 2002 06:09:25 -0000 1.4 +++ test/unit/src/org/openide/loaders/DataNodeTest.java 18 Jun 2004 13:34:47 -0000 @@ -13,6 +13,7 @@ package org.openide.loaders; +import java.io.*; import junit.textui.TestRunner; import org.openide.filesystems.FileSystem; import java.util.Enumeration; @@ -25,6 +26,9 @@ * @author Jesse Glick */ public class DataNodeTest extends NbTestCase { + private DataFolder top; + private DataObject obj; + private org.openide.util.actions.SystemAction[] originalActions; public DataNodeTest(String name) { super(name); @@ -36,12 +40,20 @@ System.exit(0); } - /* protected void setUp() throws Exception { + FileSystem sfs = Repository.getDefault().getDefaultFileSystem(); + top = DataFolder.findFolder(sfs.getRoot ()); + org.openide.filesystems.FileObject fo = org.openide.filesystems.FileUtil.createData ( + sfs.getRoot (), "data.ext" + ); + obj = DataObject.find (fo); + + originalActions = top.getLoader ().getActions (); } + protected void tearDown() throws Exception { + top.getLoader ().setActions (originalActions); } - */ /** Test that for all examples to be found in the system file system, * the node delegate has the same object as a cookie from DataObject.class. @@ -55,8 +67,6 @@ // outside a running IDE. // TopManager tm = TopManager.getDefault(); // Now scan SFS for all DO's and check the assertion. - FileSystem sfs = Repository.getDefault().getDefaultFileSystem(); - DataFolder top = DataFolder.findFolder(sfs.getRoot()); Enumeration e = top.children(true); while (e.hasMoreElements()) { DataObject o = (DataObject)e.nextElement(); @@ -66,4 +76,103 @@ } } + public void testDataNodeReturnsLoadersActions () throws Exception { + javax.swing.Action[] arr = { + new MyAction ("Name"), + new MyAction ("Two"), + null, // separator + new MyAction ("Last") + }; + obj.getLoader ().setActions (arr); + + javax.swing.Action[] nodeActions = obj.getNodeDelegate ().getActions (false); + + assertEquals ("Same actions", + java.util.Arrays.asList (arr), + java.util.Arrays.asList (nodeActions) + ); + + nodeActions = obj.getNodeDelegate ().getActions (true); + + assertEquals ("Same actions even of context ones", + java.util.Arrays.asList (arr), + java.util.Arrays.asList (nodeActions) + ); + + assertEquals ("There is just separator for system actions", + java.util.Collections.singletonList (null), + java.util.Arrays.asList (obj.getNodeDelegate ().getActions ()) + ); + + assertEquals ("Preferred is the first", + arr[0], obj.getNodeDelegate ().getPreferredAction () + ); + } + + public void testNonSerializableActionsAreRemovedAfterRebootSerializableStays () throws Exception { + javax.swing.Action[] arr = { + new MyAction ("NotSerial"), + new SerAction ("Serial"), + null, // separator + org.openide.actions.OpenAction.get (org.openide.actions.OpenAction.class) + }; + obj.getLoader ().setActions (arr); + + org.openide.util.io.NbMarshalledObject mar = new org.openide.util.io.NbMarshalledObject (obj.getLoader ()); + + Object read = mar.get (); + + assertSame ("Well SharedClassObject means the instance is still same", read, obj.getLoader ()); + + javax.swing.Action[] newArr = ((DataLoader)read).getSwingActions (); + + assertEquals ("Only serial, null, open are present", 3, newArr.length); + assertNull ("Separator is ok", newArr[1]); + assertEquals ("Serial", arr[1], newArr[0]); + assertEquals ("OpenAction", arr[2], newArr[1]); + } + + private static class MyAction extends javax.swing.AbstractAction { + String name; + + public MyAction (String name) { + this.name = name; + } + + + public void actionPerformed (java.awt.event.ActionEvent e) { + } + + public boolean equals (Object o) { + if (o instanceof MyAction) { + MyAction m = (MyAction)o; + return m.name.equals (name); + } + return false; + } + + public int hashCode () { + return 7 + name.hashCode (); + } + + public String toString () { + return "MyAction " + name; + } + } + + private static final class SerAction extends MyAction implements java.io.Serializable { + static final long serialVersionUID = 4398571748139L; + + public SerAction (String name) { + super (name); + } + + private void readObject (ObjectInputStream ois) throws IOException, ClassNotFoundException { + name = (String)ois.readObject (); + } + + private void writeObject (ObjectOutputStream oos) throws IOException { + oos.writeObject (name); + } + } }