001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.model.Portlet;
020    import com.liferay.portal.model.PortletApp;
021    import com.liferay.portal.model.PortletConstants;
022    import com.liferay.portal.service.PortletLocalServiceUtil;
023    import com.liferay.portal.util.ClassLoaderUtil;
024    
025    import java.util.Map;
026    import java.util.concurrent.ConcurrentHashMap;
027    
028    import javax.portlet.PortletConfig;
029    import javax.portlet.PortletContext;
030    import javax.portlet.PortletException;
031    
032    import javax.servlet.ServletContext;
033    
034    /**
035     * @author Brian Wing Shun Chan
036     * @author Shuyang Zhou
037     */
038    public class PortletInstanceFactoryImpl implements PortletInstanceFactory {
039    
040            public PortletInstanceFactoryImpl() {
041                    _pool = new ConcurrentHashMap<String, Map<String, InvokerPortlet>>();
042            }
043    
044            public void clear(Portlet portlet) {
045                    clear(portlet, true);
046            }
047    
048            public void clear(Portlet portlet, boolean resetRemotePortletBag) {
049                    String rootPortletId = portlet.getRootPortletId();
050    
051                    Map<String, InvokerPortlet> portletInstances = _pool.remove(
052                            rootPortletId);
053    
054                    if (portletInstances != null) {
055                            InvokerPortlet rootInvokerPortletInstance = portletInstances.remove(
056                                    rootPortletId);
057    
058                            if (rootInvokerPortletInstance != null) {
059                                    rootInvokerPortletInstance.destroy();
060                            }
061    
062                            portletInstances.clear();
063                    }
064    
065                    PortletApp portletApp = portlet.getPortletApp();
066    
067                    if (resetRemotePortletBag && portletApp.isWARFile()) {
068                            PortletBagPool.remove(rootPortletId);
069                    }
070            }
071    
072            public InvokerPortlet create(Portlet portlet, ServletContext servletContext)
073                    throws PortletException {
074    
075                    boolean instanceable = false;
076    
077                    boolean deployed = !portlet.isUndeployedPortlet();
078    
079                    if (portlet.isInstanceable() && deployed &&
080                            PortletConstants.hasInstanceId(portlet.getPortletId())) {
081    
082                            instanceable = true;
083                    }
084    
085                    String rootPortletId = portlet.getRootPortletId();
086    
087                    InvokerPortlet rootInvokerPortletInstance = null;
088    
089                    Map<String, InvokerPortlet> portletInstances = null;
090    
091                    if (deployed) {
092                            portletInstances = _pool.get(rootPortletId);
093    
094                            if (portletInstances == null) {
095                                    portletInstances =
096                                            new ConcurrentHashMap<String, InvokerPortlet>();
097    
098                                    _pool.put(rootPortletId, portletInstances);
099                            }
100                            else {
101                                    if (instanceable) {
102                                            InvokerPortlet instanceInvokerPortletInstance =
103                                                    portletInstances.get(portlet.getPortletId());
104    
105                                            if (instanceInvokerPortletInstance != null) {
106                                                    return instanceInvokerPortletInstance;
107                                            }
108                                    }
109    
110                                    rootInvokerPortletInstance = portletInstances.get(
111                                            rootPortletId);
112                            }
113                    }
114    
115                    if (rootInvokerPortletInstance == null) {
116                            PortletBag portletBag = PortletBagPool.get(rootPortletId);
117    
118                            // Portlet bag should never be null unless the portlet has been
119                            // undeployed
120    
121                            if (portletBag == null) {
122                                    PortletBagFactory portletBagFactory = new PortletBagFactory();
123    
124                                    portletBagFactory.setClassLoader(
125                                            ClassLoaderUtil.getPortalClassLoader());
126                                    portletBagFactory.setServletContext(servletContext);
127                                    portletBagFactory.setWARFile(false);
128    
129                                    try {
130                                            portletBag = portletBagFactory.create(portlet);
131                                    }
132                                    catch (Exception e) {
133                                            throw new PortletException(e);
134                                    }
135                            }
136    
137                            PortletConfig portletConfig = PortletConfigFactoryUtil.create(
138                                    portlet, servletContext);
139    
140                            rootInvokerPortletInstance = init(
141                                    portlet, portletConfig, portletBag.getPortletInstance());
142    
143                            if (deployed) {
144                                    portletInstances.put(rootPortletId, rootInvokerPortletInstance);
145                            }
146                    }
147    
148                    if (!instanceable) {
149                            return rootInvokerPortletInstance;
150                    }
151    
152                    javax.portlet.Portlet portletInstance =
153                            rootInvokerPortletInstance.getPortletInstance();
154    
155                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
156                            portlet, servletContext);
157    
158                    PortletContext portletContext = portletConfig.getPortletContext();
159                    boolean checkAuthToken = rootInvokerPortletInstance.isCheckAuthToken();
160                    boolean facesPortlet = rootInvokerPortletInstance.isFacesPortlet();
161                    boolean strutsPortlet = rootInvokerPortletInstance.isStrutsPortlet();
162                    boolean strutsBridgePortlet =
163                            rootInvokerPortletInstance.isStrutsBridgePortlet();
164    
165                    InvokerPortlet instanceInvokerPortletInstance =
166                            _invokerPortletFactory.create(
167                                    portlet, portletInstance, portletConfig, portletContext,
168                                    checkAuthToken, facesPortlet, strutsPortlet,
169                                    strutsBridgePortlet);
170    
171                    if (deployed) {
172                            portletInstances.put(
173                                    portlet.getPortletId(), instanceInvokerPortletInstance);
174                    }
175    
176                    return instanceInvokerPortletInstance;
177            }
178    
179            public void delete(Portlet portlet) {
180                    if (PortletConstants.hasInstanceId(portlet.getPortletId())) {
181                            Map<String, InvokerPortlet> portletInstances = _pool.get(
182                                    portlet.getRootPortletId());
183    
184                            if (portletInstances != null) {
185                                    portletInstances.remove(portlet.getPortletId());
186                            }
187                    }
188            }
189    
190            public void destroy() {
191    
192                    // LPS-10473
193    
194            }
195    
196            public void destroy(Portlet portlet) {
197                    clear(portlet);
198    
199                    PortletConfigFactoryUtil.destroy(portlet);
200                    PortletContextFactory.destroy(portlet);
201    
202                    PortletLocalServiceUtil.destroyPortlet(portlet);
203            }
204    
205            public void setInvokerPortletFactory(
206                    InvokerPortletFactory invokerPortletFactory) {
207    
208                    _invokerPortletFactory = invokerPortletFactory;
209            }
210    
211            protected InvokerPortlet init(
212                            Portlet portlet, PortletConfig portletConfig,
213                            javax.portlet.Portlet portletInstance)
214                    throws PortletException {
215    
216                    PortletContext portletContext = portletConfig.getPortletContext();
217    
218                    InvokerPortlet invokerPortlet = _invokerPortletFactory.create(
219                            portlet, portletInstance, portletContext);
220    
221                    invokerPortlet.init(portletConfig);
222    
223                    return invokerPortlet;
224            }
225    
226            private InvokerPortletFactory _invokerPortletFactory;
227            private Map<String, Map<String, InvokerPortlet>> _pool;
228    
229    }