1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet;
24  
25  import com.liferay.portal.kernel.portlet.PortletBag;
26  import com.liferay.portal.kernel.portlet.PortletBagPool;
27  import com.liferay.portal.model.Portlet;
28  import com.liferay.portal.model.PortletApp;
29  import com.liferay.portal.model.PortletConstants;
30  import com.liferay.portal.service.PortletLocalServiceUtil;
31  
32  import java.util.Iterator;
33  import java.util.Map;
34  import java.util.concurrent.ConcurrentHashMap;
35  
36  import javax.portlet.PortletConfig;
37  import javax.portlet.PortletContext;
38  import javax.portlet.PortletException;
39  import javax.portlet.UnavailableException;
40  
41  import javax.servlet.ServletContext;
42  
43  /**
44   * <a href="PortletInstanceFactory.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Brian Wing Shun Chan
47   */
48  public class PortletInstanceFactory {
49  
50      public static InvokerPortlet create(
51              Portlet portlet, ServletContext servletContext)
52          throws PortletException {
53  
54          return _instance._create(portlet, servletContext);
55      }
56  
57      public static void destroy(Portlet portlet) {
58          _instance._destroy(portlet);
59      }
60  
61      public void setInternalInvokerPortletPrototype(
62          InvokerPortlet internalInvokerPortletPrototype) {
63  
64          _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
65      }
66  
67      private PortletInstanceFactory() {
68          _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
69      }
70  
71      private InvokerPortlet _create(
72              Portlet portlet, ServletContext servletContext)
73          throws PortletException {
74  
75          boolean instanceable = false;
76  
77          if ((portlet.isInstanceable()) &&
78              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
79  
80              instanceable = true;
81          }
82  
83          Map<String, InvokerPortlet> portletInstances = _pool.get(
84              portlet.getRootPortletId());
85  
86          if (portletInstances == null) {
87              portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
88  
89              _pool.put(portlet.getRootPortletId(), portletInstances);
90          }
91  
92          InvokerPortlet instanceInvokerPortletInstance = null;
93  
94          if (instanceable) {
95              instanceInvokerPortletInstance = portletInstances.get(
96                  portlet.getPortletId());
97          }
98  
99          InvokerPortlet rootInvokerPortletInstance = null;
100 
101         if (instanceInvokerPortletInstance == null) {
102             rootInvokerPortletInstance = portletInstances.get(
103                 portlet.getRootPortletId());
104 
105             if (rootInvokerPortletInstance == null) {
106                 PortletConfig portletConfig =
107                     PortletConfigFactory.create(portlet, servletContext);
108 
109                 PortletApp portletApp = portlet.getPortletApp();
110 
111                 if (portletApp.isWARFile()) {
112                     PortletBag portletBag = PortletBagPool.get(
113                         portlet.getRootPortletId());
114 
115                     rootInvokerPortletInstance = _init(
116                         portlet, portletConfig,
117                         portletBag.getPortletInstance());
118                 }
119                 else {
120                     rootInvokerPortletInstance = _init(portlet, portletConfig);
121                 }
122 
123                 portletInstances.put(
124                     portlet.getRootPortletId(), rootInvokerPortletInstance);
125             }
126         }
127 
128         if (instanceable) {
129             if (instanceInvokerPortletInstance == null) {
130                 javax.portlet.Portlet portletInstance =
131                     rootInvokerPortletInstance.getPortletInstance();
132 
133                 PortletConfig portletConfig =
134                     PortletConfigFactory.create(portlet, servletContext);
135 
136                 PortletContext portletContext =
137                     portletConfig.getPortletContext();
138                 boolean facesPortlet =
139                     rootInvokerPortletInstance.isFacesPortlet();
140                 boolean strutsPortlet =
141                     rootInvokerPortletInstance.isStrutsPortlet();
142                 boolean strutsBridgePortlet =
143                     rootInvokerPortletInstance.isStrutsBridgePortlet();
144 
145                 instanceInvokerPortletInstance =
146                     _internalInvokerPortletPrototype.create(
147                         portlet, portletInstance, portletConfig, portletContext,
148                         facesPortlet, strutsPortlet, strutsBridgePortlet);
149 
150                 portletInstances.put(
151                     portlet.getPortletId(), instanceInvokerPortletInstance);
152             }
153         }
154         else {
155             if (rootInvokerPortletInstance != null) {
156                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
157             }
158         }
159 
160         return instanceInvokerPortletInstance;
161     }
162 
163     private void _destroy(Portlet portlet) {
164         Map<String, InvokerPortlet> portletInstances = _pool.get(
165             portlet.getRootPortletId());
166 
167         if (portletInstances != null) {
168             Iterator<Map.Entry<String, InvokerPortlet>> itr =
169                 portletInstances.entrySet().iterator();
170 
171             while (itr.hasNext()) {
172                 Map.Entry<String, InvokerPortlet> entry = itr.next();
173 
174                 String portletId = entry.getKey();
175                 InvokerPortlet invokerPortletInstance = entry.getValue();
176 
177                 if (PortletConstants.getInstanceId(portletId) == null) {
178                     invokerPortletInstance.destroy();
179 
180                     break;
181                 }
182             }
183         }
184 
185         _pool.remove(portlet.getRootPortletId());
186 
187         PortletApp portletApp = portlet.getPortletApp();
188 
189         if (portletApp.isWARFile()) {
190             PortletBag portletBag = PortletBagPool.get(
191                 portlet.getRootPortletId());
192 
193             if (portletBag != null) {
194                 portletBag.setPortletInstance(null);
195             }
196         }
197 
198         PortletConfigFactory.destroy(portlet);
199         PortletContextFactory.destroy(portlet);
200 
201         PortletLocalServiceUtil.destroyPortlet(portlet);
202     }
203 
204     private InvokerPortlet _init(Portlet portlet, PortletConfig portletConfig)
205         throws PortletException {
206 
207         return _init(portlet, portletConfig, null);
208     }
209 
210     private InvokerPortlet _init(
211             Portlet portlet, PortletConfig portletConfig,
212             javax.portlet.Portlet portletInstance)
213         throws PortletException {
214 
215         InvokerPortlet invokerPortlet = null;
216 
217         try {
218             if (portletInstance == null) {
219                 portletInstance =
220                     (javax.portlet.Portlet)Class.forName(
221                         portlet.getPortletClass()).newInstance();
222             }
223 
224             PortletContext portletContext = portletConfig.getPortletContext();
225 
226             invokerPortlet = _internalInvokerPortletPrototype.create(
227                 portlet, portletInstance, portletContext);
228 
229             invokerPortlet.init(portletConfig);
230         }
231         catch (ClassNotFoundException cnofe) {
232             throw new UnavailableException(cnofe.getMessage());
233         }
234         catch (InstantiationException ie) {
235             throw new UnavailableException(ie.getMessage());
236         }
237         catch (IllegalAccessException iae) {
238             throw new UnavailableException(iae.getMessage());
239         }
240 
241         return invokerPortlet;
242     }
243 
244     private static PortletInstanceFactory _instance =
245         new PortletInstanceFactory();
246 
247     private static InvokerPortlet _internalInvokerPortletPrototype;
248 
249     private Map<String, Map<String, InvokerPortlet>> _pool;
250 
251 }