1. /*
  2. * @(#)PropertyEditorManager.java 1.45 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.beans;
  8. /**
  9. * The PropertyEditorManager can be used to locate a property editor for
  10. * any given type name. This property editor must support the
  11. * java.beans.PropertyEditor interface for editing a given object.
  12. * <P>
  13. * The PropertyEditorManager uses three techniques for locating an editor
  14. * for a given type. First, it provides a registerEditor method to allow
  15. * an editor to be specifically registered for a given type. Second it
  16. * tries to locate a suitable class by adding "Editor" to the full
  17. * qualified classname of the given type (e.g. "foo.bah.FozEditor").
  18. * Finally it takes the simple classname (without the package name) adds
  19. * "Editor" to it and looks in a search-path of packages for a matching
  20. * class.
  21. * <P>
  22. * So for an input class foo.bah.Fred, the PropertyEditorManager would
  23. * first look in its tables to see if an editor had been registered for
  24. * foo.bah.Fred and if so use that. Then it will look for a
  25. * foo.bah.FredEditor class. Then it will look for (say)
  26. * standardEditorsPackage.FredEditor class.
  27. * <p>
  28. * Default PropertyEditors will be provided for the Java primitive types
  29. * "boolean", "byte", "short", "int", "long", "float", and "double"; and
  30. * for the classes java.lang.String. java.awt.Color, and java.awt.Font.
  31. */
  32. public class PropertyEditorManager {
  33. /**
  34. * Register an editor class to be used to edit values of
  35. * a given target class.
  36. *
  37. * <p>First, if there is a security manager, its <code>checkPropertiesAccess</code>
  38. * method is called. This could result in a SecurityException.
  39. *
  40. * @param targetType the Class object of the type to be edited
  41. * @param editorClass the Class object of the editor class. If
  42. * this is null, then any existing definition will be removed.
  43. * @exception SecurityException if a security manager exists and its
  44. * <code>checkPropertiesAccess</code> method doesn't allow setting
  45. * of system properties.
  46. * @see SecurityManager#checkPropertiesAccess
  47. */
  48. public static void registerEditor(Class<?> targetType, Class<?> editorClass) {
  49. SecurityManager sm = System.getSecurityManager();
  50. if (sm != null) {
  51. sm.checkPropertiesAccess();
  52. }
  53. initialize();
  54. if (editorClass == null) {
  55. registry.remove(targetType);
  56. } else {
  57. registry.put(targetType, editorClass);
  58. }
  59. }
  60. /**
  61. * Locate a value editor for a given target type.
  62. *
  63. * @param targetType The Class object for the type to be edited
  64. * @return An editor object for the given target class.
  65. * The result is null if no suitable editor can be found.
  66. */
  67. public static synchronized PropertyEditor findEditor(Class<?> targetType) {
  68. initialize();
  69. Class editorClass = (Class)registry.get(targetType);
  70. if (editorClass != null) {
  71. try {
  72. Object o = editorClass.newInstance();
  73. return (PropertyEditor)o;
  74. } catch (Exception ex) {
  75. System.err.println("Couldn't instantiate type editor \"" +
  76. editorClass.getName() + "\" : " + ex);
  77. }
  78. }
  79. // Now try adding "Editor" to the class name.
  80. String editorName = targetType.getName() + "Editor";
  81. try {
  82. return (PropertyEditor) Introspector.instantiate(targetType, editorName);
  83. } catch (Exception ex) {
  84. // Silently ignore any errors.
  85. }
  86. // Now try looking for <searchPath>.fooEditor
  87. editorName = targetType.getName();
  88. while (editorName.indexOf('.') > 0) {
  89. editorName = editorName.substring(editorName.indexOf('.')+1);
  90. }
  91. for (int i = 0; i < searchPath.length; i++) {
  92. String name = searchPath[i] + "." + editorName + "Editor";
  93. try {
  94. return (PropertyEditor) Introspector.instantiate(targetType, name);
  95. } catch (Exception ex) {
  96. // Silently ignore any errors.
  97. }
  98. }
  99. // We couldn't find a suitable Editor.
  100. return null;
  101. }
  102. /**
  103. * Gets the package names that will be searched for property editors.
  104. *
  105. * @return The array of package names that will be searched in
  106. * order to find property editors.
  107. * <p> The default value for this array is implementation-dependent,
  108. * e.g. Sun implementation initially sets to {"sun.beans.editors"}.
  109. */
  110. public static synchronized String[] getEditorSearchPath() {
  111. // Return a copy of the searchPath.
  112. String result[] = new String[searchPath.length];
  113. for (int i = 0; i < searchPath.length; i++) {
  114. result[i] = searchPath[i];
  115. }
  116. return result;
  117. }
  118. /**
  119. * Change the list of package names that will be used for
  120. * finding property editors.
  121. *
  122. * <p>First, if there is a security manager, its <code>checkPropertiesAccess</code>
  123. * method is called. This could result in a SecurityException.
  124. *
  125. * @param path Array of package names.
  126. * @exception SecurityException if a security manager exists and its
  127. * <code>checkPropertiesAccess</code> method doesn't allow setting
  128. * of system properties.
  129. * @see SecurityManager#checkPropertiesAccess
  130. */
  131. public static synchronized void setEditorSearchPath(String path[]) {
  132. SecurityManager sm = System.getSecurityManager();
  133. if (sm != null) {
  134. sm.checkPropertiesAccess();
  135. }
  136. initialize();
  137. if (path == null) {
  138. path = new String[0];
  139. }
  140. searchPath = path;
  141. }
  142. private static synchronized void load(Class targetType, String name) {
  143. String editorName = name;
  144. for (int i = 0; i < searchPath.length; i++) {
  145. try {
  146. editorName = searchPath[i] + "." + name;
  147. Class cls = Class.forName(editorName);
  148. registry.put(targetType, cls);
  149. return;
  150. } catch (Exception ex) {
  151. // Drop through and try next package.
  152. }
  153. }
  154. // This shouldn't happen.
  155. System.err.println("load of " + editorName + " failed");
  156. }
  157. private static synchronized void initialize() {
  158. if (registry != null) {
  159. return;
  160. }
  161. registry = new java.util.Hashtable();
  162. load(Byte.TYPE, "ByteEditor");
  163. load(Short.TYPE, "ShortEditor");
  164. load(Integer.TYPE, "IntEditor");
  165. load(Long.TYPE ,"LongEditor");
  166. load(Boolean.TYPE, "BoolEditor");
  167. load(Float.TYPE, "FloatEditor");
  168. load(Double.TYPE, "DoubleEditor");
  169. }
  170. private static String[] searchPath = { "sun.beans.editors" };
  171. private static java.util.Hashtable registry;
  172. }