--- a/openide.loaders/src/org/openide/loaders/DataLoaderPool.java Mon Jun 02 16:52:06 2008 -0700
+++ a/openide.loaders/src/org/openide/loaders/DataLoaderPool.java Tue Jun 03 20:58:08 2008 +0200
@@ -41,7 +41,10 @@
package org.openide.loaders;
+import java.awt.Image;
import java.io.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -476,7 +479,12 @@ implements java.io.Serializable {
Enumeration extends DataObject.Factory> en = allLoaders (fo);
while (en.hasMoreElements ()) {
DataObject.Factory l = en.nextElement ();
- DataObject obj = l.findDataObject (fo, recognized);
+ DataObject obj;
+ if (l instanceof DataLoader) {
+ obj = l.findDataObject (fo, recognized);
+ } else {
+ obj = DataObjectPool.handleFindDataObject(l, fo, recognized);
+ }
if (!recognized.isEmpty()) {
for (FileObject f : recognized) {
r.markRecognized(f);
@@ -575,7 +583,40 @@ implements java.io.Serializable {
}
return null;
}
-
+
+ /** Factory method to create default implementation of a factory for
+ * data objects. It takes the class of the DataObject
and
+ * is ready to call its constructor. The constructor needs to take two
+ * arguments: FileObject and MultiDataLoader. It can throw IOException as
+ * is usual among DataObject constructors.
+ *
+ * You can also invoke this method from a layer by following definition:
+ *
+ * <file name="nameofyourfile.instance">
+ * &attr name="instanceCreate" methodvalue="org.openide.loaders.DataLoaderPool.factory"/>
+ * &attr name="dataObjectClass" stringvalue="org.your.pkg.YourDataObject"/>
+ * &attr name="mimeType" stringvalue="yourmime/type"/>
+ * &attr name="SystemFileSystem.localizingIcon" stringvalue="org/your/pkg/YourDataObject.png"/>
+ * </file>
+ *
+ * @param clazz the class of the data object to create. Must have appropriate
+ * constructor.
+ * @param mimeType the mime type associated with the object, used for
+ * example to create the right actions for the object's node
+ * @return factory to be registered in Loaders/mime/type/Factories
+ * in layer file
+ * @since 7.1
+ */
+ public static DataObject.Factory factory(
+ Class dataObjectClass, String mimeType, Image image
+ ) {
+ return new MimeFactory(dataObjectClass, mimeType, image, null);
+ }
+ static DataObject.Factory factory(
+ FileObject fo
+ ) throws ClassNotFoundException {
+ return MimeFactory.layer(fo);
+ }
/** Lazy getter for system loaders.
*/
@@ -801,11 +842,7 @@ private static class InstanceLoader exte
};
}
} // end of InstanceLoader
-
-
-
-
/** Loader for file objects not recognized by any other loader */
private static final class DefaultLoader extends MultiFileLoader {
static final long serialVersionUID =-6761887227412396555L;
--- a/openide.loaders/src/org/openide/loaders/DataNode.java Mon Jun 02 16:52:06 2008 -0700
+++ a/openide.loaders/src/org/openide/loaders/DataNode.java Tue Jun 03 20:58:08 2008 +0200
@@ -246,6 +246,11 @@ public class DataNode extends AbstractNo
}
return super.getHtmlDisplayName();
}
+
+ private java.awt.Image getImageFromFactory() {
+ MimeFactory> fact = getLookup().lookup(MimeFactory.class);
+ return fact != null ? fact.getImage() : null;
+ }
/** Get the displayed icon for this node.
* A filesystem may {@link org.openide.filesystems.FileSystem#getStatus specially alter} this.
@@ -254,8 +259,12 @@ public class DataNode extends AbstractNo
* @param type the icon type from {@link java.beans.BeanInfo}
* @return the desired icon
*/
+ @Override
public java.awt.Image getIcon (int type) {
- java.awt.Image img = super.getIcon (type);
+ java.awt.Image img = getImageFromFactory();
+ if (img == null) {
+ img = super.getIcon (type);
+ }
try {
img = obj.getPrimaryFile ().getFileSystem ().getStatus ().annotateIcon (img, type, new LazyFilesSet());
@@ -273,8 +282,12 @@ public class DataNode extends AbstractNo
* @param type the icon type from {@link java.beans.BeanInfo}
* @return the desired icon
*/
+ @Override
public java.awt.Image getOpenedIcon (int type) {
- java.awt.Image img = super.getOpenedIcon(type);
+ java.awt.Image img = getImageFromFactory();
+ if (img == null) {
+ img = super.getOpenedIcon(type);
+ }
try {
img = obj.getPrimaryFile ().getFileSystem ().getStatus ().annotateIcon (img, type, new LazyFilesSet());
@@ -351,6 +364,11 @@ public class DataNode extends AbstractNo
if (systemActions != null) {
return systemActions;
+ }
+
+ MimeFactory> mime = getLookup().lookup(MimeFactory.class);
+ if (mime != null) {
+ return mime.getActions();
}
return obj.getLoader ().getSwingActions ();
--- a/openide.loaders/src/org/openide/loaders/DataObjectPool.java Mon Jun 02 16:52:06 2008 -0700
+++ a/openide.loaders/src/org/openide/loaders/DataObjectPool.java Tue Jun 03 20:58:08 2008 +0200
@@ -156,6 +156,26 @@ implements ChangeListener {
getPOOL ().enterRecognition(fo);
ret = loader.handleFindDataObject (fo, rec);
+ } finally {
+ exitAllowConstructor (prev);
+ }
+
+ return ret;
+ }
+
+ /** Calls into one loader. Setups security condition to allow DataObject ocnstructor
+ * to succeed.
+ */
+ public static DataObject handleFindDataObject (DataObject.Factory factory, FileObject fo, Set super FileObject> rec)
+ throws java.io.IOException {
+ DataObject ret;
+
+ Collection- prev = enterAllowContructor();
+ try {
+ // make sure this thread is allowed to recognize
+ getPOOL ().enterRecognition(fo);
+
+ ret = factory.findDataObject (fo, rec);
} finally {
exitAllowConstructor (prev);
}
--- a/openide.loaders/test/unit/src/org/openide/loaders/DataLoaderInLayerTest.java Mon Jun 02 16:52:06 2008 -0700
+++ a/openide.loaders/test/unit/src/org/openide/loaders/DataLoaderInLayerTest.java Tue Jun 03 20:58:08 2008 +0200
@@ -42,12 +42,18 @@ package org.openide.loaders;
package org.openide.loaders;
+import java.awt.Image;
+import java.awt.Toolkit;
import org.openide.filesystems.*;
import java.io.IOException;
import java.util.*;
import org.netbeans.junit.*;
import java.beans.PropertyChangeListener;
+import java.net.URL;
+import javax.swing.Action;
import junit.framework.Test;
+import org.openide.actions.EditAction;
+import org.openide.nodes.Node;
/** Check what can be done when registering loaders in layer.
* @author Jaroslav Tulach
@@ -93,6 +99,20 @@ public class DataLoaderInLayerTest exten
}
}
}
+ private static void addRemove(String mime, F factory, boolean add) throws IOException {
+ String res = "Loaders/" + mime + "/Factories/" + factory.getClass().getSimpleName().replace('.', '-') + ".instance";
+ FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
+ if (add) {
+ FileObject fo = FileUtil.createData(root, res);
+ fo.setAttribute("instanceCreate", factory);
+ assertSame("No serialization, just memory fs is used", factory, fo.getAttribute("instanceCreate"));
+ } else {
+ FileObject fo = root.getFileObject(res);
+ if (fo != null) {
+ fo.delete();
+ }
+ }
+ }
public void testSimpleGetChildren() throws Exception {
DataLoader l = DataLoader.getLoader(SimpleUniFileLoader.class);
@@ -122,6 +142,37 @@ public class DataLoaderInLayerTest exten
assertEquals(SimpleDataObject.class, dob.getClass());
} finally {
addRemove("text/plain", SimpleFactory.class, false);
+ }
+ }
+
+ public void testFactoryInstanceRegistrationWorksAsWell() throws Exception {
+ URL u = DataLoaderInLayerTest.class.getResource("/org/openide/loaders/saveAll.gif");
+ Image img = Toolkit.getDefaultToolkit().createImage(u);
+
+ DataObject.Factory f = DataLoaderPool.factory(SimpleDataObject.class, "text/simplefactory", img);
+
+ addRemove("text/plain", f, true);
+ try {
+ FileSystem lfs = createFS("folderF/file.simple");
+ FileObject fo = lfs.findResource("folderF");
+ DataFolder df = DataFolder.findFolder(fo);
+ DataObject[] arr = df.getChildren();
+ assertEquals("One object", 1, arr.length);
+ DataObject dob = arr[0];
+ assertEquals(SimpleDataObject.class, dob.getClass());
+
+ FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
+ FileObject edit = FileUtil.createData(root, "/Loaders/text/simplefactory/Actions/org-openide-actions-EditAction.instance");
+
+ Node node = dob.getNodeDelegate();
+ Action[] actions = node.getActions(true);
+ assertEquals("One action is present: " + Arrays.asList(actions), 1, actions.length);
+ assertEquals("It is the edit one", EditAction.class, actions[0].getClass());
+
+ assertSame("Icon is propagated for open", img, node.getOpenedIcon(0));
+ assertSame("Icon is propagated", img, node.getIcon(0));
+ } finally {
+ addRemove("text/plain", f, false);
}
}