Author: craigmcc
Date: Sat Jan  7 20:47:04 2006
New Revision: 366984

URL: http://svn.apache.org/viewcvs?rev=366984&view=rev
Log:
Implement a new remoting Processor that maps a request for a resource id
like "/foo/bar" to a Commons Chain command named "foo.bar" in a catalog
named "remoting".  This Processor is not configured by default.

Added:
    
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java
   (with props)
    
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java
   (with props)
    
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java
   (with props)
    
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java
   (with props)
Modified:
    
struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/faces/DialogNavigationHandler.java
    
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html
    
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/faces/DialogNavigationHandler.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/faces/DialogNavigationHandler.java?rev=366984&r1=366983&r2=366984&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/faces/DialogNavigationHandler.java
 (original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/faces/DialogNavigationHandler.java
 Sat Jan  7 20:47:04 2006
@@ -36,6 +36,7 @@
 import org.apache.shale.dialog.Transition;
 import org.apache.shale.dialog.ViewState;
 import org.apache.shale.dialog.impl.StatusImpl;
+import org.apache.shale.util.Messages;
 
 /**
  * <p>An implementation of <code>NavigationHandler</code> that provides
@@ -126,6 +127,13 @@
     public static final Class[] SIGNATURE = new Class[0];
 
 
+    /**
+     * <p>Localized messages for this class.</p>
+     */
+    private static final Messages messages =
+        new Messages("org.apache.shale.resources.Bundle");
+
+
     // ------------------------------------------------------ Instance 
Variables
 
 
@@ -199,11 +207,14 @@
         // Postprocess based on the nature of the current state
         Dialog dialog = getDialog(context, position.getDialogName());
         if (dialog == null) {
-            throw new IllegalArgumentException(position.toString());
+            throw new 
IllegalArgumentException(messages.getMessage("dialog.noDialog",
+                                               new Object[] { 
position.getDialogName() }));
         }
         State state = dialog.findState(position.getStateName());
         if (state == null) {
-            throw new IllegalArgumentException(position.toString());
+            throw new 
IllegalArgumentException(messages.getMessage("dialog.noState",
+                                               new Object[] { 
position.getStateName(),
+                                                              
position.getDialogName() }));
         }
         postprocess(context, status, state, outcome);
 
@@ -252,6 +263,9 @@
      *
      * @param context <code>FacesContext</code> for the current request
      * @param dialogName Name of the requested dialog
+     *
+     * @exception IllegalStateException if dialog configuration metadata
+     *  has not yet been processed
      */
     private Dialog getDialog(FacesContext context, String dialogName) {
 
@@ -261,7 +275,7 @@
         Map map = (Map)
           
context.getExternalContext().getApplicationMap().get(Globals.DIALOGS);
         if (map == null) {
-            return null;
+            throw new 
IllegalStateException(messages.getMessage("dialog.unconfigured"));
         }
         return (Dialog) map.get(dialogName);
 
@@ -323,6 +337,9 @@
      * @param status Current [EMAIL PROTECTED] Status} for this user
      * @param state The [EMAIL PROTECTED] State} we retrieved based on the 
[EMAIL PROTECTED] Status}
      * @param outcome Original outcome from handler
+     *
+     * @exception IllegalArgumentException if the current state is not
+     *  a ViewState
      */
     private void postprocess(FacesContext context, Status status,
                              State state, String outcome) {
@@ -336,7 +353,9 @@
             State nextState = transition(status, state, outcome);
             preprocess(context, status, nextState, outcome);
         } else {
-            throw new IllegalArgumentException(state.toString());
+            throw new 
IllegalArgumentException(messages.getMessage("dialog.noPostProcess",
+                                               new Object[] { state.getName(),
+                                                              
state.getClass().getName() }));
         }
 
     }
@@ -351,6 +370,9 @@
      * @param state The [EMAIL PROTECTED] State} we just transitioned to
      * @param outcome The outcome that caused us to transition to this
      *  [EMAIL PROTECTED] State}
+     *
+     * @exception IllegalArgumentExceptoin if the specified state is not of
+     *  a known type
      */
     private void preprocess(FacesContext context, Status status,
                             State state, String outcome) {
@@ -392,7 +414,9 @@
         } else if (state instanceof ViewState) {
             render(context, ((ViewState) state).getViewId());
         } else {
-            throw new IllegalArgumentException(state.toString());
+            throw new 
IllegalArgumentException(messages.getMessage("dialog.noPreProcess",
+                                               new Object[] { state.getName(),
+                                                              
state.getClass().getName() }));
         }
 
     }
