View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.object;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.construct.FlowConstruct;
11  import org.mule.api.construct.FlowConstructAware;
12  import org.mule.api.lifecycle.InitialisationCallback;
13  import org.mule.api.lifecycle.InitialisationException;
14  import org.mule.api.object.ObjectFactory;
15  import org.mule.api.service.Service;
16  import org.mule.api.service.ServiceAware;
17  import org.mule.config.i18n.MessageFactory;
18  import org.mule.util.BeanUtils;
19  import org.mule.util.ClassUtils;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /**
29   * Creates object instances based on the class and sets any properties.  This factory is also responsible for applying
30   * any object processors on the object before the lifecycle callbacks are called.
31   */
32  public abstract class AbstractObjectFactory implements ObjectFactory, FlowConstructAware
33  {
34  
35      public static final String ATTRIBUTE_OBJECT_CLASS_NAME = "objectClassName";
36      public static final String ATTRIBUTE_OBJECT_CLASS = "objectClass";
37  
38      protected String objectClassName;
39      protected Class<?> objectClass;
40      protected Map properties = null;
41      protected List<InitialisationCallback> initialisationCallbacks = new ArrayList<InitialisationCallback>();
42      protected FlowConstruct flowConstruct;
43      protected boolean disposed = false;
44  
45      protected transient Log logger = LogFactory.getLog(getClass());
46  
47      /**
48       * For Spring only
49       */
50      public AbstractObjectFactory()
51      {
52          // nop
53      }
54  
55      public AbstractObjectFactory(String objectClassName)
56      {
57          this(objectClassName, null);
58      }
59  
60      public AbstractObjectFactory(String objectClassName, Map properties)
61      {
62          super();
63          this.objectClassName = objectClassName;
64          this.properties = properties;
65          setupObjectClassFromObjectClassName();
66      }
67  
68      public AbstractObjectFactory(Class<?> objectClass)
69      {
70          this(objectClass, null);
71      }
72  
73      public AbstractObjectFactory(Class<?> objectClass, Map properties)
74      {
75          super();
76          this.objectClassName = objectClass.getName();
77          this.objectClass = objectClass;
78          this.properties = properties;
79      }
80  
81      protected Class<?> setupObjectClassFromObjectClassName()
82      {
83          try
84          {
85              Class<?> klass = ClassUtils.getClass(objectClassName);
86              objectClass = klass;
87              return klass;
88          }
89          catch (ClassNotFoundException e)
90          {
91              throw new IllegalArgumentException(e);
92          }
93      }
94  
95      public void setFlowConstruct(FlowConstruct flowConstruct)
96      {
97          this.flowConstruct = flowConstruct;
98      }
99  
100     public void initialise() throws InitialisationException
101     {
102         if ((objectClassName == null) || (objectClass == null))
103         {
104             throw new InitialisationException(
105                     MessageFactory.createStaticMessage("Object factory has not been initialized."), this);
106         }
107         disposed = false;
108     }
109 
110     public void dispose()
111     {
112         disposed = true;
113         //Don't reset the component config state i.e. objectClass since service objects can be recycled
114     }
115 
116     /**
117      * Creates an initialized object instance based on the class and sets any properties.
118      * This method handles all injection of properties for the resulting object
119      *
120      * @param muleContext the current {@link org.mule.api.MuleContext} instance. This can be used for performing registry lookups
121      *                    applying processors to newly created objects or even firing custom notifications
122      * @throws Exception Can throw any type of exception while creating a new object
123      */
124     public Object getInstance(MuleContext muleContext) throws Exception
125     {
126         if (objectClass == null || disposed)
127         {
128             throw new InitialisationException(
129                     MessageFactory.createStaticMessage("Object factory has not been initialized."), this);
130         }
131 
132         Object object = ClassUtils.instanciateClass(objectClass);
133 
134         if (properties != null)
135         {
136             BeanUtils.populateWithoutFail(object, properties, true);
137         }
138 
139         if (object instanceof FlowConstructAware)
140         {
141             ((FlowConstructAware) object).setFlowConstruct(flowConstruct);
142         }
143 
144         if (object instanceof ServiceAware && flowConstruct instanceof Service)
145         {
146             ((ServiceAware) object).setService((Service) flowConstruct);
147         }
148 
149         if (isAutoWireObject())
150         {
151             muleContext.getRegistry().applyProcessors(object);
152         }
153         fireInitialisationCallbacks(object);
154 
155         return object;
156     }
157 
158     protected void fireInitialisationCallbacks(Object component) throws InitialisationException
159     {
160         for (InitialisationCallback callback : initialisationCallbacks)
161         {
162             callback.initialise(component);
163         }
164     }
165 
166     public Class<?> getObjectClass()
167     {
168         return objectClass;
169     }
170 
171     public void setObjectClass(Class<?> objectClass)
172     {
173         this.objectClass = objectClass;
174         this.objectClassName = objectClass.getName();
175     }
176 
177     protected String getObjectClassName()
178     {
179         return objectClassName;
180     }
181 
182     public void setObjectClassName(String objectClassName)
183     {
184         this.objectClassName = objectClassName;
185         setupObjectClassFromObjectClassName();
186     }
187 
188     protected Map getProperties()
189     {
190         return properties;
191     }
192 
193     public void setProperties(Map properties)
194     {
195         this.properties = properties;
196     }
197 
198     public void addObjectInitialisationCallback(InitialisationCallback callback)
199     {
200         initialisationCallbacks.add(callback);
201     }
202 
203     public boolean isSingleton()
204     {
205         return false;
206     }
207 
208     public boolean isExternallyManagedLifecycle()
209     {
210         return false;
211     }
212 
213     public boolean isAutoWireObject()
214     {
215         return true;
216     }
217 }