1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet;
24  
25  import com.liferay.portal.model.Portlet;
26  import com.liferay.portal.model.impl.PortletImpl;
27  import com.liferay.portal.service.PortletLocalServiceUtil;
28  import com.liferay.portal.servlet.PortletContextPool;
29  import com.liferay.portal.servlet.PortletContextWrapper;
30  import com.liferay.util.CollectionFactory;
31  
32  import java.util.Iterator;
33  import java.util.Map;
34  
35  import javax.portlet.PortletConfig;
36  import javax.portlet.PortletContext;
37  import javax.portlet.PortletException;
38  import javax.portlet.UnavailableException;
39  
40  import javax.servlet.ServletContext;
41  
42  /**
43   * <a href="PortletInstanceFactory.java.html"><b><i>View Source</i></b></a>
44   *
45   * @author Brian Wing Shun Chan
46   *
47   */
48  public class PortletInstanceFactory {
49  
50      public static CachePortlet create(Portlet portlet, ServletContext ctx)
51          throws PortletException {
52  
53          return _instance._create(portlet, ctx);
54      }
55  
56      public static void destroy(Portlet portlet) {
57          _instance._destroy(portlet);
58      }
59  
60      private PortletInstanceFactory() {
61          _pool = CollectionFactory.getSyncHashMap();
62      }
63  
64      private CachePortlet _create(Portlet portlet, ServletContext ctx)
65          throws PortletException {
66  
67          boolean instanceable = false;
68  
69          if ((portlet.isInstanceable()) &&
70              (PortletImpl.getInstanceId(portlet.getPortletId()) != null)) {
71  
72              instanceable = true;
73          }
74  
75          Map portletInstances = (Map)_pool.get(portlet.getRootPortletId());
76  
77          if (portletInstances == null) {
78              portletInstances = CollectionFactory.getSyncHashMap();
79  
80              _pool.put(portlet.getRootPortletId(), portletInstances);
81          }
82  
83          CachePortlet instanceCachePortletInstance = null;
84  
85          if (instanceable) {
86              instanceCachePortletInstance = (CachePortlet)portletInstances.get(
87                  portlet.getPortletId());
88          }
89  
90          CachePortlet rootCachePortletInstance = null;
91  
92          if (instanceCachePortletInstance == null) {
93              rootCachePortletInstance = (CachePortlet)portletInstances.get(
94                  portlet.getRootPortletId());
95  
96              if (rootCachePortletInstance == null) {
97                  PortletConfig portletConfig =
98                      PortletConfigFactory.create(portlet, ctx);
99  
100                 if (portlet.isWARFile()) {
101                     PortletContextWrapper pcw =
102                         PortletContextPool.get(portlet.getRootPortletId());
103 
104                     rootCachePortletInstance = _init(
105                         portlet, portletConfig, pcw.getPortletInstance());
106                 }
107                 else {
108                     rootCachePortletInstance = _init(portlet, portletConfig);
109                 }
110 
111                 portletInstances.put(
112                     portlet.getRootPortletId(), rootCachePortletInstance);
113             }
114         }
115 
116         if (instanceable) {
117             if (instanceCachePortletInstance == null) {
118                 javax.portlet.Portlet portletInstance =
119                     rootCachePortletInstance.getPortletInstance();
120 
121                 PortletConfig portletConfig =
122                     PortletConfigFactory.create(portlet, ctx);
123 
124                 PortletContext portletCtx = portletConfig.getPortletContext();
125                 Integer expCache = rootCachePortletInstance.getExpCache();
126                 boolean facesPortlet =
127                     rootCachePortletInstance.isFacesPortlet();
128                 boolean strutsPortlet =
129                     rootCachePortletInstance.isStrutsPortlet();
130                 boolean strutsBridgePortlet =
131                     rootCachePortletInstance.isStrutsBridgePortlet();
132 
133                 instanceCachePortletInstance = new CachePortlet(
134                     portletInstance, portletConfig, portletCtx, expCache,
135                     facesPortlet, strutsPortlet, strutsBridgePortlet);
136 
137                 portletInstances.put(
138                     portlet.getPortletId(), instanceCachePortletInstance);
139             }
140         }
141         else {
142             if (rootCachePortletInstance != null) {
143                 instanceCachePortletInstance = rootCachePortletInstance;
144             }
145         }
146 
147         return instanceCachePortletInstance;
148     }
149 
150     private void _destroy(Portlet portlet) {
151         Map portletInstances = (Map)_pool.get(portlet.getRootPortletId());
152 
153         if (portletInstances == null) {
154             return;
155         }
156 
157         Iterator itr = portletInstances.entrySet().iterator();
158 
159         while (itr.hasNext()) {
160             Map.Entry entry = (Map.Entry)itr.next();
161 
162             String portletId = (String)entry.getKey();
163             CachePortlet cachePortletInstance = (CachePortlet)entry.getValue();
164 
165             if (PortletImpl.getInstanceId(portletId) == null) {
166                 cachePortletInstance.destroy();
167 
168                 break;
169             }
170         }
171 
172         _pool.remove(portlet.getRootPortletId());
173 
174         if (portlet.isWARFile()) {
175             PortletContextWrapper pcw =
176                 (PortletContextWrapper)PortletContextPool.get(
177                     portlet.getRootPortletId());
178 
179             pcw.removePortletInstance();
180         }
181 
182         PortletConfigFactory.destroy(portlet);
183         PortletContextFactory.destroy(portlet);
184 
185         PortletLocalServiceUtil.destroyPortlet(portlet);
186     }
187 
188     private CachePortlet _init(Portlet portlet, PortletConfig portletConfig)
189         throws PortletException {
190 
191         return _init(portlet, portletConfig, null);
192     }
193 
194     private CachePortlet _init(
195             Portlet portlet, PortletConfig portletConfig,
196             javax.portlet.Portlet portletInstance)
197         throws PortletException {
198 
199         CachePortlet cachePortlet = null;
200 
201         try {
202             if (portletInstance == null) {
203                 portletInstance = (javax.portlet.Portlet)
204                     Class.forName(portlet.getPortletClass()).newInstance();
205             }
206 
207             cachePortlet = new CachePortlet(
208                 portletInstance, portletConfig.getPortletContext(),
209                 portlet.getExpCache());
210 
211             cachePortlet.init(portletConfig);
212         }
213         catch (ClassNotFoundException cnofe) {
214             throw new UnavailableException(cnofe.getMessage());
215         }
216         catch (InstantiationException ie) {
217             throw new UnavailableException(ie.getMessage());
218         }
219         catch (IllegalAccessException iae) {
220             throw new UnavailableException(iae.getMessage());
221         }
222 
223         return cachePortlet;
224     }
225 
226     private static PortletInstanceFactory _instance =
227         new PortletInstanceFactory();
228 
229     private Map _pool;
230 
231 }