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