1
22
23 package com.liferay.portlet;
24
25 import com.liferay.portal.kernel.portlet.PortletBag;
26 import com.liferay.portal.kernel.portlet.PortletBagPool;
27 import com.liferay.portal.model.Portlet;
28 import com.liferay.portal.model.PortletApp;
29 import com.liferay.portal.model.PortletConstants;
30 import com.liferay.portal.service.PortletLocalServiceUtil;
31
32 import java.util.Iterator;
33 import java.util.Map;
34 import java.util.concurrent.ConcurrentHashMap;
35
36 import javax.portlet.PortletConfig;
37 import javax.portlet.PortletContext;
38 import javax.portlet.PortletException;
39 import javax.portlet.UnavailableException;
40
41 import javax.servlet.ServletContext;
42
43
49 public class PortletInstanceFactory {
50
51 public static InvokerPortlet create(
52 Portlet portlet, ServletContext servletContext)
53 throws PortletException {
54
55 return _instance._create(portlet, servletContext);
56 }
57
58 public static void destroy(Portlet portlet) {
59 _instance._destroy(portlet);
60 }
61
62 public void setInternalInvokerPortletPrototype(
63 InvokerPortlet internalInvokerPortletPrototype) {
64
65 _internalInvokerPortletPrototype = internalInvokerPortletPrototype;
66 }
67
68 private PortletInstanceFactory() {
69 _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
70 }
71
72 private InvokerPortlet _create(
73 Portlet portlet, ServletContext servletContext)
74 throws PortletException {
75
76 boolean instanceable = false;
77
78 if ((portlet.isInstanceable()) &&
79 (PortletConstants.getInstanceId(portlet.getPortletId()) != null)) {
80
81 instanceable = true;
82 }
83
84 Map<String, InvokerPortlet> portletInstances = _pool.get(
85 portlet.getRootPortletId());
86
87 if (portletInstances == null) {
88 portletInstances = new ConcurrentHashMap<String, InvokerPortlet>();
89
90 _pool.put(portlet.getRootPortletId(), portletInstances);
91 }
92
93 InvokerPortlet instanceInvokerPortletInstance = null;
94
95 if (instanceable) {
96 instanceInvokerPortletInstance = portletInstances.get(
97 portlet.getPortletId());
98 }
99
100 InvokerPortlet rootInvokerPortletInstance = null;
101
102 if (instanceInvokerPortletInstance == null) {
103 rootInvokerPortletInstance = portletInstances.get(
104 portlet.getRootPortletId());
105
106 if (rootInvokerPortletInstance == null) {
107 PortletConfig portletConfig =
108 PortletConfigFactory.create(portlet, servletContext);
109
110 PortletApp portletApp = portlet.getPortletApp();
111
112 if (portletApp.isWARFile()) {
113 PortletBag portletBag = PortletBagPool.get(
114 portlet.getRootPortletId());
115
116 rootInvokerPortletInstance = _init(
117 portlet, portletConfig,
118 portletBag.getPortletInstance());
119 }
120 else {
121 rootInvokerPortletInstance = _init(portlet, portletConfig);
122 }
123
124 portletInstances.put(
125 portlet.getRootPortletId(), rootInvokerPortletInstance);
126 }
127 }
128
129 if (instanceable) {
130 if (instanceInvokerPortletInstance == null) {
131 javax.portlet.Portlet portletInstance =
132 rootInvokerPortletInstance.getPortletInstance();
133
134 PortletConfig portletConfig =
135 PortletConfigFactory.create(portlet, servletContext);
136
137 PortletContext portletContext =
138 portletConfig.getPortletContext();
139 boolean facesPortlet =
140 rootInvokerPortletInstance.isFacesPortlet();
141 boolean strutsPortlet =
142 rootInvokerPortletInstance.isStrutsPortlet();
143 boolean strutsBridgePortlet =
144 rootInvokerPortletInstance.isStrutsBridgePortlet();
145
146 instanceInvokerPortletInstance =
147 _internalInvokerPortletPrototype.create(
148 portlet, portletInstance, portletConfig, portletContext,
149 facesPortlet, strutsPortlet, strutsBridgePortlet);
150
151 portletInstances.put(
152 portlet.getPortletId(), instanceInvokerPortletInstance);
153 }
154 }
155 else {
156 if (rootInvokerPortletInstance != null) {
157 instanceInvokerPortletInstance = rootInvokerPortletInstance;
158 }
159 }
160
161 return instanceInvokerPortletInstance;
162 }
163
164 private void _destroy(Portlet portlet) {
165 Map<String, InvokerPortlet> portletInstances = _pool.get(
166 portlet.getRootPortletId());
167
168 if (portletInstances != null) {
169 Iterator<Map.Entry<String, InvokerPortlet>> itr =
170 portletInstances.entrySet().iterator();
171
172 while (itr.hasNext()) {
173 Map.Entry<String, InvokerPortlet> entry = itr.next();
174
175 String portletId = entry.getKey();
176 InvokerPortlet invokerPortletInstance = entry.getValue();
177
178 if (PortletConstants.getInstanceId(portletId) == null) {
179 invokerPortletInstance.destroy();
180
181 break;
182 }
183 }
184 }
185
186 _pool.remove(portlet.getRootPortletId());
187
188 PortletApp portletApp = portlet.getPortletApp();
189
190 if (portletApp.isWARFile()) {
191 PortletBag portletBag = PortletBagPool.get(
192 portlet.getRootPortletId());
193
194 if (portletBag != null) {
195 portletBag.setPortletInstance(null);
196 }
197 }
198
199 PortletConfigFactory.destroy(portlet);
200 PortletContextFactory.destroy(portlet);
201
202 PortletLocalServiceUtil.destroyPortlet(portlet);
203 }
204
205 private InvokerPortlet _init(Portlet portlet, PortletConfig portletConfig)
206 throws PortletException {
207
208 return _init(portlet, portletConfig, null);
209 }
210
211 private InvokerPortlet _init(
212 Portlet portlet, PortletConfig portletConfig,
213 javax.portlet.Portlet portletInstance)
214 throws PortletException {
215
216 InvokerPortlet invokerPortlet = null;
217
218 try {
219 if (portletInstance == null) {
220 portletInstance =
221 (javax.portlet.Portlet)Class.forName(
222 portlet.getPortletClass()).newInstance();
223 }
224
225 PortletContext portletContext = portletConfig.getPortletContext();
226
227 invokerPortlet = _internalInvokerPortletPrototype.create(
228 portlet, portletInstance, portletContext);
229
230 invokerPortlet.init(portletConfig);
231 }
232 catch (ClassNotFoundException cnofe) {
233 throw new UnavailableException(cnofe.getMessage());
234 }
235 catch (InstantiationException ie) {
236 throw new UnavailableException(ie.getMessage());
237 }
238 catch (IllegalAccessException iae) {
239 throw new UnavailableException(iae.getMessage());
240 }
241
242 return invokerPortlet;
243 }
244
245 private static PortletInstanceFactory _instance =
246 new PortletInstanceFactory();
247
248 private static InvokerPortlet _internalInvokerPortletPrototype;
249
250 private Map<String, Map<String, InvokerPortlet>> _pool;
251
252 }