1   /**
2    * Copyright (c) 2000-2008 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.model.Portlet;
26  import com.liferay.portal.model.PortletApp;
27  import com.liferay.portal.model.PortletConstants;
28  import com.liferay.portal.portletcontainer.WindowInvoker;
29  import com.liferay.portal.service.PortletLocalServiceUtil;
30  import com.liferay.portal.util.PropsValues;
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      private PortletInstanceFactory() {
63          _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
64      }
65  
66      private InvokerPortlet _create(
67              Portlet portlet, ServletContext servletContext)
68          throws PortletException {
69  
70          boolean instanceable = false;
71  
72          if ((portlet.isInstanceable()) &&
73              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
74  
75              instanceable = true;
76          }
77  
78          Map<String, InvokerPortlet> portletInstances = _pool.get(
79              portlet.getRootPortletId());
80  
81          if (portletInstances == null) {
82              portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
83  
84              _pool.put(portlet.getRootPortletId(), portletInstances);
85          }
86  
87          InvokerPortlet instanceInvokerPortletInstance = null;
88  
89          if (instanceable) {
90              instanceInvokerPortletInstance = portletInstances.get(
91                  portlet.getPortletId());
92          }
93  
94          InvokerPortlet rootInvokerPortletInstance = null;
95  
96          if (instanceInvokerPortletInstance == null) {
97              rootInvokerPortletInstance = portletInstances.get(
98                  portlet.getRootPortletId());
99  
100             if (rootInvokerPortletInstance == null) {
101                 PortletConfig portletConfig =
102                     PortletConfigFactory.create(portlet, servletContext);
103 
104                 PortletApp portletApp = portlet.getPortletApp();
105 
106                 if (portletApp.isWARFile()) {
107                     PortletBag portletBag = PortletBagPool.get(
108                         portlet.getRootPortletId());
109 
110                     rootInvokerPortletInstance = _init(
111                         portlet, portletConfig,
112                         portletBag.getPortletInstance());
113                 }
114                 else {
115                     rootInvokerPortletInstance = _init(portlet, portletConfig);
116                 }
117 
118                 portletInstances.put(
119                     portlet.getRootPortletId(), rootInvokerPortletInstance);
120             }
121         }
122 
123         if (instanceable) {
124             if (instanceInvokerPortletInstance == null) {
125                 javax.portlet.Portlet portletInstance =
126                     rootInvokerPortletInstance.getPortletInstance();
127 
128                 PortletConfig portletConfig =
129                     PortletConfigFactory.create(portlet, servletContext);
130 
131                 PortletContext portletContext =
132                     portletConfig.getPortletContext();
133                 boolean facesPortlet =
134                     rootInvokerPortletInstance.isFacesPortlet();
135                 boolean strutsPortlet =
136                     rootInvokerPortletInstance.isStrutsPortlet();
137                 boolean strutsBridgePortlet =
138                     rootInvokerPortletInstance.isStrutsBridgePortlet();
139 
140                 if (PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
141                     instanceInvokerPortletInstance = new WindowInvoker(
142                         portlet, portletInstance, portletConfig, portletContext,
143                         facesPortlet, strutsPortlet, strutsBridgePortlet);
144                 }
145                 else {
146                     instanceInvokerPortletInstance = new InvokerPortlet(
147                         portlet, portletInstance, portletConfig, portletContext,
148                         facesPortlet, strutsPortlet, strutsBridgePortlet);
149                 }
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             return;
170         }
171 
172         Iterator<Map.Entry<String, InvokerPortlet>> itr =
173             portletInstances.entrySet().iterator();
174 
175         while (itr.hasNext()) {
176             Map.Entry<String, InvokerPortlet> entry = itr.next();
177 
178             String portletId = entry.getKey();
179             InvokerPortlet invokerPortletInstance = entry.getValue();
180 
181             if (PortletConstants.getInstanceId(portletId) == null) {
182                 invokerPortletInstance.destroy();
183 
184                 break;
185             }
186         }
187 
188         _pool.remove(portlet.getRootPortletId());
189 
190         PortletApp portletApp = portlet.getPortletApp();
191 
192         if (portletApp.isWARFile()) {
193             PortletBag portletBag = PortletBagPool.get(
194                 portlet.getRootPortletId());
195 
196             portletBag.removePortletInstance();
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 = (javax.portlet.Portlet)
221                     Class.forName(portlet.getPortletClass()).newInstance();
222             }
223 
224             PortletContext portletContext = portletConfig.getPortletContext();
225 
226             if (PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
227                 invokerPortlet = new WindowInvoker(
228                     portlet, portletInstance, portletContext);
229             }
230             else {
231                 invokerPortlet = new InvokerPortlet(
232                     portlet, portletInstance, portletContext);
233             }
234 
235             invokerPortlet.init(portletConfig);
236         }
237         catch (ClassNotFoundException cnofe) {
238             throw new UnavailableException(cnofe.getMessage());
239         }
240         catch (InstantiationException ie) {
241             throw new UnavailableException(ie.getMessage());
242         }
243         catch (IllegalAccessException iae) {
244             throw new UnavailableException(iae.getMessage());
245         }
246 
247         return invokerPortlet;
248     }
249 
250     private static PortletInstanceFactory _instance =
251         new PortletInstanceFactory();
252 
253     private Map<String, Map<String, InvokerPortlet>> _pool;
254 
255 }