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 boolean instanceable = false;
103
104 boolean deployed = !portlet.isUndeployedPortlet();
105
106 if (portlet.isInstanceable() && deployed &&
107 PortletConstants.hasInstanceId(portlet.getPortletId())) {
108
109 instanceable = true;
110 }
111
112 String rootPortletId = portlet.getRootPortletId();
113
114 InvokerPortlet rootInvokerPortletInstance = null;
115
116 Map<String, InvokerPortlet> portletInstances = null;
117
118 if (deployed) {
119 portletInstances = _pool.get(rootPortletId);
120
121 if (portletInstances == null) {
122 portletInstances = new ConcurrentHashMap<>();
123
124 _pool.put(rootPortletId, portletInstances);
125 }
126 else {
127 if (instanceable) {
128 InvokerPortlet instanceInvokerPortletInstance =
129 portletInstances.get(portlet.getPortletId());
130
131 if (instanceInvokerPortletInstance != null) {
132 return instanceInvokerPortletInstance;
133 }
134 }
135
136 rootInvokerPortletInstance = portletInstances.get(
137 rootPortletId);
138 }
139 }
140
141 if (rootInvokerPortletInstance == null) {
142 PortletBag portletBag = PortletBagPool.get(rootPortletId);
143
144
145
146
147 if (portletBag == null) {
148 PortletBagFactory portletBagFactory = new PortletBagFactory();
149
150 portletBagFactory.setClassLoader(
151 ClassLoaderUtil.getPortalClassLoader());
152 portletBagFactory.setServletContext(servletContext);
153 portletBagFactory.setWARFile(false);
154
155 try {
156 portletBag = portletBagFactory.create(portlet);
157 }
158 catch (Exception e) {
159 throw new PortletException(e);
160 }
161 }
162
163 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
164 portlet, servletContext);
165
166 rootInvokerPortletInstance = init(
167 portlet, portletConfig, portletBag.getPortletInstance());
168
169 if (deployed) {
170 portletInstances.put(rootPortletId, rootInvokerPortletInstance);
171 }
172 }
173
174 if (!instanceable) {
175 return rootInvokerPortletInstance;
176 }
177
178 javax.portlet.Portlet portletInstance =
179 rootInvokerPortletInstance.getPortletInstance();
180
181 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
182 portlet, servletContext);
183
184 PortletContext portletContext = portletConfig.getPortletContext();
185 boolean checkAuthToken = rootInvokerPortletInstance.isCheckAuthToken();
186 boolean facesPortlet = rootInvokerPortletInstance.isFacesPortlet();
187 boolean strutsPortlet = rootInvokerPortletInstance.isStrutsPortlet();
188 boolean strutsBridgePortlet =
189 rootInvokerPortletInstance.isStrutsBridgePortlet();
190
191 InvokerPortlet instanceInvokerPortletInstance =
192 _invokerPortletFactory.create(
193 portlet, portletInstance, portletConfig, portletContext,
194 (InvokerFilterContainer)rootInvokerPortletInstance,
195 checkAuthToken, facesPortlet, strutsPortlet,
196 strutsBridgePortlet);
197
198 if (deployed) {
199 portletInstances.put(
200 portlet.getPortletId(), instanceInvokerPortletInstance);
201 }
202
203 return instanceInvokerPortletInstance;
204 }
205
206 @Override
207 public void delete(Portlet portlet) {
208 if (PortletConstants.hasInstanceId(portlet.getPortletId())) {
209 Map<String, InvokerPortlet> portletInstances = _pool.get(
210 portlet.getRootPortletId());
211
212 if (portletInstances != null) {
213 portletInstances.remove(portlet.getPortletId());
214 }
215 }
216 }
217
218 public void destroy() {
219
220
221
222 }
223
224 @Override
225 public void destroy(Portlet portlet) {
226 _serviceTracker.close();
227
228 clear(portlet);
229
230 PortletConfigFactoryUtil.destroy(portlet);
231 PortletContextFactory.destroy(portlet);
232
233 PortletLocalServiceUtil.destroyPortlet(portlet);
234 }
235
236 protected InvokerPortlet init(
237 Portlet portlet, PortletConfig portletConfig,
238 javax.portlet.Portlet portletInstance)
239 throws PortletException {
240
241 PortletContext portletContext = portletConfig.getPortletContext();
242
243 InvokerFilterContainer invokerFilterContainer =
244 new InvokerFilterContainerImpl(portlet, portletContext);
245
246 InvokerPortlet invokerPortlet = _invokerPortletFactory.create(
247 portlet, portletInstance, portletContext, invokerFilterContainer);
248
249 invokerPortlet.init(portletConfig);
250
251 return invokerPortlet;
252 }
253
254 private InvokerPortletFactory _invokerPortletFactory;
255 private final Map<String, Map<String, InvokerPortlet>> _pool;
256 private final ServiceTracker<InvokerPortletFactory, InvokerPortletFactory>
257 _serviceTracker;
258
259 private class InvokerPortletFactoryTrackerCustomizer
260 implements ServiceTrackerCustomizer
261 <InvokerPortletFactory, InvokerPortletFactory> {
262
263 @Override
264 public InvokerPortletFactory addingService(
265 ServiceReference<InvokerPortletFactory> serviceReference) {
266
267 Registry registry = RegistryUtil.getRegistry();
268
269 InvokerPortletFactory invokerPortletFactory = registry.getService(
270 serviceReference);
271
272 _invokerPortletFactory = invokerPortletFactory;
273
274 return invokerPortletFactory;
275 }
276
277 @Override
278 public void modifiedService(
279 ServiceReference<InvokerPortletFactory> serviceReference,
280 InvokerPortletFactory invokerPortletFactory) {
281 }
282
283 @Override
284 public void removedService(
285 ServiceReference<InvokerPortletFactory> serviceReference,
286 InvokerPortletFactory invokerPortletFactory) {
287
288 Registry registry = RegistryUtil.getRegistry();
289
290 registry.ungetService(serviceReference);
291 }
292
293 }
294
295 }