@@ -499,16 +523,20 @@
             transition = state.getDialog().findTransition(outcome);
         }
         if (transition == null) {
-            throw new IllegalArgumentException
-              (status.peek().toString() + ",outcome=" + outcome);
+            throw new 
IllegalArgumentException(messages.getMessage("dialog.noTransition",
+                                               new Object[] { outcome,
+                                                              state.getName(),
+                                                              
state.getDialog().getName() }));
         }
 
         // Select the next State based on this Transition
         State nextState = state.getDialog().findState(transition.getTarget());
         if (nextState == null) {
-            throw new IllegalArgumentException
-              (status.peek().toString() + ",outcome=" + outcome +
-               ",target=" + transition.getTarget());
+            throw new 
IllegalArgumentException(messages.getMessage("dialog.noNextState",
+                                               new Object[] { outcome,
+                                                              state.getName(),
+                                                              
state.getDialog().getName(),
+                                                              
transition.getTarget() }));
         }
 
         // Transition to the next State and return it

Added: 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java?rev=366984&view=auto
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java
 (added)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java
 Sat Jan  7 20:47:04 2006
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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.context.FacesContext;
+import org.apache.commons.chain.Context;
+import org.apache.commons.chain.impl.ContextBase;
+
+/**
+ * <p>Implementation of <code>Context</code> suitable for use with commands
+ * or chains executed via Shale Remoting.</p>
+ */
+public class ChainContext extends ContextBase {
+    
+
+    // ------------------------------------------------------------ 
Constructors
+
+
+    /**
+     * <p>Construct a new [EMAIL PROTECTED] ChainContext} instance wrapping the
+     * specified <code>FacesContext</code> instance.</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     */
+    public ChainContext(FacesContext context) {
+        this.context = context;
+    }
+
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    /**
+     * <p>The <code>FacesContext</code> instance that is wrapped by this
+     * <code>Context</code> instance.</p>
+     */
+    private FacesContext context = null;
+
+
+    // -------------------------------------------------------------- 
Properties
+
+
+    /**
+     * <p>Return the <code>FacesContext</code> instance that is wrapped by this
+     * <code>Context</code> instance.</p>
+     */
+    public FacesContext getFacesContext() {
+        return this.context;
+    }
+
+
+}

Propchange: 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainContext.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java?rev=366984&view=auto
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java
 (added)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java
 Sat Jan  7 20:47:04 2006
