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.util.bridges.php;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.servlet.DynamicServletConfig;
020    import com.liferay.portal.kernel.servlet.PortletServletObjectsFactory;
021    import com.liferay.portal.kernel.servlet.ServletObjectsFactory;
022    import com.liferay.portal.kernel.servlet.StringServletResponse;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.util.bridges.common.ScriptPostProcess;
026    
027    import java.io.IOException;
028    import java.io.PrintWriter;
029    
030    import java.util.Enumeration;
031    import java.util.HashMap;
032    import java.util.Map;
033    
034    import javax.portlet.ActionRequest;
035    import javax.portlet.ActionResponse;
036    import javax.portlet.GenericPortlet;
037    import javax.portlet.PortletConfig;
038    import javax.portlet.PortletException;
039    import javax.portlet.PortletURL;
040    import javax.portlet.RenderRequest;
041    import javax.portlet.RenderResponse;
042    
043    import javax.servlet.ServletConfig;
044    import javax.servlet.http.HttpServlet;
045    import javax.servlet.http.HttpServletRequest;
046    import javax.servlet.http.HttpServletResponse;
047    
048    /**
049     * @author Jorge Ferrer
050     */
051    public class PHPPortlet extends GenericPortlet {
052    
053            @Override
054            public void destroy() {
055                    if (quercusServlet != null) {
056                            quercusServlet.destroy();
057                    }
058            }
059    
060            @Override
061            public void doDispatch(
062                            RenderRequest renderRequest, RenderResponse renderResponse)
063                    throws IOException, PortletException {
064    
065                    String phpUri = renderRequest.getParameter(_PHP_URI_PARAM);
066    
067                    if (phpUri != null) {
068                            processPHP(phpUri, renderRequest, renderResponse);
069                    }
070                    else {
071                            super.doDispatch(renderRequest, renderResponse);
072                    }
073            }
074    
075            @Override
076            public void doEdit(
077                            RenderRequest renderRequest, RenderResponse renderResponse)
078                    throws IOException, PortletException {
079    
080                    if (renderRequest.getPreferences() == null) {
081                            super.doEdit(renderRequest, renderResponse);
082                    }
083                    else {
084                            processPHP(editUri, renderRequest, renderResponse);
085                    }
086            }
087    
088            @Override
089            public void doHelp(
090                    RenderRequest renderRequest, RenderResponse renderResponse) {
091    
092                    processPHP(helpUri, renderRequest, renderResponse);
093            }
094    
095            @Override
096            public void doView(
097                    RenderRequest renderRequest, RenderResponse renderResponse) {
098    
099                    processPHP(viewUri, renderRequest, renderResponse);
100            }
101    
102            @Override
103            public void init(PortletConfig portletConfig) throws PortletException {
104                    super.init(portletConfig);
105    
106                    editUri = getInitParameter("edit-uri");
107                    helpUri = getInitParameter("help-uri");
108                    viewUri = getInitParameter("view-uri");
109    
110                    addPortletParams = GetterUtil.getBoolean(
111                            portletConfig.getInitParameter("add-portlet-params"), true);
112    
113                    String servletObjectsFactoryName = GetterUtil.getString(
114                            getInitParameter("servlet-objects-factory"),
115                            PortletServletObjectsFactory.class.getName());
116    
117                    try {
118                            Class<?> servletObjectsFactoryClass = Class.forName(
119                                    servletObjectsFactoryName);
120    
121                            servletObjectsFactory =
122                                    (ServletObjectsFactory)servletObjectsFactoryClass.newInstance();
123                    }
124                    catch (Exception e) {
125                            throw new PortletException(
126                                    "Unable to instantiate factory" + servletObjectsFactoryName, e);
127                    }
128            }
129    
130            @Override
131            public void processAction(
132                            ActionRequest actionRequest, ActionResponse actionResponse) {
133                    String phpURI = actionRequest.getParameter(_PHP_URI_PARAM);
134    
135                    if (phpURI != null) {
136                            actionResponse.setRenderParameter(_PHP_URI_PARAM, phpURI);
137                    }
138            }
139    
140            protected synchronized void initQuercus(ServletConfig servletConfig)
141                    throws PortletException {
142    
143                    if (quercusServlet == null) {
144                            try {
145                                    quercusServlet = (HttpServlet)Class.forName(
146                                            _QUERCUS_SERVLET).newInstance();
147    
148                                    Map<String, String> params = new HashMap<String, String>();
149    
150                                    Enumeration<String> enu = servletConfig.getInitParameterNames();
151    
152                                    while (enu.hasMoreElements()) {
153                                            String name = enu.nextElement();
154    
155                                            if (!name.equals("portlet-class")) {
156                                                    params.put(name, servletConfig.getInitParameter(name));
157                                            }
158                                    }
159    
160                                    servletConfig = new DynamicServletConfig(servletConfig, params);
161    
162                                    quercusServlet.init(servletConfig);
163                            }
164                            catch (Exception e) {
165                                    throw new PortletException(e);
166                            }
167                    }
168            }
169    
170            protected void processPHP(
171                    String phpURI, RenderRequest renderRequest,
172                    RenderResponse renderResponse) {
173    
174                    try {
175                            ServletConfig servletConfig =
176                                    servletObjectsFactory.getServletConfig(
177                                            getPortletConfig(), renderRequest);
178    
179                            initQuercus(servletConfig);
180    
181                            HttpServletRequest request =
182                                    servletObjectsFactory.getServletRequest(renderRequest);
183                            HttpServletResponse response =
184                                    servletObjectsFactory.getServletResponse(
185                                            renderRequest, renderResponse);
186    
187                            PHPServletRequest phpRequest = new PHPServletRequest(
188                                    request, servletConfig, renderRequest, renderResponse,
189                                    getPortletConfig(), phpURI, addPortletParams);
190    
191                            StringServletResponse stringResponse = new StringServletResponse(
192                                    response);
193    
194                            quercusServlet.service(phpRequest, stringResponse);
195    
196                            String result = stringResponse.getString();
197    
198                            if (stringResponse.getContentType().startsWith("text/")) {
199                                    result = rewriteURLs(result, renderResponse.createRenderURL());
200                            }
201    
202                            renderResponse.setContentType(stringResponse.getContentType());
203    
204                            PrintWriter writer = renderResponse.getWriter();
205    
206                            writer.write(result.toCharArray());
207                    }
208                    catch (Exception e) {
209                            _log.error("Error processing PHP", e);
210                    }
211            }
212    
213            protected String rewriteURLs(String page, PortletURL portletURL) {
214                    ScriptPostProcess scriptPostProcess = new ScriptPostProcess();
215    
216                    scriptPostProcess.setInitalPage(new StringBundler(page));
217    
218                    scriptPostProcess.postProcessPage(portletURL, _PHP_URI_PARAM);
219    
220                    return scriptPostProcess.getFinalizedPage();
221            }
222    
223            protected boolean addPortletParams;
224            protected String editUri;
225            protected String helpUri;
226            protected HttpServlet quercusServlet;
227            protected ServletObjectsFactory servletObjectsFactory;
228            protected String viewUri;
229    
230            private static final String _PHP_URI_PARAM = "phpURI";
231    
232            private static final String _QUERCUS_SERVLET =
233                    "com.caucho.quercus.servlet.QuercusServlet";
234    
235            private static Log _log = LogFactoryUtil.getLog(PHPPortlet.class);
236    
237    }