Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/MethodBindingProcessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/MethodBindingProcessor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/WebResourceProcessor.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/WebResourceProcessor.java?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/WebResourceProcessor.java
(added)
+++
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/WebResourceProcessor.java
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.shale.remoting.impl;
+
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Date;
+import java.util.ResourceBundle;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.remoting.Processor;
+
+/**
+ * <p>Implementation of [EMAIL PROTECTED] Processor} which serves resources
from the
+ * web application's static resources. View identifiers shoud be a fully
+ * qualified path, beginning with a slash ("/") character (for example,
+ * <code>/org/apache/shale/remoting/MyResource.css</code>).</p>
+ */
+public class WebResourceProcessor extends AbstractResourceProcessor {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ /**
+ * <p><code>ResourceBundle</code> containing our localized messages.</p>
+ */
+ private ResourceBundle bundle =
ResourceBundle.getBundle("org.apache.shale.remoting.Bundle");
+
+
+ /**
+ * <p>Log instance for this class.</p>
+ */
+ private static Log log = LogFactory.getLog(WebResourceProcessor.class);
+
+
+ // --------------------------------------------------------------
Properties
+
+
+
+ // -------------------------------------------------------- Abstract
Methods
+
+
+ /** [EMAIL PROTECTED] */
+ protected URL getResourceURL(FacesContext context, String resourceId) {
+
+ // Disallow access to resources in reserved directories
+ String resourceIdUpper = resourceId.toUpperCase();
+ if (resourceIdUpper.startsWith("/WEB-INF") ||
resourceIdUpper.startsWith("/META-INF")) {
+ if (log.isWarnEnabled()) {
+ log.warn(bundle.getString("resource.refuse"));
+ log.warn(resourceId);
+ }
+ return null;
+ }
+
+ // Disallow access to JSP and JSP fragment sources
+ if(resourceIdUpper.endsWith(".JSP") ||
resourceIdUpper.endsWith(".JSPF")) {
+ if (log.isWarnEnabled()) {
+ log.warn(bundle.getString("resource.refuse"));
+ log.warn(resourceId);
+ }
+ return null;
+ }
+
+ // Call getResource() on the ServletContext or PortletContext instance
+ Object ctxt = context.getExternalContext().getContext();
+ try {
+ Method method =
+ ctxt.getClass().getMethod("getResource",
+ new Class[] { String.class });
+ URL url = (URL) method.invoke(ctxt, new Object[] { resourceId });
+ if (log.isDebugEnabled()) {
+ log.debug("getResource(" + resourceId + ") --> " + url);
+ }
+ return url;
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
+ log.error(bundle.getString("resource.exception"), e);
+ log.error(resourceId);
+ }
+ return null;
+ }
+
+ }
+
+
+
+ // --------------------------------------------------------- Private
Methods
+
+
+
+}
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/WebResourceProcessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/WebResourceProcessor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/package.html
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/package.html?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/package.html
(added)
+++
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/package.html
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,24 @@
+<!--
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+-->
+
+<!-- $Id$ -->
+
+<body>
+
+<p>This package contains default implementations for the APIs specified
+by Shale remoting support.</p>
+
+</body>
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/package.html
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html
(added)
+++
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,232 @@
+<!--
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+-->
+
+<!-- $Id$ -->
+
+<body>
+
+<p>This package contains interfaces and APIs to support access for remoting
+(client side components that need to perform server side activities and/or
+retrieve information on a background thread. A JavaServer Faces
+<code>PhaseListener</code> is used to gain control at the end of the
+<em>Restore View</em> phase of the request processing lifecycle, and
+determine whether or not the <em>view identifier</em> of the requested
+view now matches one of a set of configured patterns. When a match is
+detected, control of this request is handed over to a configured
+<a href="Processor.html">Processor</a> instance, which can take complete
+responsibility for creating the response for this request (and then
+calling <code>FacesContext.responseComplete()</code> to tell JSF this has been
+done).</p>
+
+<h3>Concrete Processor Implementations</h3>
+
+<p>You can define your own <a href="Processor.html">Processor</a>
implementations,
+and map them to requests as shown below. Alternatively, the following concrete
+implementations are available out of the box for your use:</p>
+<ul>
+ <li><a href="impl/ClassResourceProcessor.html">ClassResourceProcessor</a> -
+ Serves static resources (such as stylesheets or JavaScript source
files)
+ from the web application classpath. In other words, resource files can
+ be packaged inside a JAR file that is included in the
+ <code>/WEB-INF/lib</code> directory, without requiring the developer to
+ modify their build script to extract the resources into the webapp root
+ directory or a specially configured subdirectory.</li>
+ <li><a href="impl/WebResourceProcessor.html">WebResourceProcessor</a> -
+ Serves static resources (such as stylesheets or JavaScript source
files)
+ from the web application's document root. This is essentially the same
+ as allowing your servlet container's default file-serving servlet to
+ serve the resources, but allows operation in scenarios where such a
+ file serving servlet has not been configured.</li>
+ <li><a href="impl/MethodBindingProcessor.html">MethodBindingProcessor</a> -
+ Translates the resource portion of the URL (see examples below) into a
+ JavaServer Faces <em>method binding expression</em> that points at a
+ public method taking no parameters, and then executes a call to this
+ method. As a result of evaluating the method binding, it is possible
+ that the JavaServer Faces <em>managed beans</em> facility will be
+ invoked to create and configure the bean containing the called
method.</li>
+</ul>
+
+<p>The static resource serving <a href="Processor.html">Processor</a>
implentations
+share the following features:</p>
+<ul>
+ <li>Disallow access to prohibited resources (web application resources
+ under <code>/WEB-INF</code> or <code>/META-INF</code>, Java class
+ files, and JSP source files).</li>
+ <li>Set the content type of the response based on the extension portion
+ of the resource identifier. This is done by first consulting the
+ servlet or portlet container (which supports mapping of extensions
+ to content types with a <code><mime-type></code> element in the
+ web application deployment descriptor), and then by consulting a
+ fallback list of mappings for common types of resources.</li>
+ <li>Support browser caching of static content, by watching for incoming
+ requests that contain an <code>If-Modified-Since</code> HTTP header,
+ and returning an HTTP "not modified" (304) response if this application
+ has not been restarted since the resource was served to this
client.</li>
+ <li>Requests for non-existent resources will return a standard HTTP
+ "not found" (404) response.</li>
+ <li>Standard servlet access control features may be applied to the served
+ resources, by using standard security constraint elements in the web
+ application deployment descriptor.</li>
+</ul>
+
+<p>The dynamic logic invoked by <a href="impl/MethodBindingProcessor.html">
+MethodBindingProcessor</a> can use any technique it desires to create the
+content for this response. Available options (starting with the one that is
+recommended best practice) include:</p>
+<ul>
+ <li>For a text response, acquire a <code>ResponseWriter</code> instance
+ and use its methods, just as a <code>Renderer</code> would:
+ <blockquote><pre>
+FacesContext context = FacesContext.getCurrentInstance();
+ResponseWriter writer = (new ResponseFactory()).createResponseWriter(context,
"text/xml");
+writer.startDocument();
+...
+writer.endDocument();
+writer.close();
+ </pre></blockquote></li>
+ <li>For a binary response, acquire a <code>ResponseStream</code> instance
+ and use its methods:
+ <blockquote><pre>
+FacesContext context = FacesContext.getCurrentInstance();
+ResponseStream stream = (new ResponseFactory()).createResponseStream(context,
"image/gif");
+stream.write(...);
+...
+stream.close();
+ </pre></blockquote></l>
+ <li>Stash relevant model data (typically in request scope), and then
forward
+ to a JSP page (with either JSF components or JSTL tags coupled with EL
+ expressions) that will produce the actual response:
+ <blockquote><pre>
+FacesContext context = FacesContext.getCurrentInstance();
+context.getExternalContext().dispatch("/results.jsp");
+ </pre></blockquote></li>
+ <li>Access the response object from the external context, and acquire a
+ writer or stream from the response object directly. Note that this
+ technique, unlike those illustrated above, requires you to program
+ specfically to either the servlet or portlet response APIs.</li>
+</ul>
+
+<p>Before returning, the dynamic logic should call
<code>responseComplete()</code>
+on the <code>FacesContext</code> instance for the current request, to bypass
+the remaining phases of the JavaServer Faces request processing lifecycle.</p>
+
+<h3>Configuring Remoting Support</h3>
+
+<p>In order for a request URI to be processed at all by the Shale remoting
+facilities, it must match the mapping for <code>FacesServlet</code> that is
+already defined in <code>/WEB-INF/web.xml</code>. Once that occurs, JSF will
+have constructed a corresponding view identifier that can be retrieved by
+calling:
+<blockquote><pre>
+String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
+</pre></blockquote></p>
+
+<p>This view identifier is then compared to a set of matching patterns which,
+like servlet mappings, can be either prefix matched (<code>/foo/*</code>) or
+extension matched (<code>*.foo</code>). If the view identifier matches, it
will
+be transformed into a corresponding <em>resource identifier</em> that is passed
+to the <code>process()</code> method of an appropriate <a
href="Processor.html">
+Processor</a> instance.</p>
+
+<p>Mapping of view identifiers to resources is configured by specifying comma
+delimited lists of "pattern:classname" pairs for the following context
initialization
+parameters in <code>/WEB-INF/web.xml</code>. For each of these parameters that
+is not specified, the value illustrated here will be the default
(<strong>WARNING</strong>
+- this decision may be changed later, so double check the latest
documentation):
+<blockquote><pre>
+<context-param>
+ <param-name>
+ org.apache.shale.remoting.CLASS_RESOURCES
+ </param-name>
+ <param-value>
+ /static/*:org.apache.shale.remoting.impl.ClassResourceProcessor
+ </param-value>
+</context-param>
+
+<context-param>
+ <param-name>
+ org.apache.shale.remoting.DYNAMIC_RESOURCES
+ </param-name>
+ <param-value>
+ /dynamic/*:org.apache.shale.remoting.impl.MethodBindingProcessor
+ </param-value>
+</context-param>
+
+<context-param>
+ <param-name>
+ org.apache.shale.remoting.WEBAPP_RESOURCES
+ </param-name>
+ <param-value>
+ /webapp/*:org.apache.shale.remoting.impl.WebResourceProcessor
+ </param-value>
+</context-param>
+</pre></blockquote></p>
+
+<p>In addition, you can configure the following additional context
initialization
+parameters:</p>
+<ul>
+ <li><code>org.apache.shale.remoting.OTHER_RESOURCES</code> - configuration
+ pairs as described above, which will be marked with the "other"
+ mechanism type. No default value.</li>
+ <li><code>org.apache.shale.remoting.MAPPING_CLASS</code> - fully qualified
+ classname of class used to create <a href="Mapping.html">Mapping</a>
+ instances to record configuration information. If not specified, the
+ <a href="impl/MappingImpl.html">MappingImpl</a> class will be
used.</li>
+ <li><code>org.apache.shale.remoting.MAPPINGS_CLASS</code> - fully qualified
+ classname of class used to create a <a
href="Mappings.html">Mappings</a>
+ instance to record configuration information. If not specified, the
+ <a href="impl/MappingsImpl.html">MappingsImpl</a> class will be
used.</li>
+</ul>
+
+<p>Once the configuration information has been processed (which will occur on
+the first JSF request after the application has started), an instance of
+<a href="Mappings.html">Mappings</a> will be stored as an application scope
+parameter under the key identified by <code>Globals.MAPPINGS_ATTR</code> which
+contains all of the configuration information being used. This instance might
+be useful, for example, to a JSF component that wishes to dynamically determine
+the appropriate mapping for class resources.</p>
+
+
+<h3>Example URLs</h3>
+
+<p>Given the default resource mappings described above, and assuming that the
+developer has mapped <code>FacesServlet</code> to the <code>*.faces</code>
+pattern, the following request URLs will be mapped to appropriate resources
+and processed as follows:</p>
+
+<p><code>http://localhost:8080/myapp/dynamic/foo/bar.faces</code>
+<blockquote>
+ Constructs a method binding expression <code>#{foo.bar}</code> and then
+ executes it. This will cause the bean instance at attribute name
<code>foo</code>
+ to be located (or created, if necessary), and then the public
<code>bar()</code>
+ method, which takes no parameters, will be called on that instance.
+</blockquote></p>
+
+<p><code>http://localhost:8080/myapp/static/mycompany/mypackage/MyScript.js.faces</code>
+<blockquote>
+ Locates and serves a static resource
(<code>/mycompany/mypackage/MyScript.js</code>)
+ from the web application class loader, which will therefore locate such
resources
+ in the <code>/WEB-INF/classes</code> directory, or packaged in a JAR file
in the
+ <code>/WEB-INF/lib</code> directory.</p>
+</blockquote></p>
+
+<p><code>http://localhost:8080/myapp/webapp/resources/MyScript.js.faces</code>
+<blockquote>
+ Locates and serves a static resource (<code>/resources/MyScript.js</code>)
+ from the document root of the web application.</p>
+</blockquote></p>
+
+</body>
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ClassResourceProcessorTestCase.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ClassResourceProcessorTestCase.java?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ClassResourceProcessorTestCase.java
(added)
+++
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ClassResourceProcessorTestCase.java
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.shale.remoting.impl;
+
+import javax.faces.el.EvaluationException;
+import javax.faces.el.MethodNotFoundException;
+import javax.servlet.http.HttpServletResponse;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.test.mock.MockServletOutputStream;
+
+/**
+ * <p>Test case for
<code>org.apache.shale.remoting.impl.ClassResourceProcessor</code>.</p>
+ */
+public class ClassResourceProcessorTestCase extends AbstractJsfTestCase {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // Construct a new instance of this test case.
+ public ClassResourceProcessorTestCase(String name) {
+ super(name);
+ }
+
+
+ // ------------------------------------------------------ Manifest
Constants
+
+
+ private static final String INVALID_RESOURCE_ID =
+ "/org/apache/shale/remoting/impl/MissingData.text";
+
+ private static final String VALID_RESOURCE_ID =
+ "/org/apache/shale/remoting/impl/TestData.text";
+
+ private static final String VALID_RESOURCE_CONTENT =
+ "This is a test. It is only a test."; // Not including line
delimiters!
+
+ // ----------------------------------------------------------- Setup
Methods
+
+
+ // Set up instance variables for this test case.
+ public void setUp() {
+
+ threadClassLoader = Thread.currentThread().getContextClassLoader();
+
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
+ super.setUp();
+ servletContext.addMimeType("text", "text/x-plain");
+ processor = new ClassResourceProcessor();
+
+ }
+
+
+ // Return the tests included in this test case.
+ public static Test suite() {
+
+ return (new TestSuite(ClassResourceProcessorTestCase.class));
+
+ }
+
+
+ // Tear down instance variables for this test case.
+ public void tearDown() {
+
+ processor = null;
+ super.tearDown();
+ Thread.currentThread().setContextClassLoader(threadClassLoader);
+
+ }
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ // The Processor instance to be tested
+ private ClassResourceProcessor processor = null;
+
+
+ // The cached thread context class loader
+ private ClassLoader threadClassLoader = null;
+
+
+ // ------------------------------------------------------------ Test
Methods
+
+
+ // Test an invalid resource
+ public void testInvalidResource() throws Exception {
+
+ processor.process(facesContext, INVALID_RESOURCE_ID);
+ assertEquals(HttpServletResponse.SC_NOT_FOUND, response.getStatus());
+ assertEquals(INVALID_RESOURCE_ID, response.getMessage());
+
+ }
+
+
+ // Test mapping of resource identifiers to URLs
+ public void testMapping() {
+
+ assertNotNull(processor.getResourceURL(facesContext,
VALID_RESOURCE_ID));
+ assertNull(processor.getResourceURL(facesContext,
INVALID_RESOURCE_ID));
+
+ }
+
+
+ // Test a pristine instance of the Processor to be tested
+ public void testPristine() {
+
+ assertNotNull(processor);
+ assertEquals("text/x-plain",
servletContext.getMimeType(VALID_RESOURCE_ID));
+ assertEquals("text/x-plain",
servletContext.getMimeType(INVALID_RESOURCE_ID));
+
+ }
+
+
+ // Test a valid resource that has not been modified
+ public void testNotModifiedResource() throws Exception {
+
+ long timestamp = processor.getLastModified();
+ request.addDateHeader("If-Modified-Since", timestamp);
+ processor.process(facesContext, VALID_RESOURCE_ID);
+ assertEquals(HttpServletResponse.SC_NOT_MODIFIED,
response.getStatus());
+
+ }
+
+
+ // Test a valid resource
+ public void testValidResource() throws Exception {
+
+ processor.process(facesContext, VALID_RESOURCE_ID);
+ assertEquals("text/x-plain", response.getContentType());
+ MockServletOutputStream stream =
+ (MockServletOutputStream) response.getOutputStream();
+ assertNotNull(stream);
+ assertTrue(stream.size() > VALID_RESOURCE_CONTENT.length());
+ byte content[] = stream.content();
+ for (int i = 0; i < VALID_RESOURCE_CONTENT.length(); i++) {
+ byte b = (byte) ((int) VALID_RESOURCE_CONTENT.charAt(i));
+ assertEquals("Byte at position " + i, b, content[i]);
+ }
+
+
+ }
+
+ // --------------------------------------------------------- Support
Methods
+
+
+
+}
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ClassResourceProcessorTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ClassResourceProcessorTestCase.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MappingImplTestCase.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MappingImplTestCase.java?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MappingImplTestCase.java
(added)
+++
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MappingImplTestCase.java
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.shale.remoting.impl;
+
+import javax.faces.component.UIViewRoot;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+
+/**
+ * <p>Test case for
<code>org.apache.shale.remoting.impl.MappingImpl</code>.</p>
+ */
+public class MappingImplTestCase extends AbstractJsfTestCase {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // Construct a new instance of this test case.
+ public MappingImplTestCase(String name) {
+ super(name);
+ }
+
+
+ // ----------------------------------------------------------- Setup
Methods
+
+
+ // Set up instance variables for this test case.
+ public void setUp() {
+
+ super.setUp();
+ facesContext.setViewRoot(new UIViewRoot());
+ mapping = new MappingImpl();
+
+ }
+
+
+ // Return the tests included in this test case.
+ public static Test suite() {
+
+ return (new TestSuite(MappingImplTestCase.class));
+
+ }
+
+
+ // Tear down instance variables for this test case.
+ public void tearDown() {
+
+ mapping = null;
+ super.tearDown();
+
+ }
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ // The instance to be tested
+ private MappingImpl mapping = null;
+
+
+ // ------------------------------------------------------------ Test
Methods
+
+
+ // Test extension mapping
+ public void testExtension() {
+
+ mapping.setPattern("*.foo");
+ facesContext.getViewRoot().setViewId("foo");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId(".foo");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo.bar");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/bar.foo");
+ assertEquals("/bar", mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/bar/baz.foo");
+ assertEquals("/bar/baz", mapping.mapViewId(facesContext));
+
+ }
+
+
+ // Test invalid patterns
+ public void testInvalid() {
+
+ try {
+ mapping.setPattern("");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ try {
+ mapping.setPattern("foo");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ try {
+ mapping.setPattern("/foo");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ try {
+ mapping.setPattern("/foo/");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ try {
+ mapping.setPattern(".foo");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ try {
+ mapping.setPattern("*.foo.");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ try {
+ mapping.setPattern("*.foo.bar");
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ ; // Expected result
+ }
+
+ }
+
+
+ // Test prefix mapping
+ public void testPrefix() {
+
+ mapping.setPattern("/foo/*");
+ facesContext.getViewRoot().setViewId("foo");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/bar");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/bar/foo");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo");
+ assertNull(mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo/bar");
+ assertEquals("/bar", mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo/bar.baz");
+ assertEquals("/bar.baz", mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo/bar/baz");
+ assertEquals("/bar/baz", mapping.mapViewId(facesContext));
+ facesContext.getViewRoot().setViewId("/foo/bar/baz.bop");
+ assertEquals("/bar/baz.bop", mapping.mapViewId(facesContext));
+
+ }
+
+
+ // Test a pristine instance
+ public void testPristine() {
+
+ assertNull(mapping.getMechanism());
+ assertNull(mapping.getPattern());
+ assertNull(mapping.getProcessor());
+
+ }
+
+
+ // --------------------------------------------------------- Support
Methods
+
+
+
+}
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MappingImplTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MappingImplTestCase.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorBusinessObject.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorBusinessObject.java?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorBusinessObject.java
(added)
+++
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorBusinessObject.java
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.shale.remoting.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.shale.remoting.faces.ResponseFactory;
+
+/**
+ * <p>Business object that includes methods to produce output, when
+ * invoked indirectly via <code>MethodBindingProcessor</code>.</p>
+ */
+public class MethodBindingProcessorBusinessObject {
+
+
+ /**
+ * <p>Create binary output directy to the servlet response.</p>
+ */
+ public void directStream() {
+
+ try {
+ FacesContext context = FacesContext.getCurrentInstance();
+ HttpServletResponse response = (HttpServletResponse)
+ context.getExternalContext().getResponse();
+ response.setContentType("application/x-binary");
+ ServletOutputStream stream = response.getOutputStream();
+ for (int i = 0; i < 10; i++) {
+ stream.write(i);
+ }
+ } catch (IOException e) {
+ throw new FacesException(e);
+ }
+
+ }
+
+
+ /**
+ * <p>Create character output directly to the servlet response.</p>
+ */
+ public void directWriter() {
+
+ try {
+ FacesContext context = FacesContext.getCurrentInstance();
+ HttpServletResponse response = (HttpServletResponse)
+ context.getExternalContext().getResponse();
+ response.setContentType("text/x-plain");
+ PrintWriter writer = response.getWriter();
+ for (int i = 0; i < 10; i++) {
+ writer.write('a' + i);
+ }
+ } catch (IOException e) {
+ throw new FacesException(e);
+ }
+
+ }
+
+
+ /**
+ * <p>Create binary output indirecty via a factory.</p>
+ */
+ public void indirectStream() {
+
+ try {
+ FacesContext context = FacesContext.getCurrentInstance();
+ ResponseStream stream =
+ (new ResponseFactory()).getResponseStream(context,
"application/x-binary");
+ for (int i = 0; i < 10; i++) {
+ stream.write(i);
+ }
+ } catch (IOException e) {
+ throw new FacesException(e);
+ }
+
+ }
+
+
+ /**
+ * <p>Create character output indirectly a factory.</p>
+ */
+ public void indirectWriter() {
+
+ try {
+ FacesContext context = FacesContext.getCurrentInstance();
+ ResponseWriter writer =
+ (new ResponseFactory()).getResponseWriter(context,
"text/x-plain");
+ for (int i = 0; i < 10; i++) {
+ writer.write('a' + i);
+ }
+ } catch (IOException e) {
+ throw new FacesException(e);
+ }
+
+ }
+
+
+}
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorBusinessObject.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorBusinessObject.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorTestCase.java
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorTestCase.java?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorTestCase.java
(added)
+++
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorTestCase.java
Mon Jan 2 13:29:19 2006
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.shale.remoting.impl;
+
+import javax.faces.el.EvaluationException;
+import javax.faces.el.MethodNotFoundException;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.test.mock.MockPrintWriter;
+import org.apache.shale.test.mock.MockServletOutputStream;
+
+/**
+ * <p>Test case for
<code>org.apache.shale.remoting.impl.MethodBindingProcessor</code>.</p>
+ */
+public class MethodBindingProcessorTestCase extends AbstractJsfTestCase {
+
+
+ // ------------------------------------------------------------
Constructors
+
+
+ // Construct a new instance of this test case.
+ public MethodBindingProcessorTestCase(String name) {
+ super(name);
+ }
+
+
+ // ----------------------------------------------------------- Setup
Methods
+
+
+ // Set up instance variables for this test case.
+ public void setUp() {
+
+ super.setUp();
+ processor = new MethodBindingProcessor();
+ servletContext.setAttribute("business", new
MethodBindingProcessorBusinessObject());
+
+ }
+
+
+ // Return the tests included in this test case.
+ public static Test suite() {
+
+ return (new TestSuite(MethodBindingProcessorTestCase.class));
+
+ }
+
+
+ // Tear down instance variables for this test case.
+ public void tearDown() {
+
+ servletContext.removeAttribute("business");
+ processor = null;
+ super.tearDown();
+
+ }
+
+
+ // ------------------------------------------------------ Instance
Variables
+
+
+ // The Processor instance to be tested
+ private MethodBindingProcessor processor = null;
+
+
+ // ------------------------------------------------------------ Test
Methods
+
+
+ // Test attempt to execute an expression with an invalid bean name
+ public void testInvalidBean() throws Exception {
+
+ try {
+ processor.process(facesContext, "/invalid/directStream");
+ fail("Should have thrown EvaluationException");
+ } catch (EvaluationException e) {
+ ; // Expected result
+ }
+
+ }
+
+
+ // Test attempt to execute an expression with an invalid method name
+ public void testInvalidMethod() throws Exception {
+
+ try {
+ processor.process(facesContext, "/business/invalidMethod");
+ fail("Should have thrown MethodNotFoundException");
+ } catch (MethodNotFoundException e) {
+ ; // Expected result
+ }
+
+ }
+
+
+ // Test mapping of resource identifiers to expressions
+ public void testMapping() {
+
+ assertEquals("#{business.directStream}",
+ processor.mapResourceId(facesContext,
"/business/directStream").getExpressionString());
+ assertEquals("#{business.directWriter}",
+ processor.mapResourceId(facesContext,
"/business/directWriter").getExpressionString());
+ assertEquals("#{business.indirectStream}",
+ processor.mapResourceId(facesContext,
"/business/indirectStream").getExpressionString());
+ assertEquals("#{business.indirectWriter}",
+ processor.mapResourceId(facesContext,
"/business/indirectWriter").getExpressionString());
+
+ }
+
+
+ // Test a pristine instance of the Processor to be tested
+ public void testPristine() {
+
+ assertNotNull(processor);
+ assertNotNull(servletContext.getAttribute("business"));
+ assertNull(servletContext.getAttribute("invalid"));
+
+ }
+
+
+ // Test output sent directly to the servlet response ServletOutputStream
+ public void testDirectStream() throws Exception {
+
+ processor.process(facesContext, "/business/directStream");
+ assertEquals("application/x-binary", response.getContentType());
+ MockServletOutputStream stream =
+ (MockServletOutputStream) response.getOutputStream();
+ assertNotNull(stream);
+ assertEquals(10, stream.size());
+ byte content[] = stream.content();
+ for (int i = 0; i < 10; i++) {
+ assertEquals("Byte at position " + i, (byte) i, content[i]);
+ }
+ assertTrue(facesContext.getResponseComplete());
+
+ }
+
+
+ // Test output sent directly to the servlet response PrintWriter
+ public void testDirectWriter() throws Exception {
+
+ processor.process(facesContext, "/business/directWriter");
+ assertEquals("text/x-plain", response.getContentType());
+ MockPrintWriter writer = (MockPrintWriter) response.getWriter();
+ assertNotNull(writer);
+ assertEquals(10, writer.size());
+ char content[] = writer.content();
+ for (int i = 0; i < 10; i++) {
+ assertEquals("Character at position " + i, (char) ('a' + i),
content[i]);
+ }
+ assertTrue(facesContext.getResponseComplete());
+
+ }
+
+
+ // Test output sent indirectly to the servlet or portlet response stream
+ public void testIndirectStream() throws Exception {
+
+ processor.process(facesContext, "/business/indirectStream");
+ assertEquals("application/x-binary", response.getContentType());
+ MockServletOutputStream stream =
+ (MockServletOutputStream) response.getOutputStream();
+ assertNotNull(stream);
+ assertEquals(10, stream.size());
+ byte content[] = stream.content();
+ for (int i = 0; i < 10; i++) {
+ assertEquals("Byte at position " + i, (byte) i, content[i]);
+ }
+ assertTrue(facesContext.getResponseComplete());
+
+ }
+
+
+ // Test output sent indirectly to the servlet or portlet response writer
+ public void testIndirectWriter() throws Exception {
+
+ processor.process(facesContext, "/business/indirectWriter");
+ assertEquals("text/x-plain", response.getContentType());
+ MockPrintWriter writer = (MockPrintWriter) response.getWriter();
+ assertNotNull(writer);
+ assertEquals(10, writer.size());
+ char content[] = writer.content();
+ for (int i = 0; i < 10; i++) {
+ assertEquals("Character at position " + i, (char) ('a' + i),
content[i]);
+ }
+ assertTrue(facesContext.getResponseComplete());
+
+ }
+
+
+ // --------------------------------------------------------- Support
Methods
+
+
+
+}
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/MethodBindingProcessorTestCase.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added:
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/TestData.text
URL:
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/TestData.text?rev=365442&view=auto
==============================================================================
---
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/TestData.text
(added)
+++
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/TestData.text
Mon Jan 2 13:29:19 2006
@@ -0,0 +1 @@
+This is a test. It is only a test.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]