Title: [waffle-scm] [115] trunk/core: WaffleXMLServlet is able to render ${controller} getters as XML through XStream

Diff

Modified: trunk/core/pom.xml (114 => 115)

--- trunk/core/pom.xml	2007-05-31 05:16:11 UTC (rev 114)
+++ trunk/core/pom.xml	2007-05-31 07:52:32 UTC (rev 115)
@@ -36,6 +36,10 @@
       <artifactId>jruby-complete</artifactId>
     </dependency>
     <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+    </dependency>
+    <dependency>
       <groupId>velocity</groupId>
       <artifactId>velocity</artifactId>
     </dependency>

Added: trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleXMLServlet.java (0 => 115)

--- trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleXMLServlet.java	                        (rev 0)
+++ trunk/core/src/main/java/org/codehaus/waffle/servlet/WaffleXMLServlet.java	2007-05-31 07:52:32 UTC (rev 115)
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (C) 2005,2006 Michael Ward                                      *
+ * All rights reserved.                                                      *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *                                                                           *
+ * Original code by: Michael Ward                                            *
+ *****************************************************************************/
+package org.codehaus.waffle.servlet;
+
+import org.codehaus.waffle.action.ActionMethodResponse;
+import org.codehaus.waffle.controller.ControllerDefinition;
+import org.codehaus.waffle.view.XMLView;
+
+/**
+ * Waffle's FrontController for XML serialization.
+ * 
+ * @author Paulo Silveira
+ */
+public class WaffleXMLServlet extends WaffleServlet {
+
+	protected void buildViewToReferrer(
+			ControllerDefinition controllerDefinition,
+			ActionMethodResponse actionMethodResponse) {
+		actionMethodResponse.setReturnValue(new XMLView());
+	}
+}

Modified: trunk/core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java (114 => 115)

--- trunk/core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java	2007-05-31 05:16:11 UTC (rev 114)
+++ trunk/core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java	2007-05-31 07:52:32 UTC (rev 115)
@@ -20,6 +20,7 @@
  * The ViewDispatcher handles redirecting/forwarding to the view
  *
  * @author Michael Ward
+ * @author Paulo Silveira
  */
 public class DefaultViewDispatcher implements ViewDispatcher {
     private final ViewResolver viewResolver;
@@ -39,7 +40,9 @@
         if (view instanceof RedirectView) {
             Map model = ((RedirectView)view).getModel();
             dispatchAssistant.redirect(request, response, model, url);
-        } else {
+        } else if (view instanceof ResponderView) {
+        	((ResponderView)view).respond(request, response);
+        }else {
             dispatchAssistant.forward(request, response, url);
         }
     }

Added: trunk/core/src/test/java/org/codehaus/waffle/servlet/WaffleXMLServletTest.java (0 => 115)

--- trunk/core/src/test/java/org/codehaus/waffle/servlet/WaffleXMLServletTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/codehaus/waffle/servlet/WaffleXMLServletTest.java	2007-05-31 07:52:32 UTC (rev 115)
@@ -0,0 +1,20 @@
+package org.codehaus.waffle.servlet;
+
+import org.codehaus.waffle.action.ActionMethodResponse;
+import org.codehaus.waffle.view.XMLView;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class WaffleXMLServletTest {
+
+	@Test
+	public void testOverridenActionMethodResponse() {
+		ActionMethodResponse response = new ActionMethodResponse();
+		response.setReturnValue("a value that will be overriden....");
+		
+		WaffleXMLServlet servlet = new WaffleXMLServlet();
+		servlet.buildViewToReferrer(null, response);
+		Assert.assertTrue((response.getReturnValue() instanceof XMLView));
+	}
+
+}

Modified: trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java (114 => 115)

--- trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java	2007-05-31 05:16:11 UTC (rev 114)
+++ trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java	2007-05-31 07:52:32 UTC (rev 115)
@@ -5,81 +5,120 @@
 import java.util.Map;
 
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 /**
  * @author Michael Ward
  * @author Mauro Talevi
+ * @author Paulo Silveira
  */
 @RunWith(JMock.class)
 public class DefaultViewDispatcherTest {
-    private static final String PATH = "/foobar.html";
-    private Mockery mockery = new Mockery();
-    private HttpServletRequest mockRequest = mockRequest();
-    private HttpServletResponse mockResponse = mockResponse();
+	private static final String PATH = "/foobar.html";
 
-    @Test
-    public void testDispatchCalled() throws IOException, ServletException {
+	private Mockery mockery = new Mockery();
 
-        Map model = new HashMap();
-        RedirectView redirectView = new RedirectView(PATH, null, model);
-        ViewResolver viewResolver = mockViewResolver(redirectView, PATH);
-        DispatchAssistant dispatchAssistant = mockDispatchAssistant(model, PATH);
+	private HttpServletRequest mockRequest = mockRequest();
 
-        DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(viewResolver, dispatchAssistant);
-        viewDispatcher.dispatch(mockRequest, mockResponse, redirectView);
-    }
+	private HttpServletResponse mockResponse = mockResponse();
 
-    @Test
-    public void testForwardCalled() throws IOException, ServletException {
-        View view = new View(PATH, null);
-        ViewResolver viewResolver = mockViewResolver(view, PATH);
-        DispatchAssistant dispatchAssistant = mockDispatchAssistant(null, PATH);
+	class SomeResponderView extends ResponderView {
 
-        DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(viewResolver, dispatchAssistant);
-        viewDispatcher.dispatch(mockRequest, mockResponse, view);
-    }
+		private boolean responded = false;
 
-    private DispatchAssistant mockDispatchAssistant(final Map model, final String path) throws IOException, ServletException {
-        final DispatchAssistant dispatchAssistant = mockery.mock(DispatchAssistant.class);
-        Expectations expectations = new Expectations() {
-            {
-                if (model != null) {
-                    allowing(dispatchAssistant).redirect(mockRequest, mockResponse, model, path);
-                } else {
-                    allowing(dispatchAssistant).forward(mockRequest, mockResponse, path);
-                }
-            }
-        };
-        mockery.checking(expectations);
-        return dispatchAssistant;
-    }
+		@Override
+		public void respond(ServletRequest req, HttpServletResponse resp)
+				throws IOException {
+			responded = true;
+		}
 
-    private ViewResolver mockViewResolver(final View view, final String path) {
-        final ViewResolver viewResolver = mockery.mock(ViewResolver.class);
-        Expectations expectations = new Expectations() {
-            {
-                allowing(viewResolver).resolve(view);
-                will(returnValue(path));
-            }
-        };
-        mockery.checking(expectations);
-        return viewResolver;
-    }
+		public boolean isResponded() {
+			return responded;
+		}
+	}
 
-    private HttpServletResponse mockResponse() {
-        return mockery.mock(HttpServletResponse.class);
-    }
+	@Test
+	public void testRespondCalled() throws IOException, ServletException {
+		SomeResponderView view = new SomeResponderView();
 
-    private HttpServletRequest mockRequest() {
-        return mockery.mock(HttpServletRequest.class);
-    }
+		ViewResolver viewResolver = mockViewResolver(view, PATH);
 
+		DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(
+				viewResolver, null);
+		viewDispatcher.dispatch(mockRequest, mockResponse, view);
+		Assert.assertTrue(view.isResponded());
+	}
+
+	@Test
+	public void testDispatchCalled() throws IOException, ServletException {
+
+		Map model = new HashMap();
+		RedirectView redirectView = new RedirectView(PATH, null, model);
+		ViewResolver viewResolver = mockViewResolver(redirectView, PATH);
+		DispatchAssistant dispatchAssistant = mockDispatchAssistant(model, PATH);
+
+		DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(
+				viewResolver, dispatchAssistant);
+		viewDispatcher.dispatch(mockRequest, mockResponse, redirectView);
+	}
+
+	@Test
+	public void testForwardCalled() throws IOException, ServletException {
+		View view = new View(PATH, null);
+		ViewResolver viewResolver = mockViewResolver(view, PATH);
+		DispatchAssistant dispatchAssistant = mockDispatchAssistant(null, PATH);
+
+		DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher(
+				viewResolver, dispatchAssistant);
+		viewDispatcher.dispatch(mockRequest, mockResponse, view);
+	}
+
+	private DispatchAssistant mockDispatchAssistant(final Map model,
+			final String path) throws IOException, ServletException {
+		final DispatchAssistant dispatchAssistant = mockery
+				.mock(DispatchAssistant.class);
+		Expectations expectations = new Expectations() {
+			{
+				if (model != null) {
+					allowing(dispatchAssistant).redirect(mockRequest,
+							mockResponse, model, path);
+				} else {
+					allowing(dispatchAssistant).forward(mockRequest,
+							mockResponse, path);
+				}
+			}
+		};
+		mockery.checking(expectations);
+		return dispatchAssistant;
+	}
+
+	private ViewResolver mockViewResolver(final View view, final String path) {
+		final ViewResolver viewResolver = mockery.mock(ViewResolver.class);
+		Expectations expectations = new Expectations() {
+			{
+				allowing(viewResolver).resolve(view);
+				will(returnValue(path));
+			}
+		};
+		mockery.checking(expectations);
+		return viewResolver;
+	}
+
+	private HttpServletResponse mockResponse() {
+		return mockery.mock(HttpServletResponse.class);
+	}
+
+	private HttpServletRequest mockRequest() {
+		return mockery.mock(HttpServletRequest.class);
+	}
+
 }