@@ -0,0 +1,250 @@
+/*
+ * Copyright 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 javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.chain.Catalog;
+import org.apache.commons.chain.CatalogFactory;
+import org.apache.commons.chain.Command;
+import org.apache.commons.chain.Context;
+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 maps a resource 
identifier
+ * to the name of a <a href="http://jakarta.apache.org/commons/chain";>Commons
+ * Chain</a> command or chain, in an appropriate catalog.  The command or chain
+ * that is executed is passed an appropriate <code>Context</code> object, and
+ * it will also have access to the current JavaServer Faces state by calling
+ * <code>FacesContext.getCurrentInstance()</code>.</p>
+ */
+public class ChainProcessor implements Processor {
+    
+
+    // ------------------------------------------------------------ 
Constructors
+
+
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    /**
+     * <p>The <code>Log</code> instance for this class.</p>
+     */
+    private static Log log = LogFactory.getLog(ChainProcessor.class);
+
+
+    // ------------------------------------------------------- Processor 
Methods
+
+
+    /**
+     * <p>Map the specified resource identifier to an appropriate Commons
+     * Chain command or chain, in an appropriate catalog.  Construct an
+     * appropriate <code>Context</code> object, and execute the specified
+     * command or chain, to which we delegate responsibility for creating
+     * the response for the current request.  Call
+     * <code>FacesContext.responseComplete()</code> to tell JavaServer Faces
+     * that the entire response has already been created.</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     * @param resourceId Resource identifier used to select the appropriate 
response
+     *  (this will generally be a context relative path starting with "/")
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception NullPointerException if <code>viewId</code> is 
<code>null</code>
+     */
+    public void process(FacesContext context, String resourceId) throws 
IOException {
+
+        // Identify the Commons Chain catalog we will be using
+        String catalogName = mapCatalog(context, resourceId);
+        Catalog catalog = CatalogFactory.getInstance().getCatalog(catalogName);
+        if (catalog == null) {
+            if (log.isErrorEnabled()) {
+                log.error("Cannot find catalog '" + catalogName + "' for 
resource '" +
+                          resourceId + "'");
+            }
+            sendNotFound(context, resourceId);
+            context.responseComplete();
+            return;
+        }
+
+        // Identify the Commons Chain chain or command we will be executing
+        String commandName = mapCommand(context, resourceId);
+        Command command = catalog.getCommand(commandName);
+        if (command == null) {
+            if (log.isErrorEnabled()) {
+                log.error("Cannot find command '" + commandName + "' in 
catalog '" +
+                          catalogName + "' for resource '" + resourceId + "'");
+            }
+            sendNotFound(context, resourceId);
+            context.responseComplete();
+            return;
+        }
+
+        // Create a new context and pass it to the specified command
+        try {
+            command.execute(createContext(context, resourceId));
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Exception executing command '" + commandName +
+                          "' from catalog '" + catalogName + "' for resource 
'" +
+                          resourceId + "'", e);
+            }
+            sendServerError(context, resourceId, e);
+        }
+
+        // Tell JavaServer Faces that the current response has been completed
+        context.responseComplete();
+
+    }
+
+
+    // ------------------------------------------------------- Protected 
Methods
+
+
+    /**
+     * <p>Create and return an appropriate <code>Context</code> instance to be
+     * passed to the command or chain that is executed.</p>
+     *
+     * <p>The default algorithm constructs and returns an instance of
+     * [EMAIL PROTECTED] ChainContext} that wraps the specified 
<code>FacesContext</code>.</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     * @param resourceId Resource identifier to be mapped
+     */
+    protected Context createContext(FacesContext context, String resourceId) {
+
+        return new ChainContext(context);
+
+    }
+
+
+    /**
+     * <p>Map the specified resource identifier to the name of a Commons Chain
+     * <code>Catalog</code> from which the command or chain instance will be
+     * acquired.</p>
+     *
+     * <p>The default implementation returns <code>remoting</code>
+     * unconditionally.</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     * @param resourceId Resource identifier to be mapped
+     */
+    protected String mapCatalog(FacesContext context, String resourceId) {
+
+        return "remoting";
+
+    }
+
+
+    /**
+     * <p>Map the specified resource identifier to the name of a Commons Chain
+     * <code>Command</code> or <code>Chain</code>, which will be acquired from
+     * a mapped <code>Catalog</code>.</p>
+     *
+     * <p>The default algorithm performs this conversion as follows:</p>
+     * <ul>
+     * <li>Strip any leading slash character.</li>
+     * <li>Convert embedded slash characters to periods.</li>
+     * </ul>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     * @param resourceId Resource identifier to be mapped
+     */
+    protected String mapCommand(FacesContext context, String resourceId) {
+
+        // Strip any leading slash character
+        if (resourceId.startsWith("/")) {
+            resourceId = resourceId.substring(1);
+        }
+
+        // Convert nested slash characters into periods
+        resourceId = resourceId.replace('/', '.');
+
+        // Return the resulting string
+        return resourceId;
+
+    }
+
+
+    /**
+     * <p>Send a "not found" HTTP response, if possible.  Otherwise, throw an
+     * <code>IllegalArgumentException</code> that will ripple out.</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     * @param resourceId Resource identifier of the resource that was not found
+     *
+     * @exception IllegalArgumentException if we cannot send an HTTP response
+     * @exception IOException if an input/output error occurs
+     */
+    protected void sendNotFound(FacesContext context, String resourceId) 
throws IOException {
+
+        if (servletRequest(context)) {
+            HttpServletResponse response = (HttpServletResponse)
+              context.getExternalContext().getResponse();
+            response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceId);
+        } else {
+            throw new IllegalArgumentException(resourceId);
+        }
+
+    }
+
+
+    /**
+     * <p>Send a "server error" HTTP response, if possible.  Otherwise, throw a
+     * <code>FacesException</code> that will ripple out.</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     * @param resourceId Resource identifier of the resource that was not found
+     * @param exception Server exception to be reported
+     *
+     * @exception FacesException if we cannot send an HTTP response
+     * @exception IOException if an input/output error occurs
+     */
+    protected void sendServerError(FacesContext context, String resourceId,
+                                   Exception e) throws IOException {
+
+        if (servletRequest(context)) {
+            HttpServletResponse response = (HttpServletResponse)
+              context.getExternalContext().getResponse();
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
resourceId);
+        } else {
+            throw new FacesException(resourceId);
+        }
+
+    }
+
+
+    /**
+     * <p>Return <code>true</code> if we are processing a servlet request (as
+     * opposed to a portlet request).</p>
+     *
+     * @param context <code>FacesContext</code> for the current request
+     */
+    protected boolean servletRequest(FacesContext context) {
+
+        return context.getExternalContext().getContext() instanceof 
ServletContext;
+
+    }
+
+
+}

