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