1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet;
16  
17  import com.liferay.portal.kernel.portlet.PortletBag;
18  import com.liferay.portal.kernel.portlet.PortletBagPool;
19  import com.liferay.portal.model.Portlet;
20  import com.liferay.portal.model.PortletApp;
21  import com.liferay.portal.model.PortletConstants;
22  import com.liferay.portal.service.PortletLocalServiceUtil;
23  
24  import java.util.Iterator;
25  import java.util.Map;
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  import javax.portlet.PortletConfig;
29  import javax.portlet.PortletContext;
30  import javax.portlet.PortletException;
31  import javax.portlet.UnavailableException;
32  
33  import javax.servlet.ServletContext;
34  
35  /**
36   * <a href="PortletInstanceFactoryImpl.java.html"><b><i>View Source</i></b></a>
37   *
38   * @author Brian Wing Shun Chan
39   */
40  public class PortletInstanceFactoryImpl implements PortletInstanceFactory {
41  
42      public PortletInstanceFactoryImpl() {
43          _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
44      }
45  
46      public void clear(Portlet portlet) {
47          Map<String, InvokerPortlet> portletInstances = _pool.get(
48              portlet.getRootPortletId());
49  
50          if (portletInstances != null) {
51              Iterator<Map.Entry<String, InvokerPortlet>> itr =
52                  portletInstances.entrySet().iterator();
53  
54              while (itr.hasNext()) {
55                  Map.Entry<String, InvokerPortlet> entry = itr.next();
56  
57                  String portletId = entry.getKey();
58                  InvokerPortlet invokerPortletInstance = entry.getValue();
59  
60                  if (PortletConstants.getInstanceId(portletId) == null) {
61                      invokerPortletInstance.destroy();
62  
63                      break;
64                  }
65              }
66          }
67  
68          _pool.remove(portlet.getRootPortletId());
69  
70          PortletApp portletApp = portlet.getPortletApp();
71  
72          if (portletApp.isWARFile()) {
73              PortletBag portletBag = PortletBagPool.get(
74                  portlet.getRootPortletId());
75  
76              if (portletBag != null) {
77                  portletBag.setPortletInstance(null);
78              }
79          }
80      }
81  
82      public InvokerPortlet create(Portlet portlet, ServletContext servletContext)
83          throws PortletException {
84  
85          boolean instanceable = false;
86  
87          if ((portlet.isInstanceable()) &&
88              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
89  
90              instanceable = true;
91          }
92  
93          Map<String, InvokerPortlet> portletInstances = _pool.get(
94              portlet.getRootPortletId());
95  
96          if (portletInstances == null) {
97              portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
98  
99              _pool.put(portlet.getRootPortletId(), portletInstances);
100         }
101 
102         InvokerPortlet instanceInvokerPortletInstance = null;
103 
104         if (instanceable) {
105             instanceInvokerPortletInstance = portletInstances.get(
106                 portlet.getPortletId());
107         }
108 
109         InvokerPortlet rootInvokerPortletInstance = null;
110 
111         if (instanceInvokerPortletInstance == null) {
112             rootInvokerPortletInstance = portletInstances.get(
113                 portlet.getRootPortletId());
114 
115             if (rootInvokerPortletInstance == null) {
116                 PortletConfig portletConfig =
117                     PortletConfigFactory.create(portlet, servletContext);
118 
119                 PortletApp portletApp = portlet.getPortletApp();
120 
121                 if (portletApp.isWARFile()) {
122                     PortletBag portletBag = PortletBagPool.get(
123                         portlet.getRootPortletId());
124 
125                     rootInvokerPortletInstance = init(
126                         portlet, portletConfig,
127                         portletBag.getPortletInstance());
128                 }
129                 else {
130                     rootInvokerPortletInstance = init(portlet, portletConfig);
131                 }
132 
133                 portletInstances.put(
134                     portlet.getRootPortletId(), rootInvokerPortletInstance);
135             }
136         }
137 
138         if (instanceable) {
139             if (instanceInvokerPortletInstance == null) {
140                 javax.portlet.Portlet portletInstance =
141                     rootInvokerPortletInstance.getPortletInstance();
142 
143                 PortletConfig portletConfig =
144                     PortletConfigFactory.create(portlet, servletContext);
145 
146                 PortletContext portletContext =
147                     portletConfig.getPortletContext();
148                 boolean facesPortlet =
149                     rootInvokerPortletInstance.isFacesPortlet();
150                 boolean strutsPortlet =
151                     rootInvokerPortletInstance.isStrutsPortlet();
152                 boolean strutsBridgePortlet =
153                     rootInvokerPortletInstance.isStrutsBridgePortlet();
154 
155                 instanceInvokerPortletInstance =
156                     _internalInvokerPortletPrototype.create(
157                         portlet, portletInstance, portletConfig, portletContext,
158                         facesPortlet, strutsPortlet, strutsBridgePortlet);
159 
160                 portletInstances.put(
161                     portlet.getPortletId(), instanceInvokerPortletInstance);
162             }
163         }
164         else {
165             if (rootInvokerPortletInstance != null) {
166                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
167             }
168         }
169 
170         return instanceInvokerPortletInstance;
171     }
172 
173     public void destroy(Portlet portlet) {
174         clear(portlet);
175 
176         PortletConfigFactory.destroy(portlet);
177         PortletContextFactory.destroy(portlet);
178 
179         PortletLocalServiceUtil.destroyPortlet(portlet);
180     }
181 
182     public void setInternalInvokerPortletPrototype(
183         InvokerPortlet internalInvokerPortletPrototype) {
184 
185         _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
186     }
187 
188     protected InvokerPortlet init(Portlet portlet, PortletConfig portletConfig)
189         throws PortletException {
190 
191         return init(portlet, portletConfig, null);
192     }
193 
194     protected InvokerPortlet init(
195             Portlet portlet, PortletConfig portletConfig,
196             javax.portlet.Portlet portletInstance)
197         throws PortletException {
198 
199         InvokerPortlet invokerPortlet = null;
200 
201         try {
202             if (portletInstance == null) {
203                 portletInstance =
204                     (javax.portlet.Portlet)Class.forName(
205                         portlet.getPortletClass()).newInstance();
206             }
207 
208             PortletContext portletContext = portletConfig.getPortletContext();
209 
210             invokerPortlet = _internalInvokerPortletPrototype.create(
211                 portlet, portletInstance, portletContext);
212 
213             invokerPortlet.init(portletConfig);
214         }
215         catch (ClassNotFoundException cnofe) {
216             throw new UnavailableException(cnofe.getMessage());
217         }
218         catch (InstantiationException ie) {
219             throw new UnavailableException(ie.getMessage());
220         }
221         catch (IllegalAccessException iae) {
222             throw new UnavailableException(iae.getMessage());
223         }
224 
225         return invokerPortlet;
226     }
227 
228     private InvokerPortlet _internalInvokerPortletPrototype;
229     private Map<String, Map<String, InvokerPortlet>> _pool;
230 
231 }