001/* java.beans.PropertyEditorManager
002   Copyright (C) 1998 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.beans;
040
041import gnu.java.beans.editors.ColorEditor;
042import gnu.java.beans.editors.FontEditor;
043import gnu.java.beans.editors.NativeBooleanEditor;
044import gnu.java.beans.editors.NativeByteEditor;
045import gnu.java.beans.editors.NativeDoubleEditor;
046import gnu.java.beans.editors.NativeFloatEditor;
047import gnu.java.beans.editors.NativeIntEditor;
048import gnu.java.beans.editors.NativeLongEditor;
049import gnu.java.beans.editors.NativeShortEditor;
050import gnu.java.beans.editors.StringEditor;
051import gnu.java.lang.ClassHelper;
052
053import java.awt.Color;
054import java.awt.Font;
055
056/**
057 * PropertyEditorManager is used to find property editors
058 * for various types (not necessarily Beans).<P>
059 *
060 * It first checks to see if the property editor is
061 * already registered; if it is, that property editor is
062 * used.  Next it takes the type's classname and appends
063 * "Editor" to it, and searches first in the class's
064 * package and then in the property editor search path.
065 *
066 * <p>Default property editors are provided for:</p>
067 *
068 * <ol>
069 * <li>boolean, byte, short, int, long, float, and double</li>
070 * <li>java.lang.String</li>
071 * <li>java.awt.Color</li>
072 * <li>java.awt.Font</li>
073 * </ol>
074 *
075 * <p><strong>Spec Suggestion:</strong> Perhaps an editor for
076 * Filename or something like it should be provided.  As well
077 * as char.</p>
078 *
079 * @author John Keiser
080 * @since 1.1
081 * @version 1.1.0, 29 Jul 1998
082 */
083
084public class PropertyEditorManager
085{
086  static java.util.Hashtable<Class<?>,Class<?>> editors =
087    new java.util.Hashtable<Class<?>,Class<?>>();
088  static String[] editorSearchPath = { "gnu.java.beans.editors",
089                                       "sun.beans.editors" };
090
091  static
092    {
093      registerEditor(Boolean.TYPE, NativeBooleanEditor.class);
094      registerEditor(Byte.TYPE,    NativeByteEditor.class);
095      registerEditor(Short.TYPE,   NativeShortEditor.class);
096      registerEditor(Integer.TYPE, NativeIntEditor.class);
097      registerEditor(Long.TYPE,    NativeLongEditor.class);
098      registerEditor(Float.TYPE,   NativeFloatEditor.class);
099      registerEditor(Double.TYPE,  NativeDoubleEditor.class);
100      registerEditor(String.class, StringEditor.class);
101      registerEditor(Color.class,  ColorEditor.class);
102      registerEditor(Font.class,   FontEditor.class);
103    }
104
105  /**
106   * Beats me why this class can be instantiated, but there
107   * you have it.
108   */
109  public PropertyEditorManager()
110  {
111    // Do nothing here
112  }
113
114  /**
115   * Register an editor for a class.  Replaces old editor
116   * if there was one registered before.
117   *
118   * @param editedClass the class that the property editor
119   *        will edit.
120   * @param editorClass the PropertyEditor class.
121   */
122  public static void registerEditor(Class<?> editedClass, Class<?> editorClass)
123  {
124    editors.put(editedClass, editorClass);
125  }
126
127  /**
128   * Returns a new instance of the property editor for the
129   * specified class.
130   *
131   * @param editedClass the class that the property editor
132   *        will edit.
133   * @return a PropertyEditor instance that can edit the
134   *         specified class.
135   */
136  public static PropertyEditor findEditor(Class<?> editedClass)
137  {
138    try
139      {
140        Class found = (Class)editors.get(editedClass);
141        if(found != null)
142          {
143            return (PropertyEditor)found.newInstance();
144          }
145
146        ClassLoader contextClassLoader
147                = Thread.currentThread().getContextClassLoader();
148
149        try
150          {
151            found = Class.forName(editedClass.getName()+"Editor", true,
152                                  contextClassLoader);
153            registerEditor(editedClass,found);
154            return (PropertyEditor)found.newInstance();
155          }
156        catch(ClassNotFoundException E)
157          {
158          }
159
160        String appendName
161                = "."
162                + ClassHelper.getTruncatedClassName(editedClass)
163                + "Editor";
164        synchronized(editorSearchPath)
165          {
166            for(int i=0;i<editorSearchPath.length;i++)
167              {
168                try
169                  {
170                    found = Class.forName(editorSearchPath[i] + appendName,
171                                          true, contextClassLoader);
172                    registerEditor(editedClass,found);
173                    return (PropertyEditor)found.newInstance();
174                  }
175                catch(ClassNotFoundException E)
176                  {
177                  }
178              }
179          }
180      }
181    catch(InstantiationException E)
182      {
183      }
184    catch(IllegalAccessException E)
185      {
186      }
187
188    return null;
189  }
190
191  /**
192   * Get the editor search path.
193   * As a minor departure from the spec, the default value
194   * for the editor search path is "gnu.java.beans.editors",
195   * "sun.beans.editors".
196   *
197   * @return the editor search path.
198   */
199  public static String[] getEditorSearchPath()
200  {
201    return editorSearchPath;
202  }
203
204  /**
205   * Set the editor search path.
206   *
207   * @param editorSearchPath the new value for the editor search path.
208   */
209  public static void setEditorSearchPath(String[] editorSearchPath)
210  {
211    synchronized(editorSearchPath)
212      {
213        PropertyEditorManager.editorSearchPath = editorSearchPath;
214      }
215  }
216}