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]