001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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 init(PortletConfig portletConfig) throws PortletException {
055                    super.init(portletConfig);
056    
057                    editUri = getInitParameter("edit-uri");
058                    helpUri = getInitParameter("help-uri");
059                    viewUri = getInitParameter("view-uri");
060    
061                    addPortletParams = GetterUtil.getBoolean(
062                            portletConfig.getInitParameter("add-portlet-params"), true);
063    
064                    String servletObjectsFactoryName = GetterUtil.getString(
065                            getInitParameter("servlet-objects-factory"),
066                            PortletServletObjectsFactory.class.getName());
067    
068                    try {
069                            Class<?> servletObjectsFactoryClass = Class.forName(
070                                    servletObjectsFactoryName);
071    
072                            servletObjectsFactory =
073                                    (ServletObjectsFactory)servletObjectsFactoryClass.newInstance();
074                    }
075                    catch (Exception e) {
076                            throw new PortletException(
077                                    "Unable to instantiate factory" + servletObjectsFactoryName, e);
078                    }
079            }
080    
081            @Override
082            public void doDispatch(
083                            RenderRequest renderRequest, RenderResponse renderResponse)
084                    throws IOException, PortletException {
085    
086                    String phpUri = renderRequest.getParameter(_PHP_URI_PARAM);
087    
088                    if (phpUri != null) {
089                            processPHP(phpUri, renderRequest, renderResponse);
090                    }
091                    else {
092                            super.doDispatch(renderRequest, renderResponse);
093                    }
094            }
095    
096            @Override
097            public void doEdit(
098                            RenderRequest renderRequest, RenderResponse renderResponse)
099                    throws IOException, PortletException {
100    
101                    if (renderRequest.getPreferences() == null) {
102                            super.doEdit(renderRequest, renderResponse);
103                    }
104                    else {
105                            processPHP(editUri, renderRequest, renderResponse);
106                    }
107            }
108    
109            @Override
110            public void doHelp(
111                    RenderRequest renderRequest, RenderResponse renderResponse) {
112    
113                    processPHP(helpUri, renderRequest, renderResponse);
114            }
115    
116            @Override
117            public void doView(
118                    RenderRequest renderRequest, RenderResponse renderResponse) {
119    
120                    processPHP(viewUri, renderRequest, renderResponse);
121            }
122    
123            @Override
124            public void processAction(
125                            ActionRequest actionRequest, ActionResponse actionResponse) {
126                    String phpURI = actionRequest.getParameter(_PHP_URI_PARAM);
127    
128                    if (phpURI != null) {
129                            actionResponse.setRenderParameter(_PHP_URI_PARAM, phpURI);
130                    }
131            }
132    
133            @Override
134            public void destroy() {
135                    if (quercusServlet != null) {
136                            quercusServlet.destroy();
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            private static final String _PHP_URI_PARAM = "phpURI";
224    
225            private static final String _QUERCUS_SERVLET =
226                    "com.caucho.quercus.servlet.QuercusServlet";
227    
228            private static Log _log = LogFactoryUtil.getLog(PHPPortlet.class);
229    
230            protected String editUri;
231            protected String helpUri;
232            protected String viewUri;
233            protected boolean addPortletParams;
234            protected ServletObjectsFactory servletObjectsFactory;
235            protected HttpServlet quercusServlet;
236    
237    }