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