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