Added: trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java (0 => 115)

--- trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java	2007-05-31 07:52:32 UTC (rev 115)
@@ -0,0 +1,206 @@
+package org.codehaus.waffle.view;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GetterXMLConverterTest {
+
+	@Test
+	public void testChecksIfGetIsAGetter() throws SecurityException,
+			NoSuchMethodException {
+		Method get = GetterXMLConverterTestClass.class.getMethod("get",
+				new Class[0]);
+		Assert.assertFalse(GetterXMLConverter.isGetter(get));
+	}
+
+	@Test
+	public void testChecksIfIsIsAGetter() throws SecurityException,
+			NoSuchMethodException {
+		Method is = GetterXMLConverterTestClass.class.getMethod("is",
+				new Class[0]);
+		Assert.assertFalse(GetterXMLConverter.isGetter(is));
+	}
+
+	@Test
+	public void testChecksIfANonReturnMethodIsAGetter()
+			throws SecurityException, NoSuchMethodException {
+		Method getVoidProperty = GetterXMLConverterTestClass.class.getMethod(
+				"getVoidProperty", new Class[0]);
+		Assert.assertFalse(GetterXMLConverter.isGetter(getVoidProperty));
+	}
+
+	@Test
+	public void testChecksIfAMethodWhichReceivesAParameterIsAGetter()
+			throws SecurityException, NoSuchMethodException {
+		Method getBizarre = GetterXMLConverterTestClass.class.getMethod(
+				"getBizarre", new Class[] { Integer.TYPE });
+		Assert.assertFalse(GetterXMLConverter.isGetter(getBizarre));
+	}
+
+	@Test
+	public void testChecksIfAMethodNotStartingWithGetIsAGetter()
+			throws SecurityException, NoSuchMethodException {
+		Method bizarreGetter3 = GetterXMLConverterTestClass.class.getMethod(
+				"bizarreGetter3", new Class[0]);
+		Assert.assertFalse(GetterXMLConverter.isGetter(bizarreGetter3));
+	}
+
+	@Test
+	public void testChecksIfAnIsMethodReturningStringIsAGetter()
+			throws SecurityException, NoSuchMethodException {
+		Method isBizarre = GetterXMLConverterTestClass.class.getMethod(
+				"isBizarre", new Class[0]);
+		Assert.assertFalse(GetterXMLConverter.isGetter(isBizarre));
+	}
+
+	@Test
+	public void testChecksForAValidGetter() throws SecurityException,
+			NoSuchMethodException {
+		Method getInternal = GetterXMLConverterTestClass.class.getMethod(
+				"getInternal", new Class[0]);
+		Assert.assertTrue(GetterXMLConverter.isGetter(getInternal));
+	}
+
+	@Test
+	public void testChecksForAValidIs() throws SecurityException,
+			NoSuchMethodException {
+		Method isClosed = GetterXMLConverterTestClass.class.getMethod(
+				"isClosed", new Class[0]);
+		Assert.assertTrue(GetterXMLConverter.isGetter(isClosed));
+	}
+
+	@Test
+	public void testChecksForAStaticMethodGetter() throws SecurityException,
+			NoSuchMethodException {
+		Method getStatic = GetterXMLConverterTestClass.class.getMethod(
+				"getStatic", new Class[0]);
+		Assert.assertFalse(GetterXMLConverter.isGetter(getStatic));
+	}
+
+	@Test
+	public void testGetGettersIgnoresGetClass() {
+		Map<String, Method> x = GetterXMLConverter
+				.getGetters(GetterXMLConverterTestClass.class);
+		Assert.assertFalse(x.containsKey("class"));
+	}
+
+	@Test
+	public void testGetGettersIgnoresGettersAndIsersWithoutAName() {
+		Map<String, Method> x = GetterXMLConverter
+				.getGetters(GetterXMLConverterTestClass.class);
+		Assert.assertFalse(x.containsKey(""));
+	}
+
+	@Test
+	public void testGetGettersIgnoresGettersReturningVoid() {
+		Map<String, Method> x = GetterXMLConverter
+				.getGetters(GetterXMLConverterTestClass.class);
+		Assert.assertFalse(x.containsKey("voidProperty"));
+	}
+
+	@Test
+	public void testGetGettersFindsIs() {
+		Map<String, Method> x = GetterXMLConverter
+				.getGetters(GetterXMLConverterTestClass.class);
+		Assert.assertTrue(x.containsKey("closed"));
+	}
+
+	@Test
+	public void testGetGettersForCapsPROPERTIES() {
+		Map<String, Method> x = GetterXMLConverter
+				.getGetters(GetterXMLConverterTestClass.class);
+		Assert.assertTrue(x.containsKey("URLocationFoo"));
+	}
+
+	@Test
+	public void testGetGettersForFieldWithLiength1() {
+		Map<String, Method> x = GetterXMLConverter
+				.getGetters(GetterXMLConverterTestClass.class);
+		Assert.assertTrue(x.containsKey("a"));
+	}
+
+	public static class GetterXMLConverterTestClass {
+
+		@SuppressWarnings("unused")
+		private int internal;
+
+		private boolean closed;
+
+		public int getA() {
+			return 0;
+		}
+
+		public void getVoidProperty() {
+		}
+
+		public void simpleMethod() {
+		}
+
+		public String getURLocationFoo() {
+			return "";
+		}
+
+		public String is() {
+			return null;
+		}
+
+		public void simpleWrongMethod() {
+			@SuppressWarnings("unused")
+			int i = 1 / 0;
+		}
+
+		public void argumentMethod(int i) {
+		}
+
+		public String isBizarre() {
+			return null;
+		}
+
+		@SuppressWarnings("unused")
+		private String value;
+
+		public void setValue(String value) {
+			this.value = value;
+		}
+
+		public static int getStatic() {
+			return 0;
+		}
+
+		protected int getProtected() {
+			return 0;
+		}
+
+		public int getInternal() {
+			return internal;
+		}
+
+		public boolean isClosed() {
+			return closed;
+		}
+
+		public void bizarreGetter1() {
+		}
+
+		public int bizarreGetter2(int x) {
+			return x;
+		}
+
+		public int bizarreGetter3() {
+			return 0;
+		}
+
+		public int getBizarre(int x) {
+			return x;
+		}
+
+		public void get() {
+
+		}
+
+	}
+
+}

Added: trunk/core/src/test/java/org/codehaus/waffle/view/XMLViewTest.java (0 => 115)

--- trunk/core/src/test/java/org/codehaus/waffle/view/XMLViewTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/codehaus/waffle/view/XMLViewTest.java	2007-05-31 07:52:32 UTC (rev 115)
@@ -0,0 +1,222 @@
+package org.codehaus.waffle.view;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.codehaus.waffle.Constants;
+import org.jmock.Expectations;
+import org.jmock.MockObjectTestCase;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.thoughtworks.xstream.converters.javabean.BeanProperty;
+import com.thoughtworks.xstream.converters.javabean.PropertyDictionary;
+
+/**
+ * 
+ * @author Paulo Silveira
+ * 
+ */
[EMAIL PROTECTED](JMock.class)
+public class XMLViewTest extends MockObjectTestCase {
+
+	private Mockery mockery = new Mockery();
+
+	private HttpServletRequest mockRequest = mockRequest();
+
+	private HttpServletResponse mockResponse = mockResponse();
+
+	private MockServletOutputStream mockOutput = new MockServletOutputStream();
+
+	@Test
+	public void testStripsPackageNameForNonAliasedType() throws IOException {
+		final MyObject object = new MyObject();
+
+		buildExpectationsFor(object);
+
+		new XMLView().respond(mockRequest, mockResponse);
+		assertEquals("<MyObject/>", mockOutput.getContent());
+	}
+
+	@Test
+	public void testObjectsWithRelationships() throws IOException {
+		final MyOtherObject object = new MyOtherObject();
+
+		buildExpectationsFor(object);
+
+		new XMLView().respond(mockRequest, mockResponse);
+		assertEquals("<MyOtherObject>\n  <myGetter/>\n</MyOtherObject>",
+				mockOutput.getContent());
+	}
+
+	@Test
+	public void testObjectsWithRelationshipsAndNullAttributes()
+			throws IOException {
+		final MyOtherObject object = new MyOtherObject();
+		object.my = null;
+
+		buildExpectationsFor(object);
+
+		new XMLView().respond(mockRequest, mockResponse);
+		assertEquals("<MyOtherObject>\n  <myGetter/>\n</MyOtherObject>",
+				mockOutput.getContent());
+	}
+
+	@Test
+	public void testObjectsCollections() throws IOException {
+		final BeanWithCollection object = new BeanWithCollection();
+		buildExpectationsFor(object);
+
+		new XMLView().respond(mockRequest, mockResponse);
+		assertEquals(
+				"<BeanWithCollection>\n  <collection>\n    <MyObject/>\n    <MyObject/>\n  </collection>\n</BeanWithCollection>",
+				mockOutput.getContent());
+	}
+
+	@Test
+	public void testDoesntStripPackageNameForWrapperTypes() throws IOException {
+		final Number[] numbers = new Number[] { new Byte((byte) 0),
+				new Short((short) 0), new Integer(0), new Long(0),
+				new Float(0), new Double(0) };
+		String expected = "<number-array>\n" + "  <byte>0</byte>\n"
+				+ "  <short>0</short>\n" + "  <int>0</int>\n"
+				+ "  <long>0</long>\n" + "  <float>0.0</float>\n"
+				+ "  <double>0.0</double>\n" + "</number-array>";
+
+		buildExpectationsFor(numbers);
+
+		new XMLView().respond(mockRequest, mockResponse);
+		assertEquals(expected, mockOutput.getContent());
+	}
+
+	private void buildExpectationsFor(final Object object) throws IOException {
+		Expectations expectations = new Expectations() {
+			{
+				one(mockRequest).getAttribute(Constants.CONTROLLER_KEY);
+				will(returnValue(object));
+				one(mockResponse).setContentType(with(any(String.class)));
+				one(mockResponse).getOutputStream();
+				will(returnValue(mockOutput));
+			}
+		};
+		mockery.checking(expectations);
+	}
+
+	private HttpServletResponse mockResponse() {
+		return mockery.mock(HttpServletResponse.class);
+	}
+
+	private HttpServletRequest mockRequest() {
+		return mockery.mock(HttpServletRequest.class);
+	}
+
+	// JMock 2 is not able to mock concrete classes yet
+	class MockServletOutputStream extends ServletOutputStream {
+		private String content;
+
+		public void write(int b) {
+
+		}
+
+		@Override
+		public void print(String s) {
+			this.content = s;
+		}
+
+		public String getContent() {
+			return content;
+		}
+	}
+
+	class SomeClass {
+		private String a;
+
+		private String URL;
+
+		private String c;
+
+		private String d;
+
+		private String e;
+
+		private String f;
+
+		public String getA() {
+			return a;
+		}
+
+		public void setA(String a) {
+			this.a = a;
+		}
+
+		public String getURL() {
+			return URL;
+		}
+
+		public void setURL(String url) {
+			this.URL = ""
+		}
+
+		public String getC() {
+			return c;
+		}
+
+		public void setC(String c) {
+			this.c = c;
+		}
+
+		public String getD() {
+			return d;
+		}
+
+		public void setE(String e) {
+			this.e = e;
+		}
+	}
+
+	@Test
+	public void testListsFieldsInClassInDefinitionOrder() {
+		Iterator properties = new PropertyDictionary()
+				.serializablePropertiesFor(SomeClass.class);
+		assertEquals("URL", ((BeanProperty) properties.next()).getName());
+		assertEquals("a", ((BeanProperty) properties.next()).getName());
+		assertEquals("c", ((BeanProperty) properties.next()).getName());
+		assertFalse("No more fields should be present", properties.hasNext());
+	}
+
+}
+
+class MyOtherObject {
+	MyObject my = new MyObject();
+
+	public MyObject getMyGetter() {
+		return my;
+	}
+}
+
+class MyObject {
+
+}
+
+class BeanWithCollection {
+
+	private Map<Object, Object> map = new HashMap<Object, Object>();
+	{
+		map.put("1", new MyObject());
+		map.put("2", new MyObject());
+	}
+
+	public Collection<Object> getCollection() {
+		return map.values();
+	}
+
+}
\ No newline at end of file


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to