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