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]