1 /* -------------------------------------------------------------------
2 * Java source file for the class FactoryManager
3 *
4 * Copyright (c), 2002, Masahiro Takatsuka.
5 * All Rights Researved.
6 *
7 * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8 * $Author: takatsukam $
9 *
10 * $Date: 2003/07/25 04:51:44 $
11 *
12 * $Id: FactoryManager.java,v 1.1.1.1 2003/07/25 04:51:44 takatsukam Exp $
13 *
14 * Reference: Document no:
15 * ___ ___
16 *
17 * To Do:
18 * ___
19 *
20 ------------------------------------------------------------------- */
21
22 /* --------------------------- Package ---------------------------- */
23 package net.jbeans.bean.factory;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">color="#329900"> ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">color="#329900"> ------------------ Import classes (packages) ------------------- */
26
27 /*====================================================================
28 Implementation of class FactoryManager
29 ====================================================================*/
30 /***
31 * The FactoryManager can be used to locate a factory class for
32 * any given class or class name. This factory class must support the
33 * net.jbeans.bean.factory.Factory interface for creating an instance of
34 * a given class.
35 * <P>
36 * The FactoryManager uses three techniques for locating a factory
37 * for a given type. First, it provides a registerFactory method to allow
38 * a factory to be specifically registered for a given type. Second it
39 * tries to locate a suitable class by adding "Factory" to the full
40 * qualified classname of the given type (e.g. "foo.bah.FozFactory").
41 * Finally it takes the simple classname (without the package name) adds
42 * "Factory" to it and looks in a search-path of packages for a matching
43 * class.
44 * <P>
45 * So for an input class foo.bah.Fred, the FactoryManager would
46 * first look in its tables to see if a factory had been registered for
47 * foo.bah.Fred and if so use that. Then it will look for a
48 * foo.bah.FredFactory class. Then it will look for (say)
49 * standardFactoryPackage.FredFactory class.
50 *
51 * @version $Revision: 1.1.1.1 $
52 * @author Masahiro Takatsuka (masa@jbeans.net)
53 */
54
55 public class FactoryManager {
56 private static String[] searchPath = {"net.jbeans.bean.factory"};
57 private static java.util.Hashtable registry;
58 private static java.util.Hashtable instances; // for reuse factory.
59
60 /***
61 * Register a factory to be used to instantiate an object of
62 * a given target class.
63 *
64 *
65 * @param targetType the Class object of the type to be instantiated
66 * @param factoryClass the Class object of the factory class. If
67 * this is null, then any existing definition will be removed.
68 */
69
70 public static void registerFactory(Class targetType, Class factoryClass) {
71 initialize();
72 if (factoryClass == null) {
73 registry.remove(targetType);
74 } else {
75 registry.put(targetType, factoryClass);
76 }
77 }
78
79 private static synchronized void initialize() {
80 if (registry == null) {
81 registry = new java.util.Hashtable();
82 }
83 if (instances == null) {
84 instances = new java.util.Hashtable();
85 }
86 }
87
88 /***
89 * Locate a value editor for a given target type.
90 *
91 * @param targetType The Class object for the type to be edited
92 * @return An editor object for the given target class.
93 * The result is null if no suitable editor can be found.
94 */
95
96 public static synchronized Factory findFactory(Class targetType) {
97 initialize();
98 Object instance = instances.get(targetType);
99 if (instance != null) {
100 return (Factory) instance;
101 }
102
103 Class factoryClass = (Class) registry.get(targetType);
104 if (factoryClass != null) {
105 try {
106 Object o = factoryClass.newInstance();
107 instances.put(targetType, o);
108 return (Factory) o;
109 } catch (Exception ex) {
110 System.err.println("Couldn't instantiate object \"" +
111 factoryClass.getName() + "\" : " + ex);
112 }
113 }
114
115 // Now try adding "Factory" to the class name.
116
117 String factoryName = targetType.getName() + "Factory";
118 try {
119 Class clazz = targetType.getClassLoader().loadClass(factoryName);
120 Object o = clazz.newInstance();
121 if (o instanceof Factory) {
122 instances.put(targetType, o);
123 return (Factory) o;
124 }
125 } catch (Exception ex) {
126 // Silently ignore any errors.
127 }
128
129 // Now try looking for <searchPath>.fooEditor
130 factoryName = targetType.getName();
131 while (factoryName.indexOf('.') > 0) {
132 factoryName = factoryName.substring(factoryName.indexOf('.') + 1);
133 }
134 for (int i = 0; i < searchPath.length; i++) {
135 String name = searchPath[i] + "." + factoryName + "Factory";
136 try {
137 Class clazz = targetType.getClassLoader().loadClass(name);
138 Object o = clazz.newInstance();
139 if (o instanceof Factory) {
140 instances.put(targetType, o);
141 return (Factory) o;
142 }
143 } catch (Exception ex) {
144 // Silently ignore any errors.
145 }
146 }
147
148 // We couldn't find a suitable Editor.
149 return null;
150 }
151
152 /***
153 * Gets the package names that will be searched for factories.
154 *
155 * @return The array of package names that will be searched in
156 * order to find factories.
157 * <p> This is initially set to {"net.jbeans.bean.factory"}.
158 */
159
160 public static synchronized String[] getEditorSearchPath() {
161 // Return a copy of the searchPath.
162 String result[] = new String[searchPath.length];
163 for (int i = 0; i < searchPath.length; i++) {
164 result[i] = searchPath[i];
165 }
166 return result;
167 }
168
169 /***
170 * Change the list of package names that will be used for
171 * finding factories.
172 *
173 * @param path Array of package names.
174 */
175
176 public static synchronized void setFactorySearchPath(String path[]) {
177 if (path == null) {
178 path = new String[0];
179 }
180 searchPath = path;
181 }
182
183 private static synchronized void load(Class targetType, String name) {
184 String factoryName = name;
185 for (int i = 0; i < searchPath.length; i++) {
186 try {
187 factoryName = searchPath[i] + "." + name;
188 Class cls = Class.forName(factoryName);
189 registry.put(targetType, cls);
190 return;
191 } catch (Exception ex) {
192 // Drop through and try next package.
193 }
194 }
195 // This shouldn't happen.
196 System.err.println("load of " + factoryName + " failed");
197 }
198 }
This page was automatically generated by Maven