001    /**
002     * Copyright (c) 2000-present 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.portal.tools.deploy;
016    
017    import com.liferay.portal.kernel.plugin.PluginPackage;
018    import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
019    import com.liferay.portal.kernel.util.FileUtil;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.PropsKeys;
022    import com.liferay.portal.kernel.util.ServerDetector;
023    import com.liferay.portal.kernel.util.StringBundler;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.kernel.xml.Document;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
029    import com.liferay.portal.model.Plugin;
030    import com.liferay.portal.tools.ToolDependencies;
031    import com.liferay.portal.util.Portal;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.PrefsPropsUtil;
034    import com.liferay.portal.util.PropsValues;
035    
036    import java.io.File;
037    
038    import java.util.ArrayList;
039    import java.util.List;
040    
041    /**
042     * @author Brian Wing Shun Chan
043     * @author Brian Myunghun Kim
044     */
045    public class PortletDeployer extends BaseDeployer {
046    
047            public static final String JSF_STANDARD =
048                    "javax.portlet.faces.GenericFacesPortlet";
049    
050            public static void main(String[] args) {
051                    ToolDependencies.wireDeployers();
052    
053                    List<String> wars = new ArrayList<>();
054                    List<String> jars = new ArrayList<>();
055    
056                    for (String arg : args) {
057                            if (arg.endsWith(".war")) {
058                                    wars.add(arg);
059                            }
060                            else if (arg.endsWith(".jar")) {
061                                    jars.add(arg);
062                            }
063                    }
064    
065                    new PortletDeployer(wars, jars);
066            }
067    
068            public PortletDeployer() {
069            }
070    
071            public PortletDeployer(List<String> wars, List<String> jars) {
072                    super(wars, jars);
073            }
074    
075            @Override
076            public void checkArguments() {
077                    super.checkArguments();
078    
079                    if (Validator.isNull(portletTaglibDTD)) {
080                            throw new IllegalArgumentException(
081                                    "The system property deployer.portlet.taglib.dtd is not set");
082                    }
083            }
084    
085            @Override
086            public void copyXmls(
087                            File srcFile, String displayName, PluginPackage pluginPackage)
088                    throws Exception {
089    
090                    super.copyXmls(srcFile, displayName, pluginPackage);
091    
092                    copyTomcatContextXml(srcFile);
093    
094                    copyDependencyXml(
095                            "_servlet_context_include.jsp", srcFile + "/WEB-INF/jsp");
096            }
097    
098            @Override
099            public String getExtraContent(
100                            double webXmlVersion, File srcFile, String displayName)
101                    throws Exception {
102    
103                    StringBundler sb = new StringBundler();
104    
105                    if (ServerDetector.isWebSphere()) {
106                            sb.append("<context-param>");
107                            sb.append("<param-name>");
108                            sb.append("com.ibm.websphere.portletcontainer.");
109                            sb.append("PortletDeploymentEnabled");
110                            sb.append("</param-name>");
111                            sb.append("<param-value>false</param-value>");
112                            sb.append("</context-param>");
113                    }
114    
115                    File portletXML = new File(
116                            srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD);
117                    File webXML = new File(srcFile + "/WEB-INF/web.xml");
118    
119                    updatePortletXML(portletXML);
120    
121                    sb.append(getServletContent(portletXML, webXML));
122    
123                    String extraContent = super.getExtraContent(
124                            webXmlVersion, srcFile, displayName);
125    
126                    sb.append(extraContent);
127    
128                    return sb.toString();
129            }
130    
131            @Override
132            public String getExtraFiltersContent(double webXmlVersion, File srcFile)
133                    throws Exception {
134    
135                    StringBundler sb = new StringBundler(4);
136    
137                    String extraFiltersContent = super.getExtraFiltersContent(
138                            webXmlVersion, srcFile);
139    
140                    sb.append(extraFiltersContent);
141    
142                    // Ignore filters
143    
144                    sb.append(getIgnoreFiltersContent(srcFile));
145    
146                    // Speed filters
147    
148                    sb.append(getSpeedFiltersContent(srcFile));
149    
150                    // Servlet context include filters
151    
152                    sb.append(
153                            getServletContextIncludeFiltersContent(webXmlVersion, srcFile));
154    
155                    return sb.toString();
156            }
157    
158            @Override
159            public String getPluginType() {
160                    return Plugin.TYPE_PORTLET;
161            }
162    
163            public String getServletContent(File portletXML, File webXML)
164                    throws Exception {
165    
166                    StringBundler sb = new StringBundler();
167    
168                    Document document = UnsecureSAXReaderUtil.read(portletXML);
169    
170                    Element rootElement = document.getRootElement();
171    
172                    List<Element> portletElements = rootElement.elements("portlet");
173    
174                    for (Element portletElement : portletElements) {
175                            String portletName = PortalUtil.getJsSafePortletId(
176                                    portletElement.elementText("portlet-name"));
177                            String portletClassName = portletElement.elementText(
178                                    "portlet-class");
179    
180                            String servletName = portletName + " Servlet";
181    
182                            sb.append("<servlet>");
183                            sb.append("<servlet-name>");
184                            sb.append(servletName);
185                            sb.append("</servlet-name>");
186                            sb.append("<servlet-class>");
187                            sb.append("com.liferay.portal.kernel.servlet.PortletServlet");
188                            sb.append("</servlet-class>");
189                            sb.append("<init-param>");
190                            sb.append("<param-name>portlet-class</param-name>");
191                            sb.append("<param-value>");
192                            sb.append(portletClassName);
193                            sb.append("</param-value>");
194                            sb.append("</init-param>");
195                            sb.append("<load-on-startup>1</load-on-startup>");
196                            sb.append("</servlet>");
197    
198                            sb.append("<servlet-mapping>");
199                            sb.append("<servlet-name>");
200                            sb.append(servletName);
201                            sb.append("</servlet-name>");
202                            sb.append("<url-pattern>/");
203                            sb.append(portletName);
204                            sb.append("/*</url-pattern>");
205                            sb.append("</servlet-mapping>");
206                    }
207    
208                    return sb.toString();
209            }
210    
211            @Override
212            public void updateDeployDirectory(File srcFile) throws Exception {
213                    boolean customPortletXML = false;
214    
215                    try {
216                            customPortletXML = PrefsPropsUtil.getBoolean(
217                                    PropsKeys.AUTO_DEPLOY_CUSTOM_PORTLET_XML,
218                                    PropsValues.AUTO_DEPLOY_CUSTOM_PORTLET_XML);
219                    }
220                    catch (Exception e) {
221    
222                            // This will only happen when running the deploy tool in Ant in the
223                            // classical way where the WAR file is actually massaged and
224                            // packaged.
225    
226                            customPortletXML = PropsValues.AUTO_DEPLOY_CUSTOM_PORTLET_XML;
227                    }
228    
229                    customPortletXML = GetterUtil.getBoolean(
230                            System.getProperty("deployer.custom.portlet.xml"),
231                            customPortletXML);
232    
233                    if (!customPortletXML) {
234                            return;
235                    }
236    
237                    File portletXML = new File(
238                            srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD);
239    
240                    if (portletXML.exists()) {
241                            File portletCustomXML = new File(
242                                    srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM);
243    
244                            if (portletCustomXML.exists()) {
245                                    portletCustomXML.delete();
246                            }
247    
248                            portletXML.renameTo(portletCustomXML);
249                    }
250            }
251    
252            public void updatePortletXML(File portletXML) throws Exception {
253                    if (!portletXML.exists()) {
254                            return;
255                    }
256    
257                    String content = FileUtil.read(portletXML);
258    
259                    content = StringUtil.replace(
260                            content, "com.liferay.util.bridges.jsp.JSPPortlet",
261                            MVCPortlet.class.getName());
262    
263                    FileUtil.write(portletXML, content);
264            }
265    
266    }