001: package org.objectweb.celtix.bus.configuration.spring;
002:
003: import java.lang.reflect.Method;
004: import java.net.MalformedURLException;
005: import java.util.ArrayList;
006: import java.util.HashMap;
007: import java.util.List;
008: import java.util.Map;
009: import java.util.logging.Level;
010: import java.util.logging.Logger;
011:
012: import org.objectweb.celtix.common.i18n.Message;
013: import org.objectweb.celtix.common.logging.LogUtils;
014: import org.objectweb.celtix.configuration.Configuration;
015: import org.objectweb.celtix.configuration.ConfigurationException;
016: import org.objectweb.celtix.configuration.ConfigurationProvider;
017: import org.objectweb.celtix.jaxb.JAXBUtils;
018: import org.objectweb.celtix.tools.generators.spring.SpringUtils;
019: import org.springframework.beans.BeansException;
020: import org.springframework.beans.factory.NoSuchBeanDefinitionException;
021: import org.springframework.core.io.UrlResource;
022:
023: public class ConfigurationProviderImpl implements ConfigurationProvider {
024:
025: public static final String CONFIG_FILE_PROPERTY_NAME = "celtix.config.file";
026:
027: private static final Logger LOG = LogUtils
028: .getL7dLogger(ConfigurationProviderImpl.class);
029: private static Map<UrlResource, CeltixXmlBeanFactory> beanFactories;
030:
031: private Object bean;
032: private Configuration configuration;
033:
034: public static void clearBeanFactoriesMap() {
035: beanFactories = null;
036: }
037:
038: public void init(Configuration c) {
039: configuration = c;
040:
041: if (null == beanFactories) {
042: beanFactories = new HashMap<UrlResource, CeltixXmlBeanFactory>();
043: }
044:
045: CeltixXmlBeanFactory beanFactory = null;
046: UrlResource urlRes = getBeanDefinitionsResource();
047: if (null != urlRes) {
048: if (!beanFactories.containsKey(urlRes)) {
049:
050: if (null != urlRes) {
051: try {
052: beanFactory = new CeltixXmlBeanFactory(urlRes);
053: } catch (BeansException ex) {
054: // continue without using configuration from the bean definitions
055: LOG.log(Level.WARNING, new Message(
056: "BEAN_FACTORY_CREATION_MSG", LOG,
057: urlRes.toString()).toString(), ex);
058: }
059: beanFactories.put(urlRes, beanFactory);
060: }
061: } else {
062: beanFactory = beanFactories.get(urlRes);
063: }
064: }
065:
066: if (null != beanFactory) {
067: beanFactory.registerCustomEditors(configuration);
068: findBean(beanFactory);
069: } else {
070: LOG.fine("Not using a bean definitions file.");
071: }
072:
073: }
074:
075: public Object getObject(String name) {
076: // TODO use BeanWrapper instead
077: if (null != bean) {
078: return invokeGetter(bean, name);
079: }
080: return null;
081: }
082:
083: public boolean setObject(String name, Object value) {
084: if (null == bean) {
085: initBean();
086: }
087:
088: if (null != bean) {
089: return invokeSetter(bean, value, name);
090: }
091:
092: return false;
093: }
094:
095: public boolean save() {
096: //TODO, two situations:
097: //1. the bean is created by spring XMLBeanFactory. As the spring XMLBeanFactory
098: //knows BeanDefinition, so it knows how to persist the bean to config file properly.
099: //2. The bean is created by ourself. In this case, we can not use spring XMLBeanFactory
100: //to do the persistence. We may need to find config schemas and using jaxb to persist
101: //bean by ourself
102:
103: return false;
104: }
105:
106: protected Object getBean() {
107: return bean;
108: }
109:
110: protected static Map<UrlResource, CeltixXmlBeanFactory> getBeanFactories() {
111: return beanFactories;
112: }
113:
114: private Object invokeGetter(Object beanObject, String name) {
115:
116: String methodName = JAXBUtils.nameToIdentifier(name,
117: JAXBUtils.IdentifierType.GETTER);
118: try {
119: Method m = beanObject.getClass().getMethod("isSet",
120: new Class[] { String.class });
121: Object o = m.invoke(beanObject, new Object[] { name });
122: if (!((Boolean) o).booleanValue()) {
123: return null;
124: }
125: m = beanObject.getClass().getMethod(methodName,
126: new Class[] {});
127: return m.invoke(beanObject);
128:
129: } catch (Exception ex) {
130: throw new ConfigurationException(new Message(
131: "BEAN_INCOVATION_EXC", LOG), ex);
132: }
133: }
134:
135: private boolean invokeSetter(Object beanObject, Object value,
136: String name) {
137:
138: String methodName = JAXBUtils.nameToIdentifier(name,
139: JAXBUtils.IdentifierType.SETTER);
140: try {
141: Class[] para = new Class[1];
142:
143: if (value.getClass() == Integer.class) {
144: para[0] = Integer.TYPE;
145: } else if (value.getClass() == Float.class) {
146: para[0] = Float.TYPE;
147: } else if (value.getClass() == Double.class) {
148: para[0] = Double.TYPE;
149: } else if (value.getClass() == Boolean.class) {
150: para[0] = Boolean.TYPE;
151: } else if (value.getClass() == Long.class) {
152: para[0] = Long.TYPE;
153: } else if (value.getClass() == Short.class) {
154: para[0] = Short.TYPE;
155: } else if (value.getClass() == Character.class) {
156: para[0] = Character.TYPE;
157: } else if (value.getClass() == Byte.class) {
158: para[0] = Byte.TYPE;
159: } else {
160: para[0] = value.getClass();
161: }
162:
163: Method m = beanObject.getClass()
164: .getMethod(methodName, para);
165: m.invoke(beanObject, value);
166: return true;
167:
168: } catch (Exception ex) {
169: ex.printStackTrace();
170: throw new ConfigurationException(new Message(
171: "BEAN_INCOVATION_EXC", LOG), ex);
172: }
173: }
174:
175: private void initBean() {
176: String beanClassName = SpringUtils
177: .getBeanClassName(configuration.getModel()
178: .getNamespaceURI());
179: Class beanClass = null;
180: try {
181: beanClass = Class.forName(beanClassName);
182: } catch (ClassCastException ex) {
183: LOG.log(Level.SEVERE, "Could not load bean class "
184: + beanClassName, ex);
185: return;
186: } catch (ClassNotFoundException ex) {
187: LOG.log(Level.SEVERE, "Could not load bean class "
188: + beanClassName, ex);
189: return;
190: }
191:
192: try {
193: bean = beanClass.newInstance();
194: } catch (Exception e) {
195: LOG.log(Level.SEVERE, "Could not create bean instance "
196: + beanClassName, e);
197: return;
198: }
199: }
200:
201: /**
202: * get the id of the ancestor configuration and look for a correspondingly named file
203: * with extension .xml in the directory pointed to by system property
204: * celtix.config.dir
205: * @param id
206: * @return
207: */
208:
209: protected UrlResource getBeanDefinitionsResource() {
210:
211: UrlResource urlRes = null;
212: String url = System.getProperty(CONFIG_FILE_PROPERTY_NAME);
213: if (null != url) {
214: try {
215: urlRes = new UrlResource(url);
216: } catch (MalformedURLException ex) {
217: // continue using default configuration
218: LOG.log(Level.WARNING, new Message("MALFORMED_URL_MSG",
219: LOG, url).toString(), ex);
220: }
221:
222: return urlRes;
223: }
224: return null;
225: }
226:
227: private void findBean(CeltixXmlBeanFactory beanFactory) {
228:
229: String beanClassName = SpringUtils
230: .getBeanClassName(configuration.getModel()
231: .getNamespaceURI());
232: Class beanClass = null;
233: try {
234: beanClass = Class.forName(beanClassName);
235: } catch (ClassCastException ex) {
236: LOG.log(Level.SEVERE, "Could not load bean class "
237: + beanClassName, ex);
238: return;
239: } catch (ClassNotFoundException ex) {
240: LOG.log(Level.SEVERE, "Could not load bean class "
241: + beanClassName, ex);
242: return;
243: }
244:
245: String[] candidates = beanFactory
246: .getBeanNamesForType(beanClass);
247: if (null == candidates || candidates.length == 0) {
248: bean = null;
249: if (LOG.isLoggable(Level.FINE)) {
250: LOG.fine("No definitions for beans of type "
251: + beanClass.getName());
252: }
253: return;
254: }
255:
256: List<BeanName> beanNames = new ArrayList<BeanName>();
257: for (String n : candidates) {
258: BeanName bn = new BeanName(n);
259: bn.normalise();
260: beanNames.add(bn);
261: }
262:
263: BeanName ref = new BeanName(configuration);
264: BeanName beanName = ref.findBestMatch(beanNames);
265:
266: if (null != beanName) {
267: try {
268: bean = beanFactory.getBean(beanName.getName(),
269: beanClass);
270: } catch (NoSuchBeanDefinitionException ex) {
271: if (LOG.isLoggable(Level.FINE)) {
272: LOG
273: .fine("Could not find definition for bean with id "
274: + beanName);
275: }
276: } catch (BeansException ex) {
277: throw new ConfigurationException(new Message(
278: "BEAN_CREATION_EXC", LOG, beanName), ex);
279: }
280: }
281:
282: if (null == bean && LOG.isLoggable(Level.INFO)) {
283: LOG
284: .info("Could not find matching bean definition for component "
285: + ref.getName());
286: }
287: }
288: }
|