001
014
015 package com.liferay.portlet;
016
017 import com.liferay.portal.kernel.model.Portlet;
018 import com.liferay.portal.kernel.model.PortletApp;
019 import com.liferay.portal.kernel.model.PortletConstants;
020 import com.liferay.portal.kernel.portlet.InvokerFilterContainer;
021 import com.liferay.portal.kernel.portlet.InvokerPortlet;
022 import com.liferay.portal.kernel.portlet.InvokerPortletFactory;
023 import com.liferay.portal.kernel.portlet.PortletBag;
024 import com.liferay.portal.kernel.portlet.PortletBagPool;
025 import com.liferay.portal.kernel.portlet.PortletConfigFactoryUtil;
026 import com.liferay.portal.kernel.portlet.PortletContextFactoryUtil;
027 import com.liferay.portal.kernel.portlet.PortletInstanceFactory;
028 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
029 import com.liferay.portal.kernel.service.PortletLocalServiceUtil;
030 import com.liferay.portal.kernel.util.ClassLoaderUtil;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.registry.Registry;
033 import com.liferay.registry.RegistryUtil;
034 import com.liferay.registry.ServiceReference;
035 import com.liferay.registry.ServiceTracker;
036 import com.liferay.registry.ServiceTrackerCustomizer;
037
038 import java.util.Map;
039 import java.util.concurrent.ConcurrentHashMap;
040
041 import javax.portlet.PortletConfig;
042 import javax.portlet.PortletContext;
043 import javax.portlet.PortletException;
044
045 import javax.servlet.ServletContext;
046
047
051 @DoPrivileged
052 public class PortletInstanceFactoryImpl implements PortletInstanceFactory {
053
054 public PortletInstanceFactoryImpl() {
055 _pool = new ConcurrentHashMap<>();
056
057 Registry registry = RegistryUtil.getRegistry();
058
059 _serviceTracker = registry.trackServices(
060 InvokerPortletFactory.class,
061 new InvokerPortletFactoryTrackerCustomizer());
062
063 _serviceTracker.open();
064 }
065
066 @Override
067 public void clear(Portlet portlet) {
068 clear(portlet, true);
069 }
070
071 @Override
072 public void clear(Portlet portlet, boolean resetRemotePortletBag) {
073 String rootPortletId = portlet.getRootPortletId();
074
075 Map<String, InvokerPortlet> portletInstances = _pool.remove(
076 rootPortletId);
077
078 if (portletInstances != null) {
079 InvokerPortlet rootInvokerPortletInstance = portletInstances.remove(
080 rootPortletId);
081
082 if (rootInvokerPortletInstance != null) {
083 rootInvokerPortletInstance.destroy();
084 }
085
086 portletInstances.clear();
087 }
088
089 PortletApp portletApp = portlet.getPortletApp();
090
091 if (resetRemotePortletBag && portletApp.isWARFile()) {
092 PortletBag portletBag = PortletBagPool.remove(rootPortletId);
093
094 if (portletBag != null) {
095 portletBag.destroy();
096 }
097 }
098 }
099
100 @Override
101 public InvokerPortlet create(Portlet portlet, ServletContext servletContext)
102 throws PortletException {
103
104 return create (portlet, servletContext, false);
105 }
106
107 @Override
108 public InvokerPortlet create(
109 Portlet portlet, ServletContext servletContext,
110 boolean destroyPrevious)
111 throws PortletException {
112
113 if (destroyPrevious) {
114 destroyRelated(portlet);
115 }
116
117 boolean instanceable = false;
118
119 boolean deployed = !portlet.isUndeployedPortlet();
120
121 if (portlet.isInstanceable() && deployed &&
122 PortletConstants.hasInstanceId(portlet.getPortletId())) {
123
124 instanceable = true;
125 }
126
127 String rootPortletId = portlet.getRootPortletId();
128
129 InvokerPortlet rootInvokerPortletInstance = null;
130
131 Map<String, InvokerPortlet> portletInstances = null;
132
133 if (deployed) {
134 portletInstances = _pool.get(rootPortletId);
135
136 if (portletInstances == null) {
137 portletInstances = new ConcurrentHashMap<>();
138
139 _pool.put(rootPortletId, portletInstances);
140 }
141 else {
142 if (instanceable) {
143 InvokerPortlet instanceInvokerPortletInstance =
144 portletInstances.get(portlet.getPortletId());
145
146 if (instanceInvokerPortletInstance != null) {
147 return instanceInvokerPortletInstance;
148 }
149 }
150
151 rootInvokerPortletInstance = portletInstances.get(
152 rootPortletId);
153 }
154 }
155
156 if (rootInvokerPortletInstance == null) {
157 PortletBag portletBag = PortletBagPool.get(rootPortletId);
158
159
160
161
162 if (portletBag == null) {
163 PortletBagFactory portletBagFactory = new PortletBagFactory();
164
165 portletBagFactory.setClassLoader(
166 ClassLoaderUtil.getPortalClassLoader());
167 portletBagFactory.setServletContext(servletContext);
168 portletBagFactory.setWARFile(false);
169
170 try {
171 portletBag = portletBagFactory.create(portlet);
172 }
173 catch (Exception e) {
174 throw new PortletException(e);
175 }
176 }
177
178 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
179 portlet, servletContext);
180
181 rootInvokerPortletInstance = init(
182 portlet, portletConfig, portletBag.getPortletInstance());
183
184 if (deployed) {
185 portletInstances.put(rootPortletId, rootInvokerPortletInstance);
186 }
187 }
188
189 if (!instanceable) {
190 return rootInvokerPortletInstance;
191 }
192
193 javax.portlet.Portlet portletInstance =
194 rootInvokerPortletInstance.getPortletInstance();
195
196 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
197 portlet, servletContext);
198
199 PortletContext portletContext = portletConfig.getPortletContext();
200 boolean checkAuthToken = rootInvokerPortletInstance.isCheckAuthToken();
201 boolean facesPortlet = rootInvokerPortletInstance.isFacesPortlet();
202 boolean strutsPortlet = rootInvokerPortletInstance.isStrutsPortlet();
203 boolean strutsBridgePortlet =
204 rootInvokerPortletInstance.isStrutsBridgePortlet();
205
206 InvokerPortlet instanceInvokerPortletInstance =
207 _invokerPortletFactory.create(
208 portlet, portletInstance, portletConfig, portletContext,
209 (InvokerFilterContainer)rootInvokerPortletInstance,
210 checkAuthToken, facesPortlet, strutsPortlet,
211 strutsBridgePortlet);
212
213 if (deployed) {
214 portletInstances.put(
215 portlet.getPortletId(), instanceInvokerPortletInstance);
216 }
217
218 return instanceInvokerPortletInstance;
219 }
220
221 @Override
222 public void delete(Portlet portlet) {
223 if (PortletConstants.hasInstanceId(portlet.getPortletId())) {
224 Map<String, InvokerPortlet> portletInstances = _pool.get(
225 portlet.getRootPortletId());
226
227 if (portletInstances != null) {
228 portletInstances.remove(portlet.getPortletId());
229 }
230 }
231 }
232
233 public void destroy() {
234
235
236
237 }
238
239 @Override
240 public void destroy(Portlet portlet) {
241 _serviceTracker.close();
242
243 clear(portlet);
244
245 destroyRelated(portlet);
246
247 PortletLocalServiceUtil.destroyPortlet(portlet);
248 }
249
250 protected void destroyRelated(Portlet portlet) {
251 PortletConfigFactoryUtil.destroy(portlet);
252 PortletContextFactoryUtil.destroy(portlet);
253 }
254
255 protected InvokerPortlet init(
256 Portlet portlet, PortletConfig portletConfig,
257 javax.portlet.Portlet portletInstance)
258 throws PortletException {
259
260 PortletContext portletContext = portletConfig.getPortletContext();
261
262 InvokerFilterContainer invokerFilterContainer =
263 new InvokerFilterContainerImpl(portlet, portletContext);
264
265 InvokerPortlet invokerPortlet = _invokerPortletFactory.create(
266 portlet, portletInstance, portletContext, invokerFilterContainer);
267
268 invokerPortlet.init(portletConfig);
269
270 return invokerPortlet;
271 }
272
273 private InvokerPortletFactory _invokerPortletFactory;
274 private final Map<String, Map<String, InvokerPortlet>> _pool;
275 private long _serviceRanking;
276 private final ServiceTracker<InvokerPortletFactory, InvokerPortletFactory>
277 _serviceTracker;
278
279 private class InvokerPortletFactoryTrackerCustomizer
280 implements ServiceTrackerCustomizer
281 <InvokerPortletFactory, InvokerPortletFactory> {
282
283 @Override
284 public synchronized InvokerPortletFactory addingService(
285 ServiceReference<InvokerPortletFactory> serviceReference) {
286
287 Registry registry = RegistryUtil.getRegistry();
288
289 InvokerPortletFactory invokerPortletFactory = registry.getService(
290 serviceReference);
291
292 long serviceRanking = GetterUtil.getLong(
293 serviceReference.getProperty("service.ranking"));
294
295 if ((_invokerPortletFactory == null) ||
296 (serviceRanking > _serviceRanking)) {
297
298 _invokerPortletFactory = invokerPortletFactory;
299 _serviceRanking = serviceRanking;
300 }
301
302 return invokerPortletFactory;
303 }
304
305 @Override
306 public void modifiedService(
307 ServiceReference<InvokerPortletFactory> serviceReference,
308 InvokerPortletFactory invokerPortletFactory) {
309 }
310
311 @Override
312 public synchronized void removedService(
313 ServiceReference<InvokerPortletFactory> serviceReference,
314 InvokerPortletFactory invokerPortletFactory) {
315
316 Registry registry = RegistryUtil.getRegistry();
317
318 registry.ungetService(serviceReference);
319
320 serviceReference = registry.getServiceReference(
321 InvokerPortletFactory.class);
322
323 if (serviceReference != null) {
324 _invokerPortletFactory = registry.getService(serviceReference);
325
326 _serviceRanking = GetterUtil.getLong(
327 serviceReference.getProperty("service.ranking"));
328 }
329 }
330
331 }
332
333 }