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