001: package org.concern.controller.spring;
002:
003: import org.concern.controller.*;
004: import org.hibernate.SessionFactory;
005: import org.springframework.beans.factory.*;
006: import org.springframework.beans.BeanUtils;
007: import org.springframework.beans.BeansException;
008: import org.springframework.core.io.Resource;
009: import org.springframework.web.context.support.ServletContextResource;
010: import org.apache.commons.logging.LogFactory;
011:
012: import javax.transaction.TransactionManager;
013: import java.io.*;
014: import java.net.URL;
015: import java.util.*;
016: import java.beans.PropertyDescriptor;
017: import java.lang.reflect.InvocationTargetException;
018:
019: public class ControllerFactoryBean implements FactoryBean,
020: InitializingBean, DisposableBean, BeanFactoryAware {
021: private static org.apache.commons.logging.Log LOG = LogFactory
022: .getLog(ControllerFactoryBean.class);
023:
024: protected Controller controller;
025: protected Resource processLocation;
026: protected TransactionManager transactionManager;
027: protected SessionFactory sessionFactory;
028: protected Map resources;
029: protected Map parameters;
030: private long timerInterval = 10000;
031: private boolean autowireByType;
032: private String processDescription;
033: private BeanFactory beanFactory;
034:
035: /**
036: * @param processLocation
037: */
038: public void setProcessLocation(Resource processLocation) {
039: this .processLocation = processLocation;
040: }
041:
042: /**
043: * Set reference to the JTA TransactionManager (optional). Alternatively setup a spring
044: * HibernateTransactionManager with the session factory.
045: * @param transactionManager the JTA TransactionManager
046: */
047: public void setTransactionManager(
048: TransactionManager transactionManager) {
049: if (transactionManager instanceof NoTransactionManager)
050: return;
051: this .transactionManager = transactionManager;
052: }
053:
054: public void setSessionFactory(SessionFactory sessionFactory) {
055: this .sessionFactory = sessionFactory;
056: }
057:
058: public void setResources(Map resources) {
059: this .resources = resources;
060: }
061:
062: public void setBeanFactory(BeanFactory beanFactory) {
063: this .beanFactory = beanFactory;
064: }
065:
066: public void setTimerInterval(long timerInterval) {
067: this .timerInterval = timerInterval;
068: }
069:
070: public void setAutowireByType(boolean autowireByType) {
071: this .autowireByType = autowireByType;
072: }
073:
074: public String getProcessDescription() {
075: return processDescription;
076: }
077:
078: public void setProcessDescription(String processDescription) {
079: this .processDescription = processDescription;
080: }
081:
082: private InputStream getProcessDescriptionAsStream() {
083: if (processDescription != null)
084: try {
085: return new ByteArrayInputStream(processDescription
086: .getBytes("UTF-8"));
087: } catch (UnsupportedEncodingException e) {
088: throw new RuntimeException(e);
089: }
090: else {
091: try {
092: URL url = processLocation.getURL();
093:
094: // workaround for tomcat bug
095: if (processLocation instanceof ServletContextResource) {
096: ServletContextResource servletContextResource = (ServletContextResource) processLocation;
097: try {
098: LOG.info("Workaround for tomcat bug.");
099: url = servletContextResource.getFile().toURL();
100: } catch (IOException e) {
101: LOG.error("Workaround failed", e);
102: }
103: }
104: return url.openStream();
105: } catch (IOException e) {
106: throw new RuntimeException(e);
107: }
108: }
109: }
110:
111: public Object getObject() throws Exception {
112: return controller;
113: }
114:
115: public Class getObjectType() {
116: return (controller != null) ? controller.getClass()
117: : org.concern.Controller.class;
118: }
119:
120: public boolean isSingleton() {
121: return true;
122: }
123:
124: public void afterPropertiesSet() throws Exception {
125: Configuration configuration = new Configuration();
126: configuration.setProcess(Configuration
127: .loadProcess(getProcessDescriptionAsStream()));
128: configuration.setTransactionManager(transactionManager);
129: configuration.setSessionFactory(sessionFactory);
130: configuration
131: .setResourceLocator(resources != null ? (ResourceLocator) new LocalResourceLocator(
132: resources)
133: : (ResourceLocator) new BeanFactoryResourceLocator(
134: beanFactory));
135: configuration
136: .setParameterResolver(parameters != null ? (ParameterResolver) new LocalParameterResolver(
137: parameters)
138: : (ParameterResolver) new NoParameterResolver());
139: configuration.setTimerInterval(timerInterval);
140:
141: controller = configuration.buildController();
142: if (autowireByType)
143: autowireByType();
144: controller.start();
145:
146: System.setProperty("concern.controller.lookup",
147: LocalControllerLookup.class.getName());
148: ((LocalControllerLookup) LocalControllerLookup.getInstance())
149: .add(controller);
150: }
151:
152: private void autowireByType() throws IllegalAccessException,
153: InvocationTargetException {
154: if (beanFactory instanceof ListableBeanFactory) {
155: ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
156: List elements = new LinkedList();
157: elements.addAll(controller.getConditions());
158: elements.addAll(controller.getEvents());
159: elements.addAll(controller.getActivities());
160: elements.addAll(controller.getListeners());
161: elements.addAll(controller.getActors());
162: elements.add(controller.getLoader());
163: for (Iterator iterator = elements.iterator(); iterator
164: .hasNext();) {
165: Object element = iterator.next();
166: PropertyDescriptor[] descriptors = BeanUtils
167: .getPropertyDescriptors(element.getClass());
168: for (int i = 0; i < descriptors.length; i++) {
169: PropertyDescriptor descriptor = descriptors[i];
170: if (descriptor.getWriteMethod() == null)
171: continue;
172: if (!descriptor.getWriteMethod()
173: .getDeclaringClass().equals(
174: element.getClass()))
175: continue;
176: try {
177: Object value = BeanFactoryUtils
178: .beanOfTypeIncludingAncestors(
179: listableBeanFactory, descriptor
180: .getPropertyType());
181: descriptor.getWriteMethod().invoke(element,
182: new Object[] { value });
183: } catch (BeansException e) {
184: }
185: }
186: }
187: }
188: }
189:
190: public void destroy() throws Exception {
191: ((LocalControllerLookup) LocalControllerLookup.getInstance())
192: .remove(controller.getProcessName());
193: controller.stop();
194: }
195: }
|