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.BufferCacheServletResponse;
020    import com.liferay.portal.kernel.servlet.DynamicServletConfig;
021    import com.liferay.portal.kernel.servlet.PortletServletObjectsFactory;
022    import com.liferay.portal.kernel.servlet.ServletObjectsFactory;
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    
134                    String phpURI = actionRequest.getParameter(_PHP_URI_PARAM);
135    
136                    if (phpURI != null) {
137                            actionResponse.setRenderParameter(_PHP_URI_PARAM, phpURI);
138                    }
139            }
140    
141            protected synchronized void initQuercus(ServletConfig servletConfig)
142                    throws PortletException {
143    
144                    if (quercusServlet == null) {
145                            try {
146                                    quercusServlet = (HttpServlet)Class.forName(
147                                            _QUERCUS_SERVLET).newInstance();
148    
149                                    Map<String, String> params = new HashMap<String, String>();
150    
151                                    Enumeration<String> enu = servletConfig.getInitParameterNames();
152    
153                                    while (enu.hasMoreElements()) {
154                                            String name = enu.nextElement();
155    
156                                            if (!name.equals("portlet-class")) {
157                                                    params.put(name, servletConfig.getInitParameter(name));
158                                            }
159                                    }
160    
161                                    servletConfig = new DynamicServletConfig(servletConfig, params);
162    
163                                    quercusServlet.init(servletConfig);
164                            }
165                            catch (Exception e) {
166                                    throw new PortletException(e);
167                            }
168                    }
169            }
170    
171            protected void processPHP(
172                    String phpURI, RenderRequest renderRequest,
173                    RenderResponse renderResponse) {
174    
175                    try {
176                            ServletConfig servletConfig =
177                                    servletObjectsFactory.getServletConfig(
178                                            getPortletConfig(), renderRequest);
179    
180                            initQuercus(servletConfig);
181    
182                            HttpServletRequest request =
183                                    servletObjectsFactory.getServletRequest(renderRequest);
184                            HttpServletResponse response =
185                                    servletObjectsFactory.getServletResponse(
186                                            renderRequest, renderResponse);
187    
188                            PHPServletRequest phpRequest = new PHPServletRequest(
189                                    request, servletConfig, renderRequest, renderResponse,
190                                    getPortletConfig(), phpURI, addPortletParams);
191    
192                            BufferCacheServletResponse bufferCacheServletResponse =
193                                    new BufferCacheServletResponse(response);
194    
195                            quercusServlet.service(phpRequest, bufferCacheServletResponse);
196    
197                            String result = bufferCacheServletResponse.getString();
198    
199                            String contentType = bufferCacheServletResponse.getContentType();
200    
201                            if (contentType.startsWith("text/")) {
202                                    result = rewriteURLs(result, renderResponse.createRenderURL());
203                            }
204    
205                            renderResponse.setContentType(contentType);
206    
207                            PrintWriter writer = renderResponse.getWriter();
208    
209                            writer.write(result.toCharArray());
210                    }
211                    catch (Exception e) {
212                            _log.error("Error processing PHP", e);
213                    }
214            }
215    
216            protected String rewriteURLs(String page, PortletURL portletURL) {
217                    ScriptPostProcess scriptPostProcess = new ScriptPostProcess();
218    
219                    scriptPostProcess.setInitalPage(new StringBundler(page));
220    
221                    scriptPostProcess.postProcessPage(portletURL, _PHP_URI_PARAM);
222    
223                    return scriptPostProcess.getFinalizedPage();
224            }
225    
226            protected boolean addPortletParams;
227            protected String editUri;
228            protected String helpUri;
229            protected HttpServlet quercusServlet;
230            protected ServletObjectsFactory servletObjectsFactory;
231            protected String viewUri;
232    
233            private static final String _PHP_URI_PARAM = "phpURI";
234    
235            private static final String _QUERCUS_SERVLET =
236                    "com.caucho.quercus.servlet.QuercusServlet";
237    
238            private static Log _log = LogFactoryUtil.getLog(PHPPortlet.class);
239    
240    }