View Javadoc

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