(no commit message)
[utils] / support / general / src / main / java / org / wamblee / ioc / BeanKernel.java
1 /*
2  * Copyright 2005-2010 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.ioc;
17
18 import org.wamblee.io.ClassPathResource;
19 import org.wamblee.io.InputResource;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23
24 import java.util.Properties;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 /**
29  * The standard means to obtain the bean factory. This works by reading a
30  * property {@value #BEAN_FACTORY_CLASS} from a property file named
31  * {@value #BEAN_KERNEL_PROP_FILE} from the class path. This property identifies
32  * the bean factory implementation to use. The configured bean factory must have
33  * a no-arg constructor.
34  */
35 public final class BeanKernel {
36     private static final Logger LOG = Logger.getLogger(BeanKernel.class
37         .getName());
38
39     /**
40      * Bean factory kernel properties file.
41      */
42     private static final String BEAN_KERNEL_PROP_FILE = "org.wamblee.beanfactory.properties";
43
44     /**
45      * Name of the property to define the name of the bean factory class to use.
46      * THis class must have a public default constructor.
47      */
48     private static final String BEAN_FACTORY_CLASS = "org.wamblee.beanfactory.class";
49
50     /**
51      * Cached bean factory.
52      */
53     private static BeanFactory BEAN_FACTORY;
54
55     /**
56      * Disabled constructor.
57      * 
58      */
59     private BeanKernel() {
60         // Empty
61     }
62
63     /**
64      * Overrides the default mechanism for looking up the bean factory by
65      * specifying it yourself.
66      * 
67      * @param aOverride
68      *            Override bean factory.
69      */
70     public static void overrideBeanFactory(BeanFactory aOverride) {
71         BEAN_FACTORY = aOverride;
72     }
73
74     /**
75      * Gets the bean factory.
76      * 
77      * @return Bean factory.
78      */
79     public static BeanFactory getBeanFactory() {
80         synchronized (BeanFactory.class) {
81             if (BEAN_FACTORY == null) {
82                 BEAN_FACTORY = lookupBeanFactory(BEAN_KERNEL_PROP_FILE);
83             }
84         }
85
86         return BEAN_FACTORY;
87     }
88
89     /**
90      * Lookup the bean factory based on the properties file.
91      * 
92      * 
93      * @return Bean factory.
94      * 
95      */
96     static BeanFactory lookupBeanFactory(String aPropertyFilename) {
97         InputResource resource = new ClassPathResource(aPropertyFilename);
98         InputStream is;
99
100         try {
101             is = resource.getInputStream();
102         } catch (IOException e) {
103             throw new BeanFactoryException("Cannot open resource " + resource,
104                 e);
105         }
106
107         try {
108             Properties props = new Properties();
109             props.load(is);
110
111             String className = props.getProperty(BEAN_FACTORY_CLASS);
112             Class beanFactory = Class.forName(className);
113
114             return (BeanFactory) beanFactory.newInstance();
115         } catch (Exception e) {
116             throw new BeanFactoryException("Cannot read from resource " +
117                 resource, e);
118         } finally {
119             try {
120                 is.close();
121             } catch (IOException e) {
122                 // last resort cannot do much now.
123                 LOG.log(Level.WARNING, "Error closing resource " + resource, e);
124             }
125         }
126     }
127 }