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