KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > framework > tools > beans > BeanFactory


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

18
19 package sync4j.framework.tools.beans;
20
21 import java.beans.XMLEncoder JavaDoc;
22 import java.beans.XMLDecoder JavaDoc;
23
24 import java.io.*;
25
26 import sync4j.framework.tools.beans.LazyInitBean;
27 import sync4j.framework.tools.beans.BeanException;
28 import sync4j.framework.tools.beans.BeanInstantiationException;
29 import sync4j.framework.tools.beans.BeanInitializationException;
30
31
32
33 /**
34  * This is a JavaBeans factory. At the moment it has a very simple
35  * implementation: it loads the class from a serialized file at runtime.
36  *
37  * @author Stefano Fornari @ Funambol
38  * @version $Id: BeanFactory.java,v 1.14 2005/06/03 22:59:00 stefano_fornari Exp $
39  */

40 public class BeanFactory {
41
42     protected BeanFactory() { }
43
44     /**
45      * Creates an instance of the given bean. The bean is first search as a
46      * class. If not found as class, it is searched as a resource. There isn't a
47      * lazy initialization.
48      *
49      * @param classLoader the class loader to use for loading the bean
50      * @param beanName name of the bean (for now is also the file name,
51      * without .ser, into which the bean has been serialized)
52      * NOT NULL
53      *
54      * @return a new instance of the serialized bean
55      *
56      * @throws BeanInstantiationException if the bean cannot be istantiated
57      * @throws BeanInitializationException if an initialization error occurred
58      * @throws BeanNotFoundException if the bean does not exist
59      */

60     public static Object JavaDoc getNoInitBeanInstance(ClassLoader JavaDoc classLoader, String JavaDoc beanName)
61     throws BeanInstantiationException,
62            BeanInitializationException,
63            BeanNotFoundException {
64
65         if (classLoader == null) {
66             classLoader = ClassLoader.getSystemClassLoader();
67         }
68
69         Object JavaDoc bean = null;
70
71         //
72
// Search beanName as a class
73
//
74
try {
75             bean = Class.forName(beanName, true, classLoader).newInstance();
76             if (bean instanceof LazyInitBean) {
77                 ((LazyInitBean)bean).init();
78             }
79             return bean;
80         } catch (ClassNotFoundException JavaDoc e) {
81             //
82
// beanName does not represent a class!
83
//
84
} catch (BeanInitializationException e) {
85             throw e;
86         } catch (Exception JavaDoc e) {
87             //
88
// Other exceptions are not good!
89
//
90
throw new BeanInstantiationException( "Error instantiating "
91                                                 + beanName
92                                                 , e
93                                                 );
94         }
95         InputStream is = classLoader.getResourceAsStream(beanName);
96
97         if (is == null) {
98             throw new BeanNotFoundException( beanName, classLoader);
99         }
100
101         BeanExceptionListener exceptionListener = new BeanExceptionListener();
102
103         //
104
// IMPORTANT NOTE
105
// --------------
106
//
107
// This serialization is a very important flaw for scalability, but we
108
// must do it for a bug in XMLDecoder (see bug # 4822050:
109
// http://developer.java.sun.com/developer/bugParade/bugs/4822050.html )
110
//
111
synchronized (BeanFactory.class) {
112             XMLDecoder JavaDoc d = new XMLDecoder JavaDoc(is, null, exceptionListener);
113             bean = d.readObject();
114             d.close();
115         }
116
117         if (exceptionListener.exceptionThrown()) {
118             Throwable JavaDoc t = exceptionListener.getException();
119
120             if (t.getCause() != null) {
121                 t = t.getCause();
122             }
123             throw new BeanInstantiationException( "Error instantiating "
124                                                 + beanName
125                                                 , t
126                                                 );
127         }
128
129         return bean;
130     }
131
132     /**
133      * Creates an instance of the given bean. The bean is first search as a
134      * class. If not found as class, it is searched as a resource.
135      *
136      * @param classLoader the class loader to use for loading the bean
137      * @param beanName name of the bean (for now is also the file name,
138      * without .ser, into which the bean has been serialized)
139      * NOT NULL
140      *
141      * @return a new instance of the serialized bean
142      *
143      * @throws BeanInstantiationException if the bean cannot be istantiated
144      * @throws BeanInitializationException if an initialization error occurred
145      * @throws BeanNotFoundException if the bean does not exist
146      */

147     public static Object JavaDoc getBeanInstance(ClassLoader JavaDoc classLoader, String JavaDoc beanName)
148     throws BeanInstantiationException,
149            BeanInitializationException,
150            BeanNotFoundException {
151
152         Object JavaDoc bean = null;
153
154         bean = getNoInitBeanInstance(classLoader, beanName);
155
156         if (bean instanceof LazyInitBean) {
157             ((LazyInitBean)bean).init();
158         }
159
160         return bean;
161     }
162
163
164     /**
165      * Creates an instance of the given bean using the system class loader.
166      *
167      * @param beanName name of the bean (for now is also the file name,
168      * without .ser, into which the bean has been serialized)
169      *
170      * @return a new instance of the serialized bean
171      *
172      * @throws BeanInstantiationException if the bean cannot be istantiated
173      * @throws BeanInitializationException if an initialization error occurred
174      * @throws BeanNotFoundException if the bean does not exist
175      */

176     public static Object JavaDoc getBeanInstance(String JavaDoc beanName)
177     throws BeanInstantiationException,
178            BeanInitializationException,
179            BeanNotFoundException {
180            return getBeanInstance(null, beanName);
181     }
182
183
184     /**
185      * Creates an instance of the given bean. This version deserializes the bean
186      * from the given file.
187      *
188      * @param beanFile the filename of the serialized file
189      *
190      * @return a new instance of the serialized bean
191      *
192      * @throws BeanInstantiationException if the bean cannot be istantiated
193      * @throws BeanInitializationException if an initialization error occurred
194      * @throws BeanNotFoundException if the bean does not exist
195      */

196     public static Object JavaDoc getBeanInstance(File beanFile)
197     throws BeanInstantiationException,
198            BeanInitializationException,
199            BeanNotFoundException {
200         try {
201             Object JavaDoc bean = null;
202
203             XMLDecoder JavaDoc e = new XMLDecoder JavaDoc(new FileInputStream(beanFile));
204             bean = e.readObject();
205             e.close();
206
207             if (bean instanceof LazyInitBean) {
208                 ((LazyInitBean)bean).init();
209             }
210             return bean;
211         } catch (FileNotFoundException e) {
212             throw new BeanNotFoundException(beanFile.getName(), (ClassLoader JavaDoc)null);
213         } catch (Exception JavaDoc e) {
214             String JavaDoc msg = "Bean creation ("
215                        + beanFile
216                        + ") failed: "
217                        + e.getMessage()
218                        ;
219             throw new BeanInstantiationException(msg, e);
220         }
221     }
222
223     /**
224      * Serialize the given object in the give file using XMLEncoder.
225      *
226      * @param obj the object to be serialized
227      * @param file the file into wich serialize the object
228      *
229      * @throws BeanException in case of errors
230      */

231     public static void saveBeanInstance(Object JavaDoc obj, File file)
232     throws BeanException {
233         XMLEncoder JavaDoc encoder = null;
234
235         try {
236             encoder = new XMLEncoder JavaDoc(new FileOutputStream(file));
237             encoder.writeObject(obj);
238         } catch (IOException e) {
239             String JavaDoc msg = "Bean saving (" + file + ") failed: " + e.getMessage();
240             throw new BeanException(msg, e);
241         } finally {
242             if (encoder != null) {
243                 encoder.close();
244             }
245         }
246     }
247
248     /**
249      * Marshals the given object into XML using <i>java.beans.XMLEncoder</i>.
250      *
251      * @param o the object to marshal
252      *
253      * @return the XML form of the object
254      *
255      * @throws BeanException in case of marshalling errors
256      */

257     public static String JavaDoc marshal(ClassLoader JavaDoc classLoader, Object JavaDoc o)
258     throws BeanException {
259         XMLEncoder JavaDoc enc = null;
260         ClassLoader JavaDoc oldClassLoader = null;
261
262         if (classLoader != null) {
263             oldClassLoader = Thread.currentThread().getContextClassLoader();
264             Thread.currentThread().setContextClassLoader(classLoader);
265         }
266
267         BeanExceptionListener exceptionListener = new BeanExceptionListener();
268         
269         try {
270             ByteArrayOutputStream os = new ByteArrayOutputStream();
271
272             enc = new XMLEncoder JavaDoc(os);
273
274             enc.writeObject(o);
275
276             enc.close(); enc = null; // we need to do this here to get the string
277

278             if (exceptionListener.exceptionThrown()) {
279                 Throwable JavaDoc t = exceptionListener.getException();
280                 throw new BeanException(t.getMessage(), t);
281             }
282             
283             return os.toString();
284         } finally {
285             if (enc != null) {
286                 enc.close();
287             }
288
289             if (classLoader != null) {
290                 Thread.currentThread().setContextClassLoader(oldClassLoader);
291             }
292         }
293     }
294
295     /**
296      * Marshals the given object into XML using <i>java.beans.XMLEncoder</i>.
297      *
298      * @param o the object to marshal
299      *
300      * @return the XML form of the object
301      *
302      * @throws BeanException in case of marshalling errors
303      */

304     public static String JavaDoc marshal(Object JavaDoc o)
305     throws BeanException {
306         return marshal(null, o);
307     }
308
309
310     /**
311      * Unmarshals the given serialized object into the corresponding instance
312      * using <i>java.beans.XMLDecoder</i>.
313      *
314      * @param classLoader the class loader to use (null for the standard one)
315      * @param xml XML serialized form
316      *
317      * @return the unmarshalled instance
318      *
319      * @throws BeanException in case of unmarshalling errors
320      */

321     public static Object JavaDoc unmarshal(ClassLoader JavaDoc classLoader, String JavaDoc xml)
322     throws BeanException {
323         XMLDecoder JavaDoc dec = null;
324         ClassLoader JavaDoc oldClassLoader = null;
325
326         if (classLoader != null) {
327             oldClassLoader = Thread.currentThread().getContextClassLoader();
328             Thread.currentThread().setContextClassLoader(classLoader);
329         }
330
331         BeanExceptionListener exceptionListener = new BeanExceptionListener();
332         
333         try {
334             ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes());
335
336             dec = new XMLDecoder JavaDoc(is);
337
338             Object JavaDoc ret = dec.readObject();
339             
340             dec.close(); dec = null;
341             
342             if (exceptionListener.exceptionThrown()) {
343                 Throwable JavaDoc t = exceptionListener.getException();
344                 throw new BeanException(t.getMessage(), t);
345             }
346
347             return ret;
348         } finally {
349             if (dec != null) {
350                 dec.close();
351             }
352
353             if (classLoader != null) {
354                 Thread.currentThread().setContextClassLoader(oldClassLoader);
355             }
356         }
357     }
358
359     /**
360      * The same as <i>unmarshal(null, xml)</i>
361      *
362      * @param xml XML serialized form
363      *
364      * @return the unmarshalled instance
365      *
366      * @throws BeanException in case of unmarshalling errors
367      */

368     public static Object JavaDoc unmarshal(String JavaDoc xml)
369     throws BeanException {
370         return unmarshal(null, xml);
371     }
372
373     /**
374      * Creates a bean instance given the class name and serialize it in the
375      * specified file. The object is serialized in XML.
376      * <p>
377      * Syntax:<br>
378      * sync4j.framework.tools.beans.BeanFactory <i>class name</i> </i>file name</i>
379      **/

380     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
381         if (args.length != 2) {
382             System.out.println("Syntax: sync4j.framework.tools.beans.BeanFactory <class name> <file name>");
383             return;
384         }
385
386         saveBeanInstance(getBeanInstance(args[0]), new File(args[1]));
387     }
388 }
389
Popular Tags