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>&lt;mime-type&gt;</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>
+&lt;context-param&gt;
+  &lt;param-name&gt;
+    org.apache.shale.remoting.CLASS_RESOURCES
+  &lt;/param-name&gt;
+  &lt;param-value&gt;
+    /static/*:org.apache.shale.remoting.impl.ClassResourceProcessor
+  &lt;/param-value&gt;
+&lt;/context-param&gt;
+
+&lt;context-param&gt;
+  &lt;param-name&gt;
+    org.apache.shale.remoting.DYNAMIC_RESOURCES
+  &lt;/param-name&gt;
+  &lt;param-value&gt;
+    /dynamic/*:org.apache.shale.remoting.impl.MethodBindingProcessor
+  &lt;/param-value&gt;
+&lt;/context-param&gt;
+
+&lt;context-param&gt;
+  &lt;param-name&gt;
+    org.apache.shale.remoting.WEBAPP_RESOURCES
+  &lt;/param-name&gt;
+  &lt;param-value&gt;
+    /webapp/*:org.apache.shale.remoting.impl.WebResourceProcessor
+  &lt;/param-value&gt;
+&lt;/context-param&gt;
+</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]

Reply via email to