1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions 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   */
49  public class PortletInstanceFactory {
50  
51      public static InvokerPortlet create(
52              Portlet portlet, ServletContext servletContext)
53          throws PortletException {
54  
55          return _instance._create(portlet, servletContext);
56      }
57  
58      public static void destroy(Portlet portlet) {
59          _instance._destroy(portlet);
60      }
61  
62      public void setInternalInvokerPortletPrototype(
63          InvokerPortlet internalInvokerPortletPrototype) {
64  
65          _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
66      }
67  
68      private PortletInstanceFactory() {
69          _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
70      }
71  
72      private InvokerPortlet _create(
73              Portlet portlet, ServletContext servletContext)
74          throws PortletException {
75  
76          boolean instanceable = false;
77  
78          if ((portlet.isInstanceable()) &&
79              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
80  
81              instanceable = true;
82          }
83  
84          Map<String, InvokerPortlet> portletInstances = _pool.get(
85              portlet.getRootPortletId());
86  
87          if (portletInstances == null) {
88              portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
89  
90              _pool.put(portlet.getRootPortletId(), portletInstances);
91          }
92  
93          InvokerPortlet instanceInvokerPortletInstance = null;
94  
95          if (instanceable) {
96              instanceInvokerPortletInstance = portletInstances.get(
97                  portlet.getPortletId());
98          }
99  
100         InvokerPortlet rootInvokerPortletInstance = null;
101 
102         if (instanceInvokerPortletInstance == null) {
103             rootInvokerPortletInstance = portletInstances.get(
104                 portlet.getRootPortletId());
105 
106             if (rootInvokerPortletInstance == null) {
107                 PortletConfig portletConfig =
108                     PortletConfigFactory.create(portlet, servletContext);
109 
110                 PortletApp portletApp = portlet.getPortletApp();
111 
112                 if (portletApp.isWARFile()) {
113                     PortletBag portletBag = PortletBagPool.get(
114                         portlet.getRootPortletId());
115 
116                     rootInvokerPortletInstance = _init(
117                         portlet, portletConfig,
118                         portletBag.getPortletInstance());
119                 }
120                 else {
121                     rootInvokerPortletInstance = _init(portlet, portletConfig);
122                 }
123 
124                 portletInstances.put(
125                     portlet.getRootPortletId(), rootInvokerPortletInstance);
126             }
127         }
128 
129         if (instanceable) {
130             if (instanceInvokerPortletInstance == null) {
131                 javax.portlet.Portlet portletInstance =
132                     rootInvokerPortletInstance.getPortletInstance();
133 
134                 PortletConfig portletConfig =
135                     PortletConfigFactory.create(portlet, servletContext);
136 
137                 PortletContext portletContext =
138                     portletConfig.getPortletContext();
139                 boolean facesPortlet =
140                     rootInvokerPortletInstance.isFacesPortlet();
141                 boolean strutsPortlet =
142                     rootInvokerPortletInstance.isStrutsPortlet();
143                 boolean strutsBridgePortlet =
144                     rootInvokerPortletInstance.isStrutsBridgePortlet();
145 
146                 instanceInvokerPortletInstance =
147                     _internalInvokerPortletPrototype.create(
148                         portlet, portletInstance, portletConfig, portletContext,
149                         facesPortlet, strutsPortlet, strutsBridgePortlet);
150 
151                 portletInstances.put(
152                     portlet.getPortletId(), instanceInvokerPortletInstance);
153             }
154         }
155         else {
156             if (rootInvokerPortletInstance != null) {
157                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
158             }
159         }
160 
161         return instanceInvokerPortletInstance;
162     }
163 
164     private void _destroy(Portlet portlet) {
165         Map<String, InvokerPortlet> portletInstances = _pool.get(
166             portlet.getRootPortletId());
167 
168         if (portletInstances != null) {
169             Iterator<Map.Entry<String, InvokerPortlet>> itr =
170                 portletInstances.entrySet().iterator();
171 
172             while (itr.hasNext()) {
173                 Map.Entry<String, InvokerPortlet> entry = itr.next();
174 
175                 String portletId = entry.getKey();
176                 InvokerPortlet invokerPortletInstance = entry.getValue();
177 
178                 if (PortletConstants.getInstanceId(portletId) == null) {
179                     invokerPortletInstance.destroy();
180 
181                     break;
182                 }
183             }
184         }
185 
186         _pool.remove(portlet.getRootPortletId());
187 
188         PortletApp portletApp = portlet.getPortletApp();
189 
190         if (portletApp.isWARFile()) {
191             PortletBag portletBag = PortletBagPool.get(
192                 portlet.getRootPortletId());
193 
194             if (portletBag != null) {
195                 portletBag.setPortletInstance(null);
196             }
197         }
198 
199         PortletConfigFactory.destroy(portlet);
200         PortletContextFactory.destroy(portlet);
201 
202         PortletLocalServiceUtil.destroyPortlet(portlet);
203     }
204 
205     private InvokerPortlet _init(Portlet portlet, PortletConfig portletConfig)
206         throws PortletException {
207 
208         return _init(portlet, portletConfig, null);
209     }
210 
211     private InvokerPortlet _init(
212             Portlet portlet, PortletConfig portletConfig,
213             javax.portlet.Portlet portletInstance)
214         throws PortletException {
215 
216         InvokerPortlet invokerPortlet = null;
217 
218         try {
219             if (portletInstance == null) {
220                 portletInstance =
221                     (javax.portlet.Portlet)Class.forName(
222                         portlet.getPortletClass()).newInstance();
223             }
224 
225             PortletContext portletContext = portletConfig.getPortletContext();
226 
227             invokerPortlet = _internalInvokerPortletPrototype.create(
228                 portlet, portletInstance, portletContext);
229 
230             invokerPortlet.init(portletConfig);
231         }
232         catch (ClassNotFoundException cnofe) {
233             throw new UnavailableException(cnofe.getMessage());
234         }
235         catch (InstantiationException ie) {
236             throw new UnavailableException(ie.getMessage());
237         }
238         catch (IllegalAccessException iae) {
239             throw new UnavailableException(iae.getMessage());
240         }
241 
242         return invokerPortlet;
243     }
244 
245     private static PortletInstanceFactory _instance =
246         new PortletInstanceFactory();
247 
248     private static InvokerPortlet _internalInvokerPortletPrototype;
249 
250     private Map<String, Map<String, InvokerPortlet>> _pool;
251 
252 }