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 checkAuthToken =
149                     rootInvokerPortletInstance.isCheckAuthToken();
150                 boolean facesPortlet =
151                     rootInvokerPortletInstance.isFacesPortlet();
152                 boolean strutsPortlet =
153                     rootInvokerPortletInstance.isStrutsPortlet();
154                 boolean strutsBridgePortlet =
155                     rootInvokerPortletInstance.isStrutsBridgePortlet();
156 
157                 instanceInvokerPortletInstance =
158                     _internalInvokerPortletPrototype.create(
159                         portlet, portletInstance, portletConfig, portletContext,
160                         checkAuthToken, facesPortlet, strutsPortlet,
161                         strutsBridgePortlet);
162 
163                 portletInstances.put(
164                     portlet.getPortletId(), instanceInvokerPortletInstance);
165             }
166         }
167         else {
168             if (rootInvokerPortletInstance != null) {
169                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
170             }
171         }
172 
173         return instanceInvokerPortletInstance;
174     }
175 
176     public void destroy(Portlet portlet) {
177         clear(portlet);
178 
179         PortletConfigFactory.destroy(portlet);
180         PortletContextFactory.destroy(portlet);
181 
182         PortletLocalServiceUtil.destroyPortlet(portlet);
183     }
184 
185     public void setInternalInvokerPortletPrototype(
186         InvokerPortlet internalInvokerPortletPrototype) {
187 
188         _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
189     }
190 
191     protected InvokerPortlet init(Portlet portlet, PortletConfig portletConfig)
192         throws PortletException {
193 
194         return init(portlet, portletConfig, null);
195     }
196 
197     protected InvokerPortlet init(
198             Portlet portlet, PortletConfig portletConfig,
199             javax.portlet.Portlet portletInstance)
200         throws PortletException {
201 
202         InvokerPortlet invokerPortlet = null;
203 
204         try {
205             if (portletInstance == null) {
206                 portletInstance =
207                     (javax.portlet.Portlet)Class.forName(
208                         portlet.getPortletClass()).newInstance();
209             }
210 
211             PortletContext portletContext = portletConfig.getPortletContext();
212 
213             invokerPortlet = _internalInvokerPortletPrototype.create(
214                 portlet, portletInstance, portletContext);
215 
216             invokerPortlet.init(portletConfig);
217         }
218         catch (ClassNotFoundException cnofe) {
219             throw new UnavailableException(cnofe.getMessage());
220         }
221         catch (InstantiationException ie) {
222             throw new UnavailableException(ie.getMessage());
223         }
224         catch (IllegalAccessException iae) {
225             throw new UnavailableException(iae.getMessage());
226         }
227 
228         return invokerPortlet;
229     }
230 
231     private InvokerPortlet _internalInvokerPortletPrototype;
232     private Map<String, Map<String, InvokerPortlet>> _pool;
233 
234 }