KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > java > plugin > ObjectFactory


1 /*****************************************************************************
2  * Java Plug-in Framework (JPF)
3  * Copyright (C) 2004-2006 Dmitry Olshansky
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *****************************************************************************/

19 package org.java.plugin;
20
21 import java.io.BufferedReader JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.io.InputStreamReader JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.java.plugin.registry.PluginRegistry;
32 import org.java.plugin.standard.StandardObjectFactory;
33 import org.java.plugin.util.ExtendedProperties;
34 import org.java.plugin.util.IoUtil;
35
36 /**
37  * Factory class to help creating base Framework objects: plug-in registry,
38  * path resolver and plug-in manager.
39  *
40  * @version $Id: ObjectFactory.java,v 1.10 2006/08/26 15:14:10 ddimon Exp $
41  */

42 public abstract class ObjectFactory {
43     /**
44      * Creates and configures new instance of object factory.
45      * @return configured instance of object factory
46      *
47      * @see #newInstance(ExtendedProperties)
48      */

49     public static ObjectFactory newInstance() {
50         return newInstance(null);
51     }
52     
53     /**
54      * Creates and configures new instance of object factory. Factory
55      * implementation class discovery procedure is following:
56      * <ul>
57      * <li>Use the <code>org.java.plugin.ObjectFactory</code> property from
58      * the given properties collection (if it is provided).</li>
59      * <li>Use the <code>org.java.plugin.ObjectFactory</code> system
60      * property.</li>
61      * <li>Use the properties file "jpf.properties" in the JRE "lib"
62      * directory or in the CLASSPATH. This configuration file is in standard
63      * <code>java.util.Properties</code> format and contains among others the
64      * fully qualified name of the implementation class with the key being the
65      * system property defined above.</li>
66      * <li>Use the Services API (as detailed in the JAR specification), if
67      * available, to determine the class name. The Services API will look for
68      * a class name in the file
69      * <code>META-INF/services/org.java.plugin.ObjectFactory</code> in jars
70      * available to the runtime.</li>
71      * <li>Framework default <code>ObjectFactory</code> implementation.</li>
72      * </ul>
73      * @param config factory configuration data, may be <code>null</code>
74      * @return configured instance of object factory
75      */

76     public static ObjectFactory newInstance(final ExtendedProperties config) {
77         Log log = LogFactory.getLog(ObjectFactory.class);
78         ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
79         if (cl == null) {
80             cl = ObjectFactory.class.getClassLoader();
81         }
82         ExtendedProperties props;
83         if (config != null) {
84             props = config;
85         } else {
86             props = loadProperties(cl);
87         }
88         String JavaDoc className = findProperty(cl, props);
89         ObjectFactory result;
90         try {
91             if (className == null) {
92                 className = "org.java.plugin.standard.StandardObjectFactory"; //$NON-NLS-1$
93
}
94             result = (ObjectFactory) loadClass(cl, className).newInstance();
95         } catch (ClassNotFoundException JavaDoc cnfe) {
96             log.fatal("failed instantiating object factory " //$NON-NLS-1$
97
+ className, cnfe);
98             throw new Error JavaDoc("failed instantiating object factory " //$NON-NLS-1$
99
+ className, cnfe);
100         } catch (IllegalAccessException JavaDoc iae) {
101             log.fatal("failed instantiating object factory " //$NON-NLS-1$
102
+ className, iae);
103             throw new Error JavaDoc("failed instantiating object factory " //$NON-NLS-1$
104
+ className, iae);
105         } catch (SecurityException JavaDoc se) {
106             log.fatal("failed instantiating object factory " //$NON-NLS-1$
107
+ className, se);
108             throw new Error JavaDoc("failed instantiating object factory " //$NON-NLS-1$
109
+ className, se);
110         } catch (InstantiationException JavaDoc ie) {
111             log.fatal("failed instantiating object factory " //$NON-NLS-1$
112
+ className, ie);
113             throw new Error JavaDoc("failed instantiating object factory " //$NON-NLS-1$
114
+ className, ie);
115         }
116         result.configure(props);
117         log.debug("object factory instance created - " + result); //$NON-NLS-1$
118
return result;
119     }
120     
121     private static Class JavaDoc loadClass(final ClassLoader JavaDoc cl, final String JavaDoc className)
122             throws ClassNotFoundException JavaDoc {
123         if (cl != null) {
124             try {
125                 return cl.loadClass(className);
126             } catch (ClassNotFoundException JavaDoc cnfe) {
127                 // ignore
128
}
129         }
130         ClassLoader JavaDoc cl2 = ObjectFactory.class.getClassLoader();
131         if (cl2 != null) {
132             try {
133                 return cl2.loadClass(className);
134             } catch (ClassNotFoundException JavaDoc cnfe) {
135                 // ignore
136
}
137         }
138         return ClassLoader.getSystemClassLoader().loadClass(className);
139     }
140     
141     private static ExtendedProperties loadProperties(final ClassLoader JavaDoc cl) {
142         Log log = LogFactory.getLog(ObjectFactory.class);
143         File JavaDoc file = new File JavaDoc(System.getProperty("java.home") //$NON-NLS-1$
144
+ File.separator + "lib" + File.separator //$NON-NLS-1$
145
+ "jpf.properties"); //$NON-NLS-1$
146
URL JavaDoc url = null;
147         if (file.canRead()) {
148             try {
149                 url = IoUtil.file2url(file);
150             } catch (MalformedURLException JavaDoc mue) {
151                 log.error("failed converting file " + file //$NON-NLS-1$
152
+ " to URL", mue); //$NON-NLS-1$
153
}
154         }
155         if (url == null) {
156             if (cl != null) {
157                 url = cl.getResource("jpf.properties"); //$NON-NLS-1$
158
if (url == null) {
159                     url = ClassLoader.getSystemResource("jpf.properties"); //$NON-NLS-1$
160
}
161             } else {
162                 url = ClassLoader.getSystemResource("jpf.properties"); //$NON-NLS-1$
163
}
164             if (url == null) {
165                 log.debug("no jpf.properties file found in ${java.home}/lib (" //$NON-NLS-1$
166
+ file
167                         + ") nor in CLASSPATH, using standard properties"); //$NON-NLS-1$
168
url = StandardObjectFactory.class.getResource("jpf.properties"); //$NON-NLS-1$
169
}
170         }
171         try {
172             InputStream JavaDoc strm = IoUtil.getResourceInputStream(url);
173             try {
174                 ExtendedProperties props = new ExtendedProperties();
175                 props.load(strm);
176                 log.debug("loaded jpf.properties from " + url); //$NON-NLS-1$
177
return props;
178             } finally {
179                 try {
180                     strm.close();
181                 } catch (IOException JavaDoc ioe) {
182                     // ignore
183
}
184             }
185         } catch (Exception JavaDoc e) {
186             log.error("failed loading jpf.properties from CLASSPATH", //$NON-NLS-1$
187
e);
188         }
189         return null;
190     }
191     
192     private static String JavaDoc findProperty(final ClassLoader JavaDoc cl,
193             final ExtendedProperties props) {
194         Log log = LogFactory.getLog(ObjectFactory.class);
195         String JavaDoc name = ObjectFactory.class.getName();
196         String JavaDoc result = System.getProperty(name);
197         if (result != null) {
198             log.debug("property " + name //$NON-NLS-1$
199
+ " found as system property"); //$NON-NLS-1$
200
return result;
201         }
202         if (props != null) {
203             result = props.getProperty(name);
204             if (result != null) {
205                 log.debug("property " + name //$NON-NLS-1$
206
+ " found in properties file"); //$NON-NLS-1$
207
return result;
208             }
209         }
210         String JavaDoc serviceId = "META-INF/services/" //$NON-NLS-1$
211
+ ObjectFactory.class.getName();
212         InputStream JavaDoc strm;
213         if (cl == null) {
214             strm = ClassLoader.getSystemResourceAsStream(serviceId);
215         } else {
216             strm = cl.getResourceAsStream(serviceId);
217         }
218         if (strm != null) {
219             try {
220                 BufferedReader JavaDoc reader = new BufferedReader JavaDoc(
221                         new InputStreamReader JavaDoc(strm, "UTF-8")); //$NON-NLS-1$
222
try {
223                     result = reader.readLine();
224                 } finally {
225                     try {
226                         reader.close();
227                     } catch (IOException JavaDoc ioe) {
228                         // ignore
229
}
230                 }
231             } catch (IOException JavaDoc ioe) {
232                 try {
233                     strm.close();
234                 } catch (IOException JavaDoc ioe2) {
235                     // ignore
236
}
237             }
238         }
239         if (result != null) {
240             log.debug("property " + name //$NON-NLS-1$
241
+ " found as service"); //$NON-NLS-1$
242
return result;
243         }
244         log.debug("no property " + name //$NON-NLS-1$
245
+ " found"); //$NON-NLS-1$
246
return result;
247     }
248     
249     /**
250      * Configures this factory instance. This method is called from
251      * {@link #newInstance(ExtendedProperties)}.
252      * @param config factory configuration data, may be <code>null</code>
253      */

254     protected abstract void configure(ExtendedProperties config);
255     
256     /**
257      * Creates new instance of plug-in manager using new instances of registry
258      * and path resolver.
259      * @return new plug-in manager instance
260      *
261      * @see #createRegistry()
262      * @see #createPathResolver()
263      */

264     public final PluginManager createManager() {
265         return createManager(createRegistry(), createPathResolver());
266     }
267     
268     /**
269      * Creates new instance of plug-in manager.
270      * @param registry
271      * @param pathResolver
272      * @return new plug-in manager instance
273      */

274     public abstract PluginManager createManager(PluginRegistry registry,
275             PathResolver pathResolver);
276     
277     /**
278      * Creates new instance of plug-in registry implementation class using
279      * standard discovery algorithm to determine which registry implementation
280      * class should be instantiated.
281      * @return new registry instance
282      */

283     public abstract PluginRegistry createRegistry();
284     
285     /**
286      * Creates new instance of path resolver implementation class using
287      * standard discovery algorithm to determine which resolver implementation
288      * class should be instantiated.
289      * @return new path resolver instance
290      */

291     public abstract PathResolver createPathResolver();
292 }
293
Popular Tags