View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.portals.bridges.php;
    18
    19  import java.io.IOException;
    20  import java.security.Principal;
    21  import java.util.Enumeration;
    22
    23  import javax.portlet.ActionRequest;
    24  import javax.portlet.ActionResponse;
    25  import javax.portlet.GenericPortlet;
    26  import javax.portlet.PortletConfig;
    27  import javax.portlet.PortletContext;
    28  import javax.portlet.PortletException;
    29  import javax.portlet.PortletSession;
    30  import javax.portlet.PortletURL;
    31  import javax.portlet.RenderRequest;
    32  import javax.portlet.RenderResponse;
    33  import javax.servlet.ServletException;
    34  import javax.servlet.http.HttpServletRequest;
    35  import javax.servlet.http.HttpServletResponse;
    36  import org.apache.commons.logging.Log;
    37  import org.apache.commons.logging.LogFactory;
    38  import org.apache.portals.bridges.common.ScriptPostProcess;
    39  import org.apache.portals.bridges.common.ServletContextProvider;
    40  import org.apache.portals.bridges.php.PHPParameters;
    41
    42  /***
    43   * This portlet is executes a PHP application in a portlet.
    44   *
    45   * @author <a href="mailto:rogerrut@apache.org">Roger Ruttimann</a>
    46   * @version $Id: PHPApplicationPortlet.java 545680 2007-06-09 01:48:26Z ate $
    47   */
    48
    49  public class PHPApplicationPortlet extends GenericPortlet {
    50
    51  	/***
    52  	 * INIT parameters required by the PHP Portlet:application and ServletContextProvider
    53  	 *
    54       * Name of class implementing {@link PHPServletContextProvider}
    55       */
    56      public static final String PARAM_SERVLET_CONTEXT_PROVIDER = "ServletContextProvider";
    57
    58
    59  	/***
    60  	 * Start page for this portlet it must be the path to the script (e.g hosts/index.php)
    61  	 */
    62  	public static final String START_PAGE	=	"StartPage";
    63
    64
    65      // Local variables
    66
    67  	private ServletContextProvider servletContextProvider;
    68      private static final Log log = LogFactory.getLog(PHPApplicationPortlet.class);
    69
    70      // Servlet INFO needed for portlet
    71
    72      ServletConfigImpl servletConfig = null;
    73
    74      // PHP engine
    75      com.itgroundwork.portlet.php.servlet phpServletImpl = null;
    76
    77       // INIT Parameters
    78      private String startPage = null;
    79
    80      // caching status
    81      private boolean bUseCachedParameters = false;
    82      private String lastContextPath = null;
    83      private String lastQuery = null;
    84      private String lastURI = null;
    85
    86      //ID to identify portlet
    87      private String portletID = null;
    88
    89      public void init(PortletConfig config) throws PortletException
    90      {
    91          super.init(config);
    92
    93          //Get the INIT PARAMETERS for this portlet. If the values are missing
    94          // throw an exception
    95          startPage											=	config.getInitParameter(START_PAGE);
    96          String contextProviderClassName	=	config.getInitParameter(PARAM_SERVLET_CONTEXT_PROVIDER);
    97
    98          if (startPage == null)
    99              throw new PortletException("Portlet " + config.getPortletName()
    100                     + " is incorrectly configured. Init parameter "
    101                     + START_PAGE + " not specified");
    102
    103         if (contextProviderClassName == null)
    104             throw new PortletException("Portlet " + config.getPortletName()
    105                     + " is incorrectly configured. Init parameter "
    106                     + PARAM_SERVLET_CONTEXT_PROVIDER + " not specified");
    107
    108
    109         if (contextProviderClassName != null)
    110         {
    111             try
    112             {
    113                 Class clazz = Class.forName(contextProviderClassName);
    114                 if (clazz != null)
    115                 {
    116                     Object obj = clazz.newInstance();
    117                     if (ServletContextProvider.class.isInstance(obj))
    118                         servletContextProvider = (ServletContextProvider) obj;
    119                     else
    120                         throw new PortletException("class not found");
    121                 }
    122             } catch (Exception e)
    123             {
    124                 if (e instanceof PortletException)
    125                     throw (PortletException) e;
    126                 e.printStackTrace();
    127                 throw new PortletException("Cannot load", e);
    128             }
    129         }
    130         // Initialize config
    131         servletConfig = new ServletConfigImpl(config, servletContextProvider.getServletContext(this));
    132      }
    133
    134     /***
    135      * processAction()
    136      * Checks action initiated by the php portlet (invoking other php scripts)
    137      * @param actionRequest
    138      * @param actionResponse
    139      * @throws PortletException
    140      * @throws IOException
    141      */
    142     public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException
    143 	{
    144     	String phpParameter = actionRequest.getParameter(PHPParameters.ACTION_PARAMETER_PHP);
    145      	/*
    146     	 * If the phpParameter is not empty create a PHPParameters object and attach it to the session
    147     	 */
    148     	if ( phpParameter != null && phpParameter.length() > 0)
    149     	{
    150     		// Perl Parameter Object
    151     		PHPParameters phpScript = new PHPParameters();
    152
    153     		// Separate the values before and after the Query Mark ?
    154     		int ixQuery = phpParameter.indexOf('?');
    155     		if ( ixQuery != -1)
    156     		{
    157     			phpScript.setScriptName(phpParameter.substring(0,ixQuery));
    158
    159     			String queryArguments = phpParameter.substring(ixQuery+1);
    160     			System.out.println("ProcessRequest -- Script " + phpParameter.substring(0,ixQuery) + " Query string " + queryArguments);
    161
    162     			int ixQuerySeparator = queryArguments.indexOf('&');
    163     			while ( ixQuerySeparator != -1)
    164     			{
    165     				phpScript.addQueryArgument(queryArguments.substring(0, ixQuerySeparator));
    166     				queryArguments = queryArguments.substring(ixQuerySeparator+1);
    167     				ixQuerySeparator = queryArguments.indexOf('&');
    168     			}
    169
    170     			phpScript.addQueryArgument(queryArguments);
    171
    172     			// Add the PerlParameters to the session
    173     			actionRequest.getPortletSession().setAttribute(PHPParameters.PHP_PARAMETER, phpScript, PortletSession.APPLICATION_SCOPE);
    174     		}
    175     		else
    176     		{
    177     			// No query string just the script name
    178     			phpScript.setScriptName(phpParameter);
    179
    180     			// Get all the parameters from the request and add them as query arguments
    181     			Enumeration names = actionRequest.getParameterNames();
    182     			String name, value;
    183     			while (names.hasMoreElements())
    184     			{
    185     				name = (String)names.nextElement();
    186     				// ACTION_PARAMETER_PHP already processed just ignore it
    187     				if (name.compareToIgnoreCase(PHPParameters.ACTION_PARAMETER_PHP) != 0)
    188     				{
    189     					value = actionRequest.getParameter(name);
    190
    191        					phpScript.addQueryArgument(name + "=" + value);
    192     				}
    193     			}
    194     			// Add the PerlParameters to the session
    195     			actionRequest.getPortletSession().setAttribute(PHPParameters.PHP_PARAMETER, phpScript, PortletSession.APPLICATION_SCOPE);
    196      		}
    197     	}
    198 	}
    199
    200     /***
    201      * doView
    202      * Renders a PHP file in the portlet.
    203      * The script parameters are in a PHPParameters object that is passed in the session
    204      */
    205
    206     public void doView(RenderRequest request, RenderResponse response)
    207     throws PortletException, IOException
    208 	{
    209     	/*
    210     	 *  Extract the PHPParameter object from the session. If this is not provided use the values for startPage and application from the INIT Parameters
    211     	 */
    212     	String	reqQuery;
    213     	String	phpScript;
    214
    215     	PHPParameters phpParam = null;
    216     	try
    217 		{
    218     		phpParam = (PHPParameters)request.getPortletSession().getAttribute(PHPParameters.PHP_PARAMETER, PortletSession.APPLICATION_SCOPE);
    219 		}
    220     	catch (Exception e )
    221 		{
    222     		phpParam = null;
    223 		}
    224
    225     	if (phpParam != null)
    226     	{
    227     		// We got real parameters
    228     		bUseCachedParameters = false;
    229     		reqQuery = phpParam.getQueryString();
    230     		phpScript = phpParam.getScriptName();
    231     	}
    232     	else
    233     	{
    234     		/*
    235     		 * No parameters were send to this page. Either it is the initial invocation (use init param) or
    236     		 * iit was a refresh (use cached arguments)
    237     		 *
    238     		 * Setting the bUseCacheParameters means that nothing was provided from outside
    239     		 */
    240     		bUseCachedParameters = true;
    241     		reqQuery = "";
    242     		phpScript = this.startPage;
    243     	}
    244
    245       	//ServletContext		servletContext	= servletContextProvider.getServletContext(this);
    246     	HttpServletRequest	httpRequest		= servletContextProvider.getHttpServletRequest(this, request);
    247     	HttpServletResponse httpResponse	= servletContextProvider.getHttpServletResponse(this, response);
    248
    249     	//initialize PHP engine
    250     	if ( phpServletImpl == null)
    251     	{
    252     		try
    253 			{
    254     		phpServletImpl = new com.itgroundwork.portlet.php.servlet();
    255     		if (phpServletImpl != null )
    256     			phpServletImpl.init(servletConfig);
    257 			}
    258     		catch(ServletException se)
    259 			{
    260     			httpResponse.getWriter().println("<p><b>Initializationof PHP servlet failed!</b> Error: " + se.getMessage() + "</p>");
    261 			}
    262     	}
    263
    264
    265     	// Make sure we have an user
    266       	String userName = "anon";	//default not logged in
    267     	Principal userPrincipal = request.getUserPrincipal();
    268     	if (userPrincipal != null )
    269     		userName = userPrincipal.getName();
    270
    271         boolean bShowInfoPage = false;
    272         String	cookieValue = null;
    273
    274          // Build the context path
    275         String contextPath =		request.getContextPath();
    276         PortletContext portletApplication = getPortletContext();
    277         String path = portletApplication.getRealPath("/WEB-INF");
    278         String rootContextPath = path + "/";
    279
    280         /*
    281          * At this point we have all the information to run the PHP servlet:
    282          * 		rootContextPath	contains the file path to the PortletApplication root (e.g /home/user/tomcat/webapps/MyApplication/ )
    283          * 		phpScript				php script to execute. Includes the full path to the application (e.g hosts/index.php)
    284          * 		reqQuery				Query arguments passed to the scripts
    285          */
    286
    287         // Run parameters
    288         String runURI, runQuery, runContext;
    289
    290         // First time call or invoked from another portlet
    291         if ( bUseCachedParameters == true)
    292         {
    293         	//If it is the first call create an URI
    294         	if ( lastURI == null || lastURI.length() == 0)
    295         	{
    296         		// Build the URI with the start page and the context
    297         		lastURI = contextPath + "/" + phpScript;
    298         		lastContextPath = rootContextPath + phpScript;
    299         	}
    300
    301         	// Assign run values
    302         	runURI = lastURI;
    303         	runQuery = lastQuery;
    304         	runContext = lastContextPath;
    305         }
    306         else
    307         {
    308 			// New request for this portlet render it for the new content
    309 			String adjURI = contextPath + "/" + phpScript;
    310
    311 			String phpContext = rootContextPath + phpScript;
    312
    313 			// Assign run values
    314         	runURI = adjURI;
    315         	runQuery = reqQuery;
    316         	runContext = phpContext;
    317         }
    318
    319 		// Invoke the PHP servlet and run it
    320 		try
    321 		{
    322 			if (phpServletImpl != null )
    323 			{
    324 				    if (runQuery == null )
    325 				    	runQuery = "";
    326
    327 				    //  Call into the php library.
    328 				    // Cache the page in the servlet and don't write the output to the response since some post processing
    329 				    // is needed before the page can be send back to the client
    330 				    phpServletImpl.setUseInternalPage();
    331
    332 				    // Set the servlet parameters
    333 					phpServletImpl.setAdjustedURI(runURI);
    334 					phpServletImpl.setAuthenticatedUser(userName);
    335 					phpServletImpl.setAdjustedQuery(runQuery);
    336
    337 					// execute the PHP script
    338 					phpServletImpl.service(httpRequest, httpResponse, runContext);
    339
    340 					//Save last executed request info so that we remember when it was last called
    341 					lastQuery = runQuery;
    342 					lastContextPath = runContext;
    343 					lastURI = runURI;
    344
    345 					//PostProcess:
    346 					//	replace all relative links with actions
    347
    348 					//Any HREFs and Form actions should be extended with the ActionURL
    349 					PortletURL actionURL = response.createActionURL();
    350
    351 					// Get the buffered page from the PHP servlet
    352 					StringBuffer page = phpServletImpl.getSourcePage();
    353
    354 					// Call into the PostProcess object which is the same for PERL and other script engine
    355 					// supported in the future.
    356 					ScriptPostProcess processor = new ScriptPostProcess();
    357 					processor.setInitalPage(page);
    358 					processor.postProcessPage(actionURL, PHPParameters.ACTION_PARAMETER_PHP);
    359 					String finalPage = processor.getFinalizedPage();
    360
    361 			        //Write the page to the HttpResponse
    362 					httpResponse.getWriter().println(finalPage);
    363 			}
    364 			else
    365 			{
    366 				httpResponse.getWriter().println("<br/><b>Error in PHP servlet. Couldn't create instance of com.itgroundwork.portlet.php.servlet. Make sure the jar is included in the same app as the portas-bridges-php jar file</b>" );
    367 			}
    368 		}
    369 		catch( ServletException se)
    370 		{
    371 			httpResponse.getWriter().println("<P><B>Error in PHP servlet.Servlet Exception: " + se.getMessage() + "</B>RunQuery=" + runQuery+ " RunContext=" + runContext + " RunURI=" + runURI + " </P><BR>");
    372 			throw new PortletException(se);
    373 		}
    374 		catch (IOException e)
    375 		{
    376 			httpResponse.getWriter().println("<P><B>Error in PHP servlet. IO Exception " + e.getMessage() + "</B>RunQuery=" + runQuery+ " RunContext=" + runContext + "Run URI=" + runURI + "</P><BR>");
    377 		}
    378 	}
    379 }