java.beans.PropertyEditorManager
.
+ * @author Tim Boudreau
+ */
+final class NbPropertyEditorManagerImpl extends NbPropertyEditorManager {
+ private final HashMap map = new HashMap();
+ private String folder;
+ public static final String ATTR_EDITORFOR = "editorFor"; //NOI18N
+ public static final String ATTR_EDITORCLASS = "editorClass"; //NOI18N
+
+ public NbPropertyEditorManagerImpl () {
+ this ("/propertyeditors");
+ }
+
+ private NbPropertyEditorManagerImpl (String editorFolder) {
+ //XXX may want to expose this constructor later, for e.g. form
+ //editor which wants its own private property editor registry
+ folder = editorFolder;
+ }
+
+ public PropertyEditor findEditor (Class clazz) {
+ return findEditor (clazz, true);
+ }
+
+ private static NbPropertyEditorManager instance=null;
+ public static NbPropertyEditorManager getInstance() {
+ if (instance == null) {
+ instance = new NbPropertyEditorManagerImpl(); //NOI18N
+ }
+ return instance;
+ }
+
+ public PropertyEditor findEditor (Class clazz, boolean newInstance) {
+ synchronized (map) {
+ if (map.isEmpty()) buildMap();
+ }
+ System.out.println("Looking for editor for " + clazz.getName());
+ String cname = clazz.getName();
+
+ System.out.println("Map lookup for " + cname);
+ System.out.println("Map contents:");
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext())
+ System.out.println(" -" + i.next());
+
+ Info in = (Info) map.get(cname);
+ PropertyEditor result = null;
+ if (in != null)
+ result = in.get (newInstance);
+ //Result will only be null if there was a cnfe fetching the editor
+ //class, or if no editor is registered via XML
+ if (result != null) return result;
+ System.out.println("Falling back to property editor manager");
+ //Fall back to PropertyEditorManager
+ return PropertyEditorManager.findEditor (clazz);
+ }
+
+ private boolean listening=false;
+ private void buildMap() {
+ synchronized (map) {
+ FileObject fo = org.openide.filesystems.Repository.getDefault().getDefaultFileSystem().findResource(folder);
+ FileObject[] kids = fo.getChildren();
+ synchronized (map) {
+ for (int i=0; i < kids.length; i++) {
+ String editorFor = (String)kids[i].getAttribute ("editorFor"); //NOI18N
+ map.put (editorFor, new InfoImpl (kids[i]));
+ }
+ }
+ if (listening == false) {
+ fo.addFileChangeListener(new FileChangeListener () {
+ public void fileFolderCreated (FileEvent fe){
+ //meaningless
+ }
+ public void fileDataCreated (FileEvent fe){
+ synchronized (map) {
+ map.clear();
+ }
+ }
+ public void fileChanged (FileEvent fe) {
+ synchronized (map) {
+ map.clear();
+ }
+ }
+ public void fileDeleted (FileEvent fe) {
+ synchronized (map) {
+ map.clear();
+ }
+ }
+
+ public void fileRenamed (FileRenameEvent fe) {
+ //no effect
+ }
+
+ public void fileAttributeChanged (FileAttributeEvent fe) {
+ //in the case that editors are added or removed,
+ //dump the cache - the next call will rebuild it
+ synchronized (map) {
+ map.clear();
+ }
+ }
+
+ });
+ listening = true;
+ }
+ }
+ }
+
+ public boolean hasEditor (Class clazz) {
+ synchronized (map) {
+ if (map.isEmpty()) buildMap();
+ }
+ String cname = clazz.getName();
+ return map.keySet().contains (cname);
+ }
+
+ public Info findInfo(Class clazz) {
+ if (map.isEmpty()) buildMap();
+ return (Info) map.get (clazz.getName());
+ }
+
+ class InfoImpl implements NbPropertyEditorManager.Info {
+ private String editorClassName;
+ private String editorFor;
+ private Class editorClass;
+ private Class edForClass;
+ private boolean badClassInfo=false;
+ private PropertyEditor defaultInstance=null; //make weak/soft ref?
+ private boolean initFromPe=false;
+ public InfoImpl (FileObject fo) {
+ editorClassName = (String) fo.getAttribute (ATTR_EDITORCLASS); //NOI18N
+ editorFor = (String) fo.getAttribute (ATTR_EDITORFOR); //NOI18N
+ System.out.println("Registered " + editorClassName + " for " + editorFor); //XXX debug code
+ }
+
+ public PropertyEditor get(boolean newInstance) {
+ PropertyEditor result = null;
+ if (newInstance) {
+ try {
+ result = (PropertyEditor) getEditorClass().newInstance();
+ System.out.println("Created new instance of " + result.getClass().getName());
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ } else if (defaultInstance == null) {
+ try {
+ result = (PropertyEditor) getEditorClass().newInstance();
+ defaultInstance = result;
+ System.out.println("Created default instance of " + result.getClass().getName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return result;
+ }
+
+ private Class getEditorClass () {
+ //If we know we have a bad registration, throwing the
+ //exception once is enough.
+ if (badClassInfo) return null;
+ if (editorClass == null) {
+ try {
+ editorClass = Class.forName(editorClassName);
+ } catch (ClassNotFoundException cnfe) {
+ ErrorManager.getDefault().log (ErrorManager.WARNING,
+ "The class \"" + editorClassName + "\" which is a property editor class for \"" //NOI18N
+ + editorFor + "\" is registered cannot be loaded."); //NOI18N
+ ErrorManager.getDefault().notify(ErrorManager.WARNING, cnfe);
+ badClassInfo = true;
+ }
+ if (editorClass != null) editorClassName = null;
+ }
+ return editorClass;
+ }
+
+ private Class getEdForClass () {
+ //If we know we have a bad registration, throwing the
+ //exception once is enough.
+ if (badClassInfo) {
+ return null;
+ }
+ if (edForClass == null) {
+ try {
+ edForClass = Class.forName(editorFor);
+ } catch (ClassNotFoundException cnfe) {
+ ErrorManager.getDefault().log (ErrorManager.WARNING,
+ "The class \"" + editorFor + "\" for which the property editor class \"" //NOI18N
+ + editorClassName + "\" is registered cannot be loaded."); //NOI18N
+ ErrorManager.getDefault().notify(ErrorManager.WARNING, cnfe);
+ badClassInfo = true;
+ }
+ if (edForClass != null) editorFor = null;
+ }
+ return edForClass;
+ }
+
+ public int hashCode () {
+ if (badClassInfo) return super.hashCode();
+ return getEditorClass().getName().hashCode() ^ 31;
+ }
+
+ public boolean equals (Object o) {
+ if (!(o instanceof NbPropertyEditorManager.Info))
+ return false;
+ return o.hashCode() == hashCode();
+ }
+
+ public Object getAttribute(Object key) {
+ //do nothing for now, maybe return fo's attributes
+ return null;
+ }
+ }
+
+}
Index: openide/src/org/openide/util/NbPropertyEditorManager.java
===================================================================
RCS file: openide/src/org/openide/util/NbPropertyEditorManager.java
diff -N openide/src/org/openide/util/NbPropertyEditorManager.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openide/src/org/openide/util/NbPropertyEditorManager.java 16 Jan 2003 18:06:59 -0000
@@ -0,0 +1,164 @@
+/*
+ * Sun Public License Notice
+ *
+ * The contents of this file are subject to the Sun Public License
+ * Version 1.0 (the "License"). You may not use this file except in
+ * compliance with the License. A copy of the License is available at
+ * http://www.sun.com/
+ *
+ * The Original Code is NetBeans. The Initial Developer of the Original
+ * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+/*
+ * NbPropertyEditorManager.java
+ *
+ * Created on January 12, 2003, 10:49 PM
+ */
+
+package org.openide.util;
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+import org.openide.ErrorManager;
+/** NetBeans property editor manager. The default implementation
+ * in the NetBeans IDE allows registration of property editors
+ * via XML. The preferred method of fetching property editors
+ * in NetBeans is by using this class -
+ * java.beans.PropertyEditorManager
will not contain
+ * property editors registered using the XML registration
+ * technique. The advantage of registration via XML is that
+ * the classes do not need to be loaded on IDE startup, and
+ * many modules that currently use ModuleInstall classes to
+ * do such registration may eliminated them by using layer-based
+ * registration instead.
+ * @author Tim Boudreau
+ */
+public abstract class NbPropertyEditorManager {
+
+ private static NbPropertyEditorManager defaultInstance=null;
+ /** Get the default implementation of NbPropertyEditorManager
+ * @return The implementation of NbPropertyEditorManager.
+ */
+ public static NbPropertyEditorManager getDefault() {
+ if (defaultInstance == null) {
+ try {
+ defaultInstance = (NbPropertyEditorManager) Lookup.getDefault().lookup (NbPropertyEditorManager.class);
+ } catch (Exception e) {
+ ErrorManager.getDefault().log (ErrorManager.INFORMATIONAL,
+ "No instance of NbPropertyEditorManager registered in lookup. Using proxy for java.beans.PropertyEditorManager instead."); //NOI18N
+ ErrorManager.getDefault().notify (ErrorManager.INFORMATIONAL, e);
+ } finally {
+ if (defaultInstance == null) defaultInstance = new BeansWrapper();
+ return defaultInstance;
+ }
+ }
+ return defaultInstance;
+ }
+ /*
+ //could optionally implement as static methods, changing names of instance methods
+ public static final PropertyEditor findEditor (Class clazz, boolean newInstance) {
+ return getDefault().findEditor (clazz, newInstance);
+ }
+
+ public static final PropertyEditor findEditor (Class clazz) {
+ return getDefault().findEditor (clazz);
+ }
+
+ public static final boolean hasEditor (Class clazz) {
+ return getDefault().hasEditor (clazz);
+ }
+
+ public static final Info findInfo (Class clazz) {
+ return getDefault().findInfo (clazz);
+ }
+ */
+
+ /** Find a property editor for the given class, specifying whether a new
+ * or shared instance should be used. Looks first for
+ * editors registered with the NetBeans property editor
+ * infrastructure, and if it finds none, falls back to
+ * java.beans.PropertyEditorManager.
+ * Do not attach listeners to instances returned when
+ * newInstance
is false! Such returned property
+ * editors' values are liable to change without notice, as
+ * property displaying infrastructure may reconfigure them
+ * without notice!
+ * @param clazz The class an editor is sought for.
+ * @param newInstance If true, method will return a new instance of the class in question.
+ * @return A property editor instance.
+ */
+ public abstract PropertyEditor findEditor (Class clazz, boolean newInstance);
+ /** Find an editor for the given class. There are two use cases for
+ * property editors - as renderers, which are used merely for
+ * display purposes, and to actually edit properties.
Looks first for
+ * editors registered with the NetBeans property editor
+ * infrastructure, and if it finds none, falls back to
+ * java.beans.PropertyEditorManager.
+ * @param clazz The class an editor is sought for
+ * @return A new property editor instance
+ */
+ public abstract PropertyEditor findEditor (Class clazz);
+ /** Returns true if a property editor has been registered with
+ * this implementation (if using the default NetBeans implementation,
+ * this means if an editor has been registered using XML). Note
+ * that findEditor()
may return true even if this
+ * method returns false, in the case that an editor was registered
+ * via java.beans.PropertyEditorManager
.
+ * @param clazz The class sought
+ * @return True if an editor has been registered
+ */
+ public abstract boolean hasEditor (Class clazz);
+ /** Get an object representing the extended information that is part
+ * of property editor registration. This information is primarily
+ * used by the property sheet infrastructure for performance
+ * optimizations.
+ * @param clazz The class an Info object is sought for
+ * @return An Info instance containing the extended registration
+ * information, or null if no editor was registered using
+ * the default registration mechanism (this does not mean
+ * that no editor was registered with
+ * java.beans.PropertyEditorManager
.
+ */
+ public abstract Info findInfo (Class clazz);
+
+ /** Extended information pertaining to a property editor. */
+ public interface Info {
+ /** Get an instance of the property editor class represented by
+ * this Info object. If newInstance
is false, do
+ * not attach listeners to the result!
+ * @param newInstance True if a new instance of this property editor is desired, rather than a shared
+ * instance
+ * @return The property editor instance
+ */
+ public PropertyEditor get (boolean newInstance);
+ /**Get an arbitrary keyed attribute pertaining to the property editor.
+ * This method is here for future flexibility - there is the
+ * potential for optimizations if property editors register
+ * additional information about themselves. */
+ public Object getAttribute (Object key);
+ }
+
+ /**A fallback default implementation in the case that no
+ * instance of NbPropertyEditorManager is registered via
+ * a layer.*/
+ private static class BeansWrapper extends NbPropertyEditorManager {
+
+ public PropertyEditor findEditor(Class clazz) {
+ return PropertyEditorManager.findEditor (clazz);
+ }
+
+ public PropertyEditor findEditor(Class clazz, boolean newInstance) {
+ return PropertyEditorManager.findEditor (clazz);
+ }
+
+ public Info findInfo(Class clazz) {
+ return null;
+ }
+
+ public boolean hasEditor(Class clazz) {
+ return false;
+ }
+
+ }
+
+}
Index: openide/src/org/openide/nodes/Node.java
===================================================================
RCS file: /cvs/openide/src/org/openide/nodes/Node.java,v
retrieving revision 1.60
diff -u -r1.60 Node.java
--- openide/src/org/openide/nodes/Node.java 16 Jan 2003 15:13:22 -0000 1.60
+++ openide/src/org/openide/nodes/Node.java 16 Jan 2003 18:07:00 -0000
@@ -23,6 +23,7 @@
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
+import java.lang.ref.SoftReference;
import java.util.WeakHashMap;
import javax.swing.Action;
import javax.swing.JPopupMenu;
@@ -36,6 +37,7 @@
import org.openide.util.LookupListener;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;
+import org.openide.util.NbPropertyEditorManager;
/** A node represents one element in a hierarchy of objects (beans).
@@ -1057,13 +1059,20 @@
return true;
}
+ SoftReference ped = null;
/** Get a property editor for this property.
* The default implementation tries to use {@link java.beans.PropertyEditorManager}.
- * @return the property editor, or null
if there is no editor
- */
+ * @return the property editor, or null
if there is no editor */
public PropertyEditor getPropertyEditor () {
if (type == null) return null;
- return java.beans.PropertyEditorManager.findEditor(type);
+ PropertyEditor result=null;
+ if (ped != null) {
+ result = (PropertyEditor) ped.get();
+ if (result != null) return result;
+ }
+ result = NbPropertyEditorManager.getDefault().findEditor (type);
+ ped = new SoftReference (result);
+ return result;
}
/* Standard equals implementation for all property
@@ -1259,7 +1268,6 @@
if (result == null) {
result = lookup.lookup (TEMPL_COOKIE);
result.addLookupListener (this);
- result.allItems();
}
}