Propchange: 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/impl/ChainProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: 
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=366984&r1=366983&r2=366984&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html 
(original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/remoting/package.html 
Sat Jan  7 20:47:04 2006
@@ -57,6 +57,11 @@
         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>
+    <li><a href="impl/ChainProcessor.html">ChainProcessor</a> - Translates the
+        resource portion of the URL into execution of an appropriate
+        <a href="http://jakarta.apache.org/commons/chain";>Commons Chain</a>
+        <code>Chain</code> or <code>Command</code> from an appropriate
+        <code>Catalog</code>.</li>
 </ul>
 
 <p>The static resource serving <a href="Processor.html">Processor</a> 
implentations

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties?rev=366984&r1=366983&r2=366984&view=diff
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
 (original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/resources/Bundle.properties
 Sat Jan  7 20:47:04 2006
@@ -46,6 +46,15 @@
 # org.apache.shale.component.Token
 token.invalid=Invalid resubmit of the same form
 
+# org.apache.shale.dialog.faces.DialogNavigationHandler
+dialog.noDialog=You have requested a dialog named "{0}" but no such dialog 
definition can be found.  Double check the spelling of the dialog name.
+dialog.noNextState=You have requested a transition outcome named "{0}" from a 
state named "{1}" in a dialog named "{2}" to a new state named "{3}", but no 
state definition can be found.  Double check the spelling of the state name.
+dialog.noPreProcess=You have requested preprocessing for a state named "{0}", 
but the implementation class {1} is not of a known type (ActionState, EndState, 
SubdialogState, or ViewState).
+dialog.noPostProcess=You have requested postprocessing for a state named 
"{0}", but the implementation class "{1}" is not a ViewState.
+dialog.noState=You have requested a state named "{0}" in a dialog named "{1}" 
but no state definition can be found.  Double check the spelling of the state 
name.
+dialog.noTransition=You have requested a transition outcome named "{0}" from a 
state named "{1}" in a dialog named "{2}", but no transition definition can be 
found.  Double check the spelling of the transition outcome name.
+dialog.unconfigured=The configuration metadata for dialogs have not been 
loaded.  Did you configure the Shale application fiter in your web.xml resource?
+
 # org.apache.shale.tiles.TilesViewHandler
 tiles.renderingView=Rendering view {0}, looking for tile {1}
 tiles.dispatchingToTile=Dispatching to tile {0}

Added: 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java?rev=366984&view=auto
==============================================================================
--- 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java
 (added)
+++ 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java
 Sat Jan  7 20:47:04 2006
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.context.ResponseWriter;
+import org.apache.commons.chain.Command;
+import org.apache.commons.chain.Context;
+import org.apache.shale.remoting.faces.ResponseFactory;
+
+/**
+ * <p>Test <code>Command</code> implementation for
+ * <code>ChainProcessorTestCase</code>.</p>
+ */
+
+public class ChainProcessorCommand implements Command {
+    
+    
+    public boolean execute(Context context) throws Exception {
+
+        ChainContext ccontext = (ChainContext) context;
+        ResponseWriter writer =
+            (new ResponseFactory()).getResponseWriter
+                (ccontext.getFacesContext(), "text/x-plain");
+        writer.writeText("This is a test.  It is only a test.\n", null);
+        return false;
+
+    }
+
+
+}

Propchange: 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorCommand.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java?rev=366984&view=auto
==============================================================================
--- 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java
 (added)
+++ 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java
 Sat Jan  7 20:47:04 2006
@@ -0,0 +1,198 @@
+/*
+ * Copyright 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.servlet.http.HttpServletResponse;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.commons.chain.CatalogFactory;
+import org.apache.commons.chain.Context;
+import org.apache.commons.chain.impl.CatalogBase;
+import org.apache.shale.test.base.AbstractJsfTestCase;
+import org.apache.shale.test.mock.MockPrintWriter;
+
+/**
+ * <p>Test case for 
<code>org.apache.shale.remoting.impl.ClassResourceProcessor</code>.</p>
+ */
+public class ChainProcessorTestCase extends AbstractJsfTestCase {
+    
+
+    // ------------------------------------------------------------ 
Constructors
+
+
+    // Construct a new instance of this test case.
+    public ChainProcessorTestCase(String name) {
+        super(name);
+    }
+
+
+    // ------------------------------------------------------ Manifest 
Constants
+
+
+    /**
+     * <p>The valid content (up to the line delimiter) returned for the
+     * <code>testProcess()</code> test.</p>
+     */
+    private static final String PROCESS_CONTENT =
+            "This is a test.  It is only a test.";
+
+
+    // ----------------------------------------------------------- Setup 
Methods
+
+
+    // Set up instance variables for this test case.
+    public void setUp() {
+
+        super.setUp();
+        processor = new ChainProcessor();
+
+    }
+
+
+    // Return the tests included in this test case.
+    public static Test suite() {
+
+        return (new TestSuite(ChainProcessorTestCase.class));
+
+    }
+
+
+    // Tear down instance variables for this test case.
+    public void tearDown() {
+
+        processor = null;
+        super.tearDown();
+
+    }
+
+
+    // ------------------------------------------------------ Instance 
Variables
+
+
+    // The Processor instance to be tested
+    private ChainProcessor processor = null;
+
+
+    // ------------------------------------------------------------ Test 
Methods
+
+
+    // Test the createContext() method
+    public void testCreateContext() {
+
+        Context context = processor.createContext(facesContext, "/foo/bar");
+        assertNotNull(context);
+        assertTrue(context instanceof ChainContext);
+        assertTrue(facesContext == context.get("facesContext"));
+        assertTrue(facesContext == ((ChainContext) context).getFacesContext());
+
+    }
+
+
+    // Test the mapCatalog() method
+    public void testMapCataog() {
+
+        assertEquals("remoting", processor.mapCatalog(facesContext, 
"/foo/bar"));
+        assertEquals("remoting", processor.mapCatalog(facesContext, 
"/baz/bop"));
+
+    }
+
+
+    // Test the mapCommand() method
+    public void testMapCommand() {
+
+        assertEquals("foo.bar", processor.mapCommand(facesContext, 
"/foo/bar"));
+        assertEquals("baz.bop", processor.mapCommand(facesContext, 
"/baz/bop"));
+
+    }
+
+
+    // Test the situation where the mapped catalog is missing
+    public void testMissingCatalog() throws Exception {
+
+        processor.process(facesContext, "/foo/bar");
+        assertEquals(response.getStatus(), HttpServletResponse.SC_NOT_FOUND);
+        assertEquals(response.getMessage(), "/foo/bar");
+
+    }
+
+
+    // Test the situation where the mapped command is missing
+    public void testMissingCommand() throws Exception {
+
+        CatalogFactory.getInstance().addCatalog("remoting", new CatalogBase());
+        processor.process(facesContext, "/foo/bar");
+        assertEquals(response.getStatus(), HttpServletResponse.SC_NOT_FOUND);
+        assertEquals(response.getMessage(), "/foo/bar");
+
+    }
+
+
+    // Test a pristine instance
+    public void testPristine() throws Exception {
+
+        assertNotNull(processor);
+
+    }
+
+
+    // Test processing of a configured command
+    public void testProcess() throws Exception {
+
+        CatalogFactory.getInstance().addCatalog("remoting", new CatalogBase());
+        CatalogFactory.getInstance().getCatalog("remoting").
+                addCommand("foo.bar", new ChainProcessorCommand());
+        processor.process(facesContext, "/foo/bar");
+        assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
+        assertEquals("text/x-plain", response.getContentType());
+        MockPrintWriter writer = (MockPrintWriter) response.getWriter();
+        char content[] = writer.content();
+        assertNotNull(content);
+        assertTrue(content.length > PROCESS_CONTENT.length());
+        for (int i = 0; i < PROCESS_CONTENT.length(); i++) {
+            assertEquals("Character at position " + i, 
PROCESS_CONTENT.charAt(i), content[i]);
+        }
+
+    }
+
+
+    // Test the sendNotFound() method
+    public void testSendNotFound() throws Exception {
+
+        processor.sendNotFound(facesContext, "/foo/bar");
+        assertEquals(response.getStatus(), HttpServletResponse.SC_NOT_FOUND);
+        assertEquals(response.getMessage(), "/foo/bar");
+
+    }
+
+
+    // Test the sendServerError() method
+    public void testServerError() throws Exception {
+
+        processor.sendServerError(facesContext, "/foo/bar", new 
NullPointerException());
+        assertEquals(response.getStatus(), 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        assertEquals(response.getMessage(), "/foo/bar");
+
+    }
+
+
+
+
+    // --------------------------------------------------------- Support 
Methods
+
+
+
+}

Propchange: 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/shale/trunk/core-library/src/test/org/apache/shale/remoting/impl/ChainProcessorTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to