View Javadoc

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