1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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="PortletInstanceFactoryImpl.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Brian Wing Shun Chan
47   *
48   */
49  public class PortletInstanceFactoryImpl implements PortletInstanceFactory {
50  
51      public PortletInstanceFactoryImpl() {
52          _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
53      }
54  
55      public void clear(Portlet portlet) {
56          Map<String, InvokerPortlet> portletInstances = _pool.get(
57              portlet.getRootPortletId());
58  
59          if (portletInstances != null) {
60              Iterator<Map.Entry<String, InvokerPortlet>> itr =
61                  portletInstances.entrySet().iterator();
62  
63              while (itr.hasNext()) {
64                  Map.Entry<String, InvokerPortlet> entry = itr.next();
65  
66                  String portletId = entry.getKey();
67                  InvokerPortlet invokerPortletInstance = entry.getValue();
68  
69                  if (PortletConstants.getInstanceId(portletId) == null) {
70                      invokerPortletInstance.destroy();
71  
72                      break;
73                  }
74              }
75          }
76  
77          _pool.remove(portlet.getRootPortletId());
78  
79          PortletApp portletApp = portlet.getPortletApp();
80  
81          if (portletApp.isWARFile()) {
82              PortletBag portletBag = PortletBagPool.get(
83                  portlet.getRootPortletId());
84  
85              if (portletBag != null) {
86                  portletBag.setPortletInstance(null);
87              }
88          }
89      }
90  
91      public InvokerPortlet create(Portlet portlet, ServletContext servletContext)
92          throws PortletException {
93  
94          boolean instanceable = false;
95  
96          if ((portlet.isInstanceable()) &&
97              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
98  
99              instanceable = true;
100         }
101 
102         Map<String, InvokerPortlet> portletInstances = _pool.get(
103             portlet.getRootPortletId());
104 
105         if (portletInstances == null) {
106             portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
107 
108             _pool.put(portlet.getRootPortletId(), portletInstances);
109         }
110 
111         InvokerPortlet instanceInvokerPortletInstance = null;
112 
113         if (instanceable) {
114             instanceInvokerPortletInstance = portletInstances.get(
115                 portlet.getPortletId());
116         }
117 
118         InvokerPortlet rootInvokerPortletInstance = null;
119 
120         if (instanceInvokerPortletInstance == null) {
121             rootInvokerPortletInstance = portletInstances.get(
122                 portlet.getRootPortletId());
123 
124             if (rootInvokerPortletInstance == null) {
125                 PortletConfig portletConfig =
126                     PortletConfigFactory.create(portlet, servletContext);
127 
128                 PortletApp portletApp = portlet.getPortletApp();
129 
130                 if (portletApp.isWARFile()) {
131                     PortletBag portletBag = PortletBagPool.get(
132                         portlet.getRootPortletId());
133 
134                     rootInvokerPortletInstance = init(
135                         portlet, portletConfig,
136                         portletBag.getPortletInstance());
137                 }
138                 else {
139                     rootInvokerPortletInstance = init(portlet, portletConfig);
140                 }
141 
142                 portletInstances.put(
143                     portlet.getRootPortletId(), rootInvokerPortletInstance);
144             }
145         }
146 
147         if (instanceable) {
148             if (instanceInvokerPortletInstance == null) {
149                 javax.portlet.Portlet portletInstance =
150                     rootInvokerPortletInstance.getPortletInstance();
151 
152                 PortletConfig portletConfig =
153                     PortletConfigFactory.create(portlet, servletContext);
154 
155                 PortletContext portletContext =
156                     portletConfig.getPortletContext();
157                 boolean facesPortlet =
158                     rootInvokerPortletInstance.isFacesPortlet();
159                 boolean strutsPortlet =
160                     rootInvokerPortletInstance.isStrutsPortlet();
161                 boolean strutsBridgePortlet =
162                     rootInvokerPortletInstance.isStrutsBridgePortlet();
163 
164                 instanceInvokerPortletInstance =
165                     _internalInvokerPortletPrototype.create(
166                         portlet, portletInstance, portletConfig, portletContext,
167                         facesPortlet, strutsPortlet, strutsBridgePortlet);
168 
169                 portletInstances.put(
170                     portlet.getPortletId(), instanceInvokerPortletInstance);
171             }
172         }
173         else {
174             if (rootInvokerPortletInstance != null) {
175                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
176             }
177         }
178 
179         return instanceInvokerPortletInstance;
180     }
181 
182     public void destroy(Portlet portlet) {
183         clear(portlet);
184 
185         PortletConfigFactory.destroy(portlet);
186         PortletContextFactory.destroy(portlet);
187 
188         PortletLocalServiceUtil.destroyPortlet(portlet);
189     }
190 
191     public void setInternalInvokerPortletPrototype(
192         InvokerPortlet internalInvokerPortletPrototype) {
193 
194         _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
195     }
196 
197     protected InvokerPortlet init(Portlet portlet, PortletConfig portletConfig)
198         throws PortletException {
199 
200         return init(portlet, portletConfig, null);
201     }
202 
203     protected InvokerPortlet init(
204             Portlet portlet, PortletConfig portletConfig,
205             javax.portlet.Portlet portletInstance)
206         throws PortletException {
207 
208         InvokerPortlet invokerPortlet = null;
209 
210         try {
211             if (portletInstance == null) {
212                 portletInstance =
213                     (javax.portlet.Portlet)Class.forName(
214                         portlet.getPortletClass()).newInstance();
215             }
216 
217             PortletContext portletContext = portletConfig.getPortletContext();
218 
219             invokerPortlet = _internalInvokerPortletPrototype.create(
220                 portlet, portletInstance, portletContext);
221 
222             invokerPortlet.init(portletConfig);
223         }
224         catch (ClassNotFoundException cnofe) {
225             throw new UnavailableException(cnofe.getMessage());
226         }
227         catch (InstantiationException ie) {
228             throw new UnavailableException(ie.getMessage());
229         }
230         catch (IllegalAccessException iae) {
231             throw new UnavailableException(iae.getMessage());
232         }
233 
234         return invokerPortlet;
235     }
236 
237     private InvokerPortlet _internalInvokerPortletPrototype;
238     private Map<String, Map<String, InvokerPortlet>> _pool;
239 
240 }