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  import com.liferay.portal.util.PropsValues;
32  
33  import java.util.Iterator;
34  import java.util.Map;
35  import java.util.concurrent.ConcurrentHashMap;
36  
37  import javax.portlet.PortletConfig;
38  import javax.portlet.PortletContext;
39  import javax.portlet.PortletException;
40  import javax.portlet.UnavailableException;
41  
42  import javax.servlet.ServletContext;
43  
44  /**
45   * <a href="PortletInstanceFactoryImpl.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Brian Wing Shun Chan
48   *
49   */
50  public class PortletInstanceFactoryImpl implements PortletInstanceFactory {
51  
52      public PortletInstanceFactoryImpl() {
53          _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
54      }
55  
56      public void clear(Portlet portlet) {
57          Map<String, InvokerPortlet> portletInstances = _pool.get(
58              portlet.getRootPortletId());
59  
60          if (portletInstances != null) {
61              Iterator<Map.Entry<String, InvokerPortlet>> itr =
62                  portletInstances.entrySet().iterator();
63  
64              while (itr.hasNext()) {
65                  Map.Entry<String, InvokerPortlet> entry = itr.next();
66  
67                  String portletId = entry.getKey();
68                  InvokerPortlet invokerPortletInstance = entry.getValue();
69  
70                  if (PortletConstants.getInstanceId(portletId) == null) {
71                      invokerPortletInstance.destroy();
72  
73                      break;
74                  }
75              }
76          }
77  
78          _pool.remove(portlet.getRootPortletId());
79  
80          PortletApp portletApp = portlet.getPortletApp();
81  
82          if (portletApp.isWARFile()) {
83              PortletBag portletBag = PortletBagPool.get(
84                  portlet.getRootPortletId());
85  
86              if (portletBag != null) {
87                  portletBag.removePortletInstance();
88              }
89          }
90      }
91  
92      public InvokerPortlet create(Portlet portlet, ServletContext servletContext)
93          throws PortletException {
94  
95          boolean instanceable = false;
96  
97          if ((portlet.isInstanceable()) &&
98              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
99  
100             instanceable = true;
101         }
102 
103         Map<String, InvokerPortlet> portletInstances = _pool.get(
104             portlet.getRootPortletId());
105 
106         if (portletInstances == null) {
107             portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
108 
109             _pool.put(portlet.getRootPortletId(), portletInstances);
110         }
111 
112         InvokerPortlet instanceInvokerPortletInstance = null;
113 
114         if (instanceable) {
115             instanceInvokerPortletInstance = portletInstances.get(
116                 portlet.getPortletId());
117         }
118 
119         InvokerPortlet rootInvokerPortletInstance = null;
120 
121         if (instanceInvokerPortletInstance == null) {
122             rootInvokerPortletInstance = portletInstances.get(
123                 portlet.getRootPortletId());
124 
125             if (rootInvokerPortletInstance == null) {
126                 PortletConfig portletConfig =
127                     PortletConfigFactory.create(portlet, servletContext);
128 
129                 PortletApp portletApp = portlet.getPortletApp();
130 
131                 if (portletApp.isWARFile()) {
132                     PortletBag portletBag = PortletBagPool.get(
133                         portlet.getRootPortletId());
134 
135                     rootInvokerPortletInstance = init(
136                         portlet, portletConfig,
137                         portletBag.getPortletInstance());
138                 }
139                 else {
140                     rootInvokerPortletInstance = init(portlet, portletConfig);
141                 }
142 
143                 portletInstances.put(
144                     portlet.getRootPortletId(), rootInvokerPortletInstance);
145             }
146         }
147 
148         if (instanceable) {
149             if (instanceInvokerPortletInstance == null) {
150                 javax.portlet.Portlet portletInstance =
151                     rootInvokerPortletInstance.getPortletInstance();
152 
153                 PortletConfig portletConfig =
154                     PortletConfigFactory.create(portlet, servletContext);
155 
156                 PortletContext portletContext =
157                     portletConfig.getPortletContext();
158                 boolean facesPortlet =
159                     rootInvokerPortletInstance.isFacesPortlet();
160                 boolean strutsPortlet =
161                     rootInvokerPortletInstance.isStrutsPortlet();
162                 boolean strutsBridgePortlet =
163                     rootInvokerPortletInstance.isStrutsBridgePortlet();
164 
165                 if (PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
166                     instanceInvokerPortletInstance =
167                         _sunInvokerPortletPrototype.create(
168                             portlet, portletInstance, portletConfig,
169                             portletContext, facesPortlet, strutsPortlet,
170                             strutsBridgePortlet);
171                 }
172                 else {
173                     instanceInvokerPortletInstance =
174                         _internalInvokerPortletPrototype.create(
175                             portlet, portletInstance, portletConfig,
176                             portletContext, facesPortlet, strutsPortlet,
177                             strutsBridgePortlet);
178                 }
179 
180                 portletInstances.put(
181                     portlet.getPortletId(), instanceInvokerPortletInstance);
182             }
183         }
184         else {
185             if (rootInvokerPortletInstance != null) {
186                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
187             }
188         }
189 
190         return instanceInvokerPortletInstance;
191     }
192 
193     public void destroy(Portlet portlet) {
194         clear(portlet);
195 
196         PortletConfigFactory.destroy(portlet);
197         PortletContextFactory.destroy(portlet);
198 
199         PortletLocalServiceUtil.destroyPortlet(portlet);
200     }
201 
202     public void setInternalInvokerPortletPrototype(
203         InvokerPortlet internalInvokerPortletPrototype) {
204 
205         _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
206     }
207 
208     public void setSunInvokerPortletPrototype(
209         InvokerPortlet sunInvokerPortletPrototype) {
210 
211         _sunInvokerPortletPrototype = sunInvokerPortletPrototype;
212     }
213 
214     protected InvokerPortlet init(Portlet portlet, PortletConfig portletConfig)
215         throws PortletException {
216 
217         return init(portlet, portletConfig, null);
218     }
219 
220     protected InvokerPortlet init(
221             Portlet portlet, PortletConfig portletConfig,
222             javax.portlet.Portlet portletInstance)
223         throws PortletException {
224 
225         InvokerPortlet invokerPortlet = null;
226 
227         try {
228             if ((portletInstance == null) && !portlet.isRemote()) {
229                 portletInstance =
230                     (javax.portlet.Portlet)Class.forName(
231                         portlet.getPortletClass()).newInstance();
232             }
233 
234             PortletContext portletContext = portletConfig.getPortletContext();
235 
236             if (portlet.isRemote() || PropsValues.PORTLET_CONTAINER_IMPL_SUN) {
237                 invokerPortlet = _sunInvokerPortletPrototype.create(
238                     portlet, portletInstance, portletContext);
239             }
240             else {
241                 invokerPortlet = _internalInvokerPortletPrototype.create(
242                     portlet, portletInstance, portletContext);
243             }
244 
245             invokerPortlet.init(portletConfig);
246         }
247         catch (ClassNotFoundException cnofe) {
248             throw new UnavailableException(cnofe.getMessage());
249         }
250         catch (InstantiationException ie) {
251             throw new UnavailableException(ie.getMessage());
252         }
253         catch (IllegalAccessException iae) {
254             throw new UnavailableException(iae.getMessage());
255         }
256 
257         return invokerPortlet;
258     }
259 
260     private InvokerPortlet _internalInvokerPortletPrototype;
261     private InvokerPortlet _sunInvokerPortletPrototype;
262     private Map<String, Map<String, InvokerPortlet>> _pool;
263 
264 }