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.MuleContext;
10  import org.mule.api.MuleException;
11  import org.mule.api.component.Component;
12  import org.mule.api.component.InterfaceBinding;
13  import org.mule.api.component.LifecycleAdapter;
14  import org.mule.api.lifecycle.InitialisationCallback;
15  import org.mule.api.lifecycle.InitialisationException;
16  import org.mule.api.model.EntryPointResolverSet;
17  import org.mule.api.object.ObjectFactory;
18  import org.mule.config.PoolingProfile;
19  import org.mule.util.pool.DefaultLifecycleEnabledObjectPool;
20  import org.mule.util.pool.LifecyleEnabledObjectPool;
21  import org.mule.util.pool.ObjectPool;
22  
23  import java.util.List;
24  
25  /**
26   * <code>PooledJavaComponent</code> implements pooling.
27   */
28  public class PooledJavaComponent extends AbstractJavaComponent
29  {
30  
31      protected PoolingProfile poolingProfile;
32      protected LifecyleEnabledObjectPool lifecycleAdapterPool;
33  
34      public PooledJavaComponent()
35      {
36          super();
37      }
38  
39      public PooledJavaComponent(ObjectFactory objectFactory)
40      {
41          this(objectFactory, null);
42      }
43  
44      public PooledJavaComponent(ObjectFactory objectFactory, PoolingProfile poolingProfile)
45      {
46          super(objectFactory);
47          this.poolingProfile = poolingProfile;
48      }
49  
50      public PooledJavaComponent(ObjectFactory objectFactory,
51                                 PoolingProfile poolingProfile,
52                                 EntryPointResolverSet entryPointResolverSet,
53                                 List<InterfaceBinding> bindings)
54      {
55          super(objectFactory, entryPointResolverSet, bindings);
56          this.poolingProfile = poolingProfile;
57      }
58  
59      @Override
60      protected LifecycleAdapter borrowComponentLifecycleAdaptor() throws Exception
61      {
62          return (LifecycleAdapter) lifecycleAdapterPool.borrowObject();
63      }
64  
65      @Override
66      protected void returnComponentLifecycleAdaptor(LifecycleAdapter lifecycleAdapter)
67      {
68          lifecycleAdapterPool.returnObject(lifecycleAdapter);
69      }
70  
71      @Override
72      protected void doStart() throws MuleException
73      {
74          super.doStart();
75          // Wrap pool's objectFactory with a LifeCycleAdaptor factory so we pool
76          // LifeCycleAdaptor's and not just pojo instances.
77          lifecycleAdapterPool = new DefaultLifecycleEnabledObjectPool(new LifeCycleAdapterFactory(), poolingProfile, muleContext);
78          lifecycleAdapterPool.initialise();
79          lifecycleAdapterPool.start();
80      }
81  
82      @Override
83      protected void doStop() throws MuleException
84      {
85          super.doStop();
86          if (lifecycleAdapterPool != null)
87          {
88              lifecycleAdapterPool.stop();
89              lifecycleAdapterPool.close();
90              lifecycleAdapterPool = null;
91          }
92      }
93  
94      public void setPoolingProfile(PoolingProfile poolingProfile)
95      {
96          // TODO What happens if this is set while component is started? Should we i)
97          // do nothing ii) issue warning iii) stop/start the pool
98          // (!!) iv) throw exception?
99          this.poolingProfile = poolingProfile;
100     }
101 
102     public PoolingProfile getPoolingProfile()
103     {
104         return poolingProfile;
105     }
106 
107     /**
108      * <code>LifeCycleAdaptorFactory</code> wraps the Component' s
109      * {@link ObjectFactory}. The LifeCycleAdaptorFactory <code>getInstance()</code> method
110      * creates a new {@link LifecycleAdapter} wrapping the object instance obtained
111      * for the component instance {@link ObjectFactory} set on the {@link Component}.
112      * <br/>
113      * This allows us to keep {@link LifecycleAdapter} creation in the Component and
114      * out of the {@link DefaultLifecycleEnabledObjectPool} and to use the generic
115      * {@link ObjectPool} interface.
116      */
117     protected class LifeCycleAdapterFactory implements ObjectFactory
118     {
119         public Object getInstance(MuleContext context) throws Exception
120         {
121             return createLifecycleAdaptor();
122         }
123 
124         public Class<?> getObjectClass()
125         {
126             return LifecycleAdapter.class;
127         }
128 
129         public void initialise() throws InitialisationException
130         {
131             objectFactory.initialise();
132         }
133 
134         public void dispose()
135         {
136             objectFactory.dispose();
137         }
138 
139         public void addObjectInitialisationCallback(InitialisationCallback callback)
140         {
141             objectFactory.addObjectInitialisationCallback(callback);
142         }
143 
144         public boolean isSingleton()
145         {
146             return false;
147         }
148 
149         public boolean isExternallyManagedLifecycle()
150         {
151             return objectFactory.isExternallyManagedLifecycle();
152         }
153 
154         public boolean isAutoWireObject()
155         {
156             return objectFactory.isAutoWireObject();
157         }
158     }
159 }