1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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.kernel.util.PortalClassLoaderUtil;
20  import com.liferay.portal.model.Portlet;
21  import com.liferay.portal.model.PortletApp;
22  import com.liferay.portal.model.PortletConstants;
23  import com.liferay.portal.service.PortletLocalServiceUtil;
24  
25  import java.util.Iterator;
26  import java.util.Map;
27  import java.util.concurrent.ConcurrentHashMap;
28  
29  import javax.portlet.PortletConfig;
30  import javax.portlet.PortletContext;
31  import javax.portlet.PortletException;
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          clear(portlet, true);
48      }
49  
50      public void clear(Portlet portlet, boolean resetRemotePortletBag) {
51          Map<String, InvokerPortlet> portletInstances = _pool.get(
52              portlet.getRootPortletId());
53  
54          if (portletInstances != null) {
55              Iterator<Map.Entry<String, InvokerPortlet>> itr =
56                  portletInstances.entrySet().iterator();
57  
58              while (itr.hasNext()) {
59                  Map.Entry<String, InvokerPortlet> entry = itr.next();
60  
61                  String portletId = entry.getKey();
62                  InvokerPortlet invokerPortletInstance = entry.getValue();
63  
64                  if (PortletConstants.getInstanceId(portletId) == null) {
65                      invokerPortletInstance.destroy();
66  
67                      break;
68                  }
69              }
70          }
71  
72          _pool.remove(portlet.getRootPortletId());
73  
74          PortletApp portletApp = portlet.getPortletApp();
75  
76          if (resetRemotePortletBag && portletApp.isWARFile()) {
77              PortletBagPool.remove(portlet.getRootPortletId());
78          }
79      }
80  
81      public InvokerPortlet create(Portlet portlet, ServletContext servletContext)
82          throws PortletException {
83  
84          boolean instanceable = false;
85  
86          if ((portlet.isInstanceable()) &&
87              (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
88  
89              instanceable = true;
90          }
91  
92          Map<String, InvokerPortlet> portletInstances = _pool.get(
93              portlet.getRootPortletId());
94  
95          if (portletInstances == null) {
96              portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
97  
98              _pool.put(portlet.getRootPortletId(), portletInstances);
99          }
100 
101         InvokerPortlet instanceInvokerPortletInstance = null;
102 
103         if (instanceable) {
104             instanceInvokerPortletInstance = portletInstances.get(
105                 portlet.getPortletId());
106         }
107 
108         InvokerPortlet rootInvokerPortletInstance = null;
109 
110         if (instanceInvokerPortletInstance == null) {
111             rootInvokerPortletInstance = portletInstances.get(
112                 portlet.getRootPortletId());
113 
114             if (rootInvokerPortletInstance == null) {
115                 PortletBag portletBag = PortletBagPool.get(
116                     portlet.getRootPortletId());
117 
118                 // Portlet bag should never be null unless the portlet has been
119                 // undeployed
120 
121                 if (portletBag == null) {
122                     PortletBagFactory portletBagFactory =
123                         new PortletBagFactory();
124 
125                     portletBagFactory.setClassLoader(
126                         PortalClassLoaderUtil.getClassLoader());
127                     portletBagFactory.setServletContext(servletContext);
128                     portletBagFactory.setWARFile(false);
129 
130                     try {
131                         portletBag = portletBagFactory.create(portlet);
132                     }
133                     catch (Exception e) {
134                         throw new PortletException(e);
135                     }
136                 }
137 
138                 PortletConfig portletConfig = PortletConfigFactory.create(
139                     portlet, servletContext);
140 
141                 rootInvokerPortletInstance = init(
142                     portlet, portletConfig, portletBag.getPortletInstance());
143 
144                 portletInstances.put(
145                     portlet.getRootPortletId(), rootInvokerPortletInstance);
146             }
147         }
148 
149         if (instanceable) {
150             if (instanceInvokerPortletInstance == null) {
151                 javax.portlet.Portlet portletInstance =
152                     rootInvokerPortletInstance.getPortletInstance();
153 
154                 PortletConfig portletConfig =
155                     PortletConfigFactory.create(portlet, servletContext);
156 
157                 PortletContext portletContext =
158                     portletConfig.getPortletContext();
159                 boolean checkAuthToken =
160                     rootInvokerPortletInstance.isCheckAuthToken();
161                 boolean facesPortlet =
162                     rootInvokerPortletInstance.isFacesPortlet();
163                 boolean strutsPortlet =
164                     rootInvokerPortletInstance.isStrutsPortlet();
165                 boolean strutsBridgePortlet =
166                     rootInvokerPortletInstance.isStrutsBridgePortlet();
167 
168                 instanceInvokerPortletInstance =
169                     _internalInvokerPortletPrototype.create(
170                         portlet, portletInstance, portletConfig, portletContext,
171                         checkAuthToken, facesPortlet, strutsPortlet,
172                         strutsBridgePortlet);
173 
174                 portletInstances.put(
175                     portlet.getPortletId(), instanceInvokerPortletInstance);
176             }
177         }
178         else {
179             if (rootInvokerPortletInstance != null) {
180                 instanceInvokerPortletInstance = rootInvokerPortletInstance;
181             }
182         }
183 
184         return instanceInvokerPortletInstance;
185     }
186 
187     public void destroy() {
188 
189         // LPS-10473
190 
191     }
192 
193     public void destroy(Portlet portlet) {
194         clear(portlet);
195 
196         PortletConfigFactory.destroy(portlet);
197         PortletContextFactory.destroy(portlet);
198 
199         PortletLocalServiceUtil.destroyPortlet(portlet);
200     }
201 
202     public void setInternalInvokerPortletPrototype(
203         InvokerPortlet internalInvokerPortletPrototype) {
204 
205         _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
206     }
207 
208     protected InvokerPortlet init(
209             Portlet portlet, PortletConfig portletConfig,
210             javax.portlet.Portlet portletInstance)
211         throws PortletException {
212 
213         PortletContext portletContext = portletConfig.getPortletContext();
214 
215         InvokerPortlet invokerPortlet = _internalInvokerPortletPrototype.create(
216             portlet, portletInstance, portletContext);
217 
218         invokerPortlet.init(portletConfig);
219 
220         return invokerPortlet;
221     }
222 
223     private InvokerPortlet _internalInvokerPortletPrototype;
224     private Map<String, Map<String, InvokerPortlet>> _pool;
225 
226 }