You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2008/04/01 22:11:09 UTC

svn commit: r643550 - in /myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util: ExternalContextUtils.java RequestType.java

Author: sobryan
Date: Tue Apr  1 13:11:06 2008
New Revision: 643550

URL: http://svn.apache.org/viewvc?rev=643550&view=rev
Log:
Added ExternalContextUtils API

Added:
    myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ExternalContextUtils.java
    myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/RequestType.java

Added: myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ExternalContextUtils.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ExternalContextUtils.java?rev=643550&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ExternalContextUtils.java (added)
+++ myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ExternalContextUtils.java Tue Apr  1 13:11:06 2008
@@ -0,0 +1,192 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.commons.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This provides some functionality for determining some things about the
+ * native request object that is not provided by JSF.  This class is useful
+ * for use in places where Portlet API's may or may not be present and can
+ * also provide access to some request-specific items which are not available on
+ * the JSF ExternalContext.  If portlet API's are not present, this class simply 
+ * handles the Servlet Request type.
+ */
+public final class ExternalContextUtils
+{
+	// prevent this from being instantiated
+	private ExternalContextUtils()
+	{
+	}
+
+	/**
+	 * Returns the content length or -1 if the unknown.
+	 *
+	 * @param externalContext
+	 *          the ExternalContext
+	 * @return the length or -1
+	 */
+	public static final int getContentLength(ExternalContext externalContext)
+	{
+		RequestType type = getRequestType(externalContext);
+		
+		if(type.isRequestFromClient())
+		{
+			try
+			{
+				Object request = externalContext.getRequest();
+				Method contentLenMethod = request.getClass().getMethod("getContentLength");
+				return (Integer) contentLenMethod.invoke(request); //this will autobox
+			}
+			catch(Exception e)
+			{
+				_LOG.error("Unsupported request type.", e);
+			}
+		}
+			
+		return -1;
+	}
+
+	/**
+	 * Returns the request input stream if one is available
+	 *
+	 * @param externalContext
+	 * @return
+	 * @throws IOException
+	 */
+	public static final InputStream getRequestInputStream(ExternalContext externalContext)
+			throws IOException
+	{
+		RequestType type = getRequestType(externalContext);
+		
+		if(type.isRequestFromClient())
+		{
+		  try
+			{
+		  	Object request = externalContext.getRequest();
+		  	
+		  	Method method = request.getClass().getMethod(type.isPortlet()?"getPortletInputStream":"getInputStream");
+  			return (InputStream) method.invoke(request);
+			}
+			catch (Exception e)
+			{
+				_LOG.error("Unable to get the request input stream because of an error", e);
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the requestType of this ExternalContext.
+	 * 
+	 * @param externalContext the current external context
+	 * @return the appropriate RequestType for this external context
+	 * @see RequestType
+	 */
+	public static final RequestType getRequestType(ExternalContext externalContext)
+	{
+		//Stuff is laid out strangely in this class in order to optimize
+		//performance.  We want to do as few instanceof's as possible so
+		//things are laid out according to the expected frequency of the
+		//various requests occurring.
+		if(_PORTLET_CONTEXT_CLASS != null)
+		{
+			if (_PORTLET_CONTEXT_CLASS.isInstance(externalContext.getContext()))
+			{
+				//We are inside of a portlet container
+				Object request = externalContext.getRequest();
+				
+				if(_PORTLET_RENDER_REQUEST_CLASS.isInstance(request))
+				{
+					return RequestType.RENDER;
+				}
+				
+				if(_PORTLET_RESOURCE_REQUEST_CLASS != null)
+				{
+					if(_PORTLET_ACTION_REQUEST_CLASS.isInstance(request))
+					{
+						return RequestType.ACTION;
+					}
+
+					//We are in a JSR-286 container
+					if(_PORTLET_RESOURCE_REQUEST_CLASS.isInstance(request))
+					{
+						return RequestType.RESOURCE;
+					}
+					
+					return RequestType.EVENT;
+				}
+				
+				return RequestType.ACTION;
+			}
+		}
+		
+		return RequestType.SERVLET;
+	}
+
+  private static final Log _LOG = LogFactory.getLog(TagUtils.class);
+
+	private static final Class<?>	_PORTLET_ACTION_REQUEST_CLASS;
+	private static final Class<?> _PORTLET_RENDER_REQUEST_CLASS;
+	private static final Class<?> _PORTLET_RESOURCE_REQUEST_CLASS; //Will be present in JSR-286 containers only
+	private static final Class<?>	_PORTLET_CONTEXT_CLASS;
+	
+	static
+	{
+		Class<?> context;
+		Class<?> actionRequest;
+		Class<?> renderRequest;
+		Class<?> resourceRequest;
+		try
+		{
+			ClassLoader loader = Thread.currentThread().getContextClassLoader();
+			context = loader.loadClass("javax.portlet.PortletContext");
+			actionRequest = loader.loadClass("javax.portlet.ActionRequest");
+			renderRequest = loader.loadClass("javax.portlet.RenderRequest");
+			
+			try
+			{
+				resourceRequest = loader.loadClass("javax.portlet.ResourceRequest");
+			}
+			catch (ClassNotFoundException e)
+			{
+				resourceRequest = null;
+			}
+		}
+		catch (ClassNotFoundException e)
+		{
+			context = null;
+			actionRequest = null;
+			renderRequest = null;
+			resourceRequest = null;
+		}
+
+		_PORTLET_CONTEXT_CLASS = context;
+		_PORTLET_ACTION_REQUEST_CLASS = actionRequest;
+		_PORTLET_RENDER_REQUEST_CLASS = renderRequest;
+		_PORTLET_RESOURCE_REQUEST_CLASS = resourceRequest;
+	}	
+}

Added: myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/RequestType.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/RequestType.java?rev=643550&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/RequestType.java (added)
+++ myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/RequestType.java Tue Apr  1 13:11:06 2008
@@ -0,0 +1,108 @@
+package org.apache.myfaces.commons.util;
+
+/**
+ * Represents the type of request currently in the ExternalContext.
+ * All servlet requests will be of the SERVLET requestType whereas
+ * all of the other RequestTypes will be portlet type requests.  There
+ * are a number of convenience methods on the RequestType enumeration
+ * which can be used to determine the capabilities of the current request.
+ */
+public enum RequestType
+{
+	/**
+	 * The type for all servlet requests.  SERVLET request types are
+	 * both client requests and response writable.
+	 */
+	SERVLET(true, true, false),
+	
+	/**
+	 * The type for a portlet RenderRequest.  RENDER request types are
+	 * for portlets and are response writable but are NOT client
+	 * requests.
+	 */
+	RENDER(false, true, true),
+	
+	/**
+	 * The type for a portlet ActionRequest.  ACTION request types are
+	 * for portlets and are client requests but are NOT response 
+	 * writable.
+	 */
+	ACTION(true, false, true),
+	
+	/**
+	 * The type for a portlet ResourceRequest.  RESOURCE request types
+	 * are for portlets and are both client requests and response 
+	 * writable.  RESOURCE request types will only be returned in a
+	 * Portlet 2.0 portlet container.
+	 */
+	RESOURCE(true, true, true),
+	
+	/**
+	 * The type for a portlet EventRequest.  EVENT request types
+	 * are for portlets and are neither client requests nor response 
+	 * writable.  EVENT request types will only be returned in a
+	 * Portlet 2.0 portlet container.
+	 */		
+	EVENT(false, false, true);
+	
+	private boolean _client;
+	private boolean _writable;
+	private boolean _portlet;
+	
+	RequestType(boolean client, boolean writable, boolean portlet)
+	{
+		_client = client;
+		_writable  = writable;
+		_portlet    = portlet;
+	}
+	
+	/**
+	 * Returns <code>true</code> if this request was a direct
+	 * result of a call from the client.  This implies that
+	 * the current application is the "owner" of the current
+	 * request and that it has access to the inputStream, can
+	 * get and set character encodings, etc.  Currently all
+	 * SERVLET, ACTION, and RESOURCE RequestTypes are client
+	 * requests.
+	 * 
+	 * @return <code>true</code> if the current request is a
+	 *         client data type request and <code>false</code>
+	 *         if it is not.
+	 */
+	public boolean isRequestFromClient()
+	{
+		return _client;
+	}
+	
+	/**
+	 * Returns <code>true</code> if the response for this
+	 * RequestType is intended to produce output to the client.
+	 * Currently the SERVLET, RENDER, and RESOURCE request are
+	 * response writable.
+	 *  
+	 * @return <code>true</code> if the current request is 
+	 *         intended to produce output and <code>false</code>
+	 *         if it is not.
+	 */
+	public boolean isResponseWritable()
+	{
+		return _writable;
+	}
+	
+	/**
+	 * Returns <code>true</code> if the response for this
+	 * RequestType originated from a JSR-168 or JSR-286 
+	 * portlet container.  Currently RENDER, ACTION,
+	 * RESOURCE, and EVENT RequestTypes are all portlet
+	 * requests.
+	 * 
+	 * @return <code>true</code> if the current request
+	 *         originated inside of a JSR-168 or JSR-286
+	 *         Portlet Container or <code>false</code> if
+	 *         it did not.
+	 */
+	public boolean isPortlet()
+	{
+		return _portlet;
+	}
+}
\ No newline at end of file