/* java.beans.PropertyEditorManager
   Copyright (C) 1998 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.beans;

import gnu.java.beans.editors.ColorEditor;
import gnu.java.beans.editors.FontEditor;
import gnu.java.beans.editors.NativeBooleanEditor;
import gnu.java.beans.editors.NativeByteEditor;
import gnu.java.beans.editors.NativeDoubleEditor;
import gnu.java.beans.editors.NativeFloatEditor;
import gnu.java.beans.editors.NativeIntEditor;
import gnu.java.beans.editors.NativeLongEditor;
import gnu.java.beans.editors.NativeShortEditor;
import gnu.java.beans.editors.StringEditor;
import gnu.java.lang.ClassHelper;

import java.awt.Color;
import java.awt.Font;

/**
 * PropertyEditorManager is used to find property editors
 * for various types (not necessarily Beans).<P>
 *
 * It first checks to see if the property editor is
 * already registered; if it is, that property editor is
 * used.  Next it takes the type's classname and appends
 * "Editor" to it, and searches first in the class's
 * package and then in the property editor search path.
 *
 * <p>Default property editors are provided for:</p>
 * 
 * <ol>
 * <li>boolean, byte, short, int, long, float, and double</li>
 * <li>java.lang.String</li>
 * <li>java.awt.Color</li>
 * <li>java.awt.Font</li>
 * </ol>
 *
 * <p><strong>Spec Suggestion:</strong> Perhaps an editor for
 * Filename or something like it should be provided.  As well
 * as char.</p>
 *
 * @author John Keiser
 * @since 1.1
 * @version 1.1.0, 29 Jul 1998
 */

public class PropertyEditorManager
{
  static java.util.Hashtable editors = new java.util.Hashtable();
  static String[] editorSearchPath = { "gnu.java.beans.editors",
                                       "sun.beans.editors" };

  static
    {
      registerEditor(Boolean.TYPE, NativeBooleanEditor.class);
      registerEditor(Byte.TYPE,    NativeByteEditor.class);
      registerEditor(Short.TYPE,   NativeShortEditor.class);
      registerEditor(Integer.TYPE, NativeIntEditor.class);
      registerEditor(Long.TYPE,    NativeLongEditor.class);
      registerEditor(Float.TYPE,   NativeFloatEditor.class);
      registerEditor(Double.TYPE,  NativeDoubleEditor.class);
      registerEditor(String.class, StringEditor.class);
      registerEditor(Color.class,  ColorEditor.class);
      registerEditor(Font.class,   FontEditor.class);
    }

  /**
   * Beats me why this class can be instantiated, but there
   * you have it.
   */
  public PropertyEditorManager()
  {
    // Do nothing here
  }

  /**
   * Register an editor for a class.  Replaces old editor
   * if there was one registered before.
   *
   * @param editedClass the class that the property editor
   *        will edit.
   * @param editorClass the PropertyEditor class.
   */
  public static void registerEditor(Class editedClass, Class editorClass)
  {
    editors.put(editedClass, editorClass);
  }

  /**
   * Returns a new instance of the property editor for the
   * specified class.
   *
   * @param editedClass the class that the property editor
   *        will edit.
   * @return a PropertyEditor instance that can edit the
   *         specified class.
   */
  public static PropertyEditor findEditor(Class editedClass)
  {
    try
      {
        Class found = (Class)editors.get(editedClass);
        if(found != null)
          {
            return (PropertyEditor)found.newInstance();
          }

	ClassLoader contextClassLoader
		= Thread.currentThread().getContextClassLoader();

        try
          {
            found = Class.forName(editedClass.getName()+"Editor", true,
				  contextClassLoader);
            registerEditor(editedClass,found);
            return (PropertyEditor)found.newInstance();
          }
        catch(ClassNotFoundException E)
          {
          }

        String appendName
		= "."
		+ ClassHelper.getTruncatedClassName(editedClass)
		+ "Editor";
        synchronized(editorSearchPath)
          {
            for(int i=0;i<editorSearchPath.length;i++)
              {
                try
                  {
                    found = Class.forName(editorSearchPath[i] + appendName,
					  true, contextClassLoader);
                    registerEditor(editedClass,found);
                    return (PropertyEditor)found.newInstance();
                  }
                catch(ClassNotFoundException E)
                  {
                  }
              }
          }
      }
    catch(InstantiationException E)
      {
      }
    catch(IllegalAccessException E)
      {
      }
    
    return null;
  }

  /**
   * Get the editor search path.
   * As a minor departure from the spec, the default value
   * for the editor search path is "gnu.java.beans.editors",
   * "sun.beans.editors".
   *
   * @return the editor search path.
   */
  public static String[] getEditorSearchPath()
  {
    return editorSearchPath;
  }

  /**
   * Set the editor search path.
   *
   * @param editorSearchPath the new value for the editor search path.
   */
  public static void setEditorSearchPath(String[] editorSearchPath)
  {
    synchronized(editorSearchPath)
      {
        PropertyEditorManager.editorSearchPath = editorSearchPath;
      }
  }
}
