View Javadoc

1   /*
2    * $Id: AbstractJavaComponent.java 19191 2010-08-25 21:05:23Z tcarlson $
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.component;
12  
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleException;
15  import org.mule.api.component.InterfaceBinding;
16  import org.mule.api.component.JavaComponent;
17  import org.mule.api.component.LifecycleAdapter;
18  import org.mule.api.component.LifecycleAdapterFactory;
19  import org.mule.api.construct.FlowConstruct;
20  import org.mule.api.construct.FlowConstructAware;
21  import org.mule.api.lifecycle.InitialisationException;
22  import org.mule.api.model.EntryPointResolver;
23  import org.mule.api.model.EntryPointResolverSet;
24  import org.mule.api.object.ObjectFactory;
25  import org.mule.api.service.Service;
26  import org.mule.config.i18n.CoreMessages;
27  import org.mule.model.resolvers.DefaultEntryPointResolverSet;
28  import org.mule.model.resolvers.LegacyEntryPointResolverSet;
29  
30  import java.util.ArrayList;
31  import java.util.Collection;
32  import java.util.List;
33  
34  /**
35   * Abstract implementation of JavaComponent adds JavaComponent specific's:
36   * {@link EntryPointResolverSet}, {@link org.mule.api.routing.BindingCollection} and
37   * {@link ObjectFactory}. Provides default implementations of doOnCall and doOnEvent
38   * and defines abstract template methods provided for obtaining and returning the
39   * component object instance.
40   */
41  public abstract class AbstractJavaComponent extends AbstractComponent implements JavaComponent
42  {
43  
44      protected EntryPointResolverSet entryPointResolverSet;
45  
46      protected List<InterfaceBinding> bindings = new ArrayList<InterfaceBinding>();
47  
48      protected ObjectFactory objectFactory;
49  
50      protected LifecycleAdapterFactory lifecycleAdapterFactory;
51  
52      /**
53       * For Spring only
54       */
55      public AbstractJavaComponent()
56      {
57          super();
58      }
59  
60      public AbstractJavaComponent(ObjectFactory objectFactory)
61      {
62          this(objectFactory, null, null);
63      }
64  
65      public AbstractJavaComponent(ObjectFactory objectFactory,
66                                   EntryPointResolverSet entryPointResolverSet,
67                                   List<InterfaceBinding> bindings)
68      {
69          super();
70          this.objectFactory = objectFactory;
71          this.entryPointResolverSet = entryPointResolverSet;
72          if (bindings != null)
73          {
74              this.bindings = bindings;
75          }
76      }
77  
78      @Override
79      protected Object doInvoke(MuleEvent event) throws Exception
80      {
81          return invokeComponentInstance(event);
82      }
83  
84      protected Object invokeComponentInstance(MuleEvent event) throws Exception
85      {
86          LifecycleAdapter componentLifecycleAdapter = null;
87          try
88          {
89              componentLifecycleAdapter = borrowComponentLifecycleAdaptor();
90              return componentLifecycleAdapter.invoke(event);
91          }
92          finally
93          {
94              if (componentLifecycleAdapter != null)
95              {
96                  returnComponentLifecycleAdaptor(componentLifecycleAdapter);
97              }
98          }
99      }
100 
101     public Class<?> getObjectType()
102     {
103         return objectFactory.getObjectClass();
104     }
105 
106     /**
107      * Creates and initialises a new LifecycleAdaptor instance wrapped the component
108      * object instance obtained from the configured object factory.
109      * 
110      * @throws MuleException
111      * @throws Exception
112      */
113     protected LifecycleAdapter createLifecycleAdaptor() throws Exception
114     {
115         //Todo this could be moved to the LCAFactory potentially
116         Object object = objectFactory.getInstance(muleContext);
117 
118         LifecycleAdapter lifecycleAdapter;
119         if (lifecycleAdapterFactory != null)
120         {
121             // Custom lifecycleAdapterFactory set on component
122             lifecycleAdapter = 
123                 lifecycleAdapterFactory.create(object, this, flowConstruct, entryPointResolverSet, muleContext);
124         }
125         else if (objectFactory.isExternallyManagedLifecycle())
126         {
127             // If no lifecycleAdapterFactory is configured explicitly and object factory returns 
128             // externally managed instance then use NullLifecycleAdapter so that lifecycle 
129             // is not propagated
130             lifecycleAdapter = 
131                 new NullLifecycleAdapter(object, this, flowConstruct, entryPointResolverSet, muleContext);
132         }
133         else if (flowConstruct instanceof Service)
134         {
135             // Inherit lifecycleAdapterFactory from model
136             lifecycleAdapter = ((Service) flowConstruct).getModel().getLifecycleAdapterFactory().create(
137                 object, this, flowConstruct, entryPointResolverSet, muleContext);
138         }
139         else
140         {
141             lifecycleAdapter = new DefaultComponentLifecycleAdapterFactory().create(object, this,
142                 flowConstruct, entryPointResolverSet, muleContext);
143         }
144         lifecycleAdapter.initialise();
145         return lifecycleAdapter;
146     }
147 
148     protected abstract LifecycleAdapter borrowComponentLifecycleAdaptor() throws Exception;
149 
150     protected abstract void returnComponentLifecycleAdaptor(LifecycleAdapter lifecycleAdapter) throws Exception;
151 
152     @Override
153     protected void doInitialise() throws InitialisationException
154     {
155         if (objectFactory == null)
156         {
157             throw new InitialisationException(CoreMessages.objectIsNull("object factory"), this);
158         }
159         objectFactory.initialise();
160     }
161 
162     @Override
163     protected void doStart() throws MuleException
164     {
165         // We need to resolve entry point resolvers here rather than in initialise()
166         // because when configuring with spring, although the service has been
167         // injected and is available the injected service construction has not been
168         // completed and model is still in null.
169         if (entryPointResolverSet == null)
170         {
171             if (flowConstruct instanceof Service)
172             {
173                 entryPointResolverSet = ((Service) flowConstruct).getModel().getEntryPointResolverSet();
174             }
175             else
176             {
177                 entryPointResolverSet = new LegacyEntryPointResolverSet();
178             }
179         }
180     }
181 
182     @Override
183     protected void doDispose()
184     {
185         if (objectFactory!=null)
186         {
187             objectFactory.dispose();
188         }
189     }
190 
191     public EntryPointResolverSet getEntryPointResolverSet()
192     {
193         return entryPointResolverSet;
194     }
195 
196     public List<InterfaceBinding> getInterfaceBindings()
197     {
198         return bindings;
199     }
200 
201     public void setEntryPointResolverSet(EntryPointResolverSet entryPointResolverSet)
202     {
203         this.entryPointResolverSet = entryPointResolverSet;
204     }
205 
206     public void setInterfaceBindings(List<InterfaceBinding> bindings)
207     {
208         this.bindings = bindings;
209     }
210 
211     /**
212      * Allow for incremental addition of resolvers by for example the spring-config
213      * module
214      * 
215      * @param entryPointResolvers Resolvers to add
216      */
217     public void setEntryPointResolvers(Collection<EntryPointResolver> entryPointResolvers)
218     {
219         if (null == entryPointResolverSet)
220         {
221             entryPointResolverSet = new DefaultEntryPointResolverSet();
222         }
223         
224         for (EntryPointResolver resolver : entryPointResolvers)
225         {
226             entryPointResolverSet.addEntryPointResolver(resolver);
227         }
228     }
229 
230     public ObjectFactory getObjectFactory()
231     {
232         return objectFactory;
233     }
234 
235     public void setObjectFactory(ObjectFactory objectFactory)
236     {
237         this.objectFactory = objectFactory;
238         injectService();
239     }
240 
241     public LifecycleAdapterFactory getLifecycleAdapterFactory()
242     {
243         return lifecycleAdapterFactory;
244     }
245 
246     public void setLifecycleAdapterFactory(LifecycleAdapterFactory lifecycleAdapterFactory)
247     {
248         this.lifecycleAdapterFactory = lifecycleAdapterFactory;
249     }
250 
251     @Override
252     public void setFlowConstruct(FlowConstruct flowConstruct)
253     {
254         super.setFlowConstruct(flowConstruct);
255         injectService();
256     }
257 
258     protected void injectService()
259     {
260         if (objectFactory != null && objectFactory instanceof FlowConstructAware && flowConstruct != null)
261         {
262             // The registry cannot inject the Service for this object since there is
263             // no way to tie the two together, so
264             // we set the service on the object factory, that way the factory is
265             // responsible for injecting all properties
266             // on the result object
267             ((FlowConstructAware) objectFactory).setFlowConstruct(flowConstruct);
268         }
269     }
270 }