- Revision
- 115
- Author
- paulosilveira
- Date
- 2007-05-31 02:52:32 -0500 (Thu, 31 May 2007)
Log Message
WaffleXMLServlet is able to render ${controller} getters as XML through XStreamModified Paths
- trunk/core/pom.xml
- trunk/core/src/main/java/org/codehaus/waffle/view/DefaultViewDispatcher.java
- trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java
Added Paths
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:
