- Revision
- 129
- Author
- mward
- Date
- 2007-06-01 23:09:52 -0500 (Fri, 01 Jun 2007)
Log Message
simplified GetterXMLConverter to use Introspector
Modified Paths
- trunk/core/src/main/java/org/codehaus/waffle/view/GetterXMLConverter.java
- trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java
- trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java
- trunk/examples/jruby-example/src/main/ruby/ruby/foo_bar.rb
Diff
Modified: trunk/core/src/main/java/org/codehaus/waffle/view/GetterXMLConverter.java (128 => 129)
--- trunk/core/src/main/java/org/codehaus/waffle/view/GetterXMLConverter.java 2007-06-01 14:09:52 UTC (rev 128) +++ trunk/core/src/main/java/org/codehaus/waffle/view/GetterXMLConverter.java 2007-06-02 04:09:52 UTC (rev 129) @@ -6,118 +6,58 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Map; -import java.util.TreeMap; /** * Used to make XStream use bean getters to serialize, no attributes * * @author Paulo Silveira + * @author Michael Ward */ public class GetterXMLConverter implements Converter { - private static final String IS_INITIALS = "is"; - private static final String GET_INITIALS = "get"; - private static final Object[] NO_ARGUMENTS = {}; - public void marshal(Object object, HierarchicalStreamWriter writer, - MarshallingContext context) { + public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) { + try { + BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); - Map<String, Method> getters = getGetters(object.getClass()); - for (String name : getters.keySet()) { - Method getter = getters.get(name); - writer.startNode(name); - try { - Object got = getter.invoke(object, NO_ARGUMENTS); - if (got != null) { - context.convertAnother(got); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + Method readMethod = propertyDescriptor.getReadMethod(); + + // skip getClass() method and any get/is methods that take arguments + if (readMethod.getParameterTypes().length == 0 && !readMethod.getName().equals("getClass")) { + writer.startNode(propertyDescriptor.getName()); + Object got = readMethod.invoke(object); + + if (got != null) { + context.convertAnother(got); + } + + writer.endNode(); } - } catch (IllegalArgumentException e) { - throw new IllegalStateException(e); - } catch (IllegalAccessException e) { - throw new IllegalStateException(e); - } catch (InvocationTargetException e) { - throw new IllegalStateException(e); } - writer.endNode(); + } catch (IllegalArgumentException e) { + throw new IllegalStateException(e); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } catch (InvocationTargetException e) { + throw new IllegalStateException(e); + } catch (IntrospectionException e) { + throw new IllegalStateException(e); } } public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) { - throw new UnsupportedOperationException( - "Converter only available for marshaling"); + throw new UnsupportedOperationException("Converter only available for marshaling"); } public boolean canConvert(Class clazz) { return true; } - - public static Map<String, Method> getGetters(Class clazz) { - Map<String, Method> methods = new TreeMap<String, Method>(); - for (Method m : clazz.getMethods()) { - if (!isGetter(m)) { - continue; - } - if (m.getDeclaringClass().equals(Object.class)) { - // hack: removing getClass() - continue; - } - String propertyName = ""; - if (m.getName().startsWith(GET_INITIALS)) { - propertyName = m.getName().substring(GET_INITIALS.length()); - - } else if (m.getName().startsWith(IS_INITIALS)) { - propertyName = m.getName().substring(IS_INITIALS.length()); - } - // ok, this is a hack, cause we can have a problem - // with classes with a get() method - // (the propertyname would be an empty string) - if (propertyName.length() != 0) { - if (propertyName.length() == 1 - || Character.isLowerCase(propertyName.charAt(1))) { - propertyName = decapitalize(propertyName); - } - methods.put(propertyName, m); - } - } - return methods; - } - - private static String decapitalize(String name) { - if (name == null || name.length() == 0) { - return name; - } - if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) - && Character.isUpperCase(name.charAt(0))) { - return name; - } - char chars[] = name.toCharArray(); - chars[0] = Character.toLowerCase(chars[0]); - return new String(chars); - } - - public static boolean isGetter(Method method) { - if (method.getParameterTypes().length != 0 - || !Modifier.isPublic(method.getModifiers()) - || method.getReturnType().equals(Void.TYPE)) { - return false; - } - if (Modifier.isStatic(method.getModifiers()) - || !Modifier.isPublic(method.getModifiers()) - || Modifier.isAbstract(method.getModifiers())) { - return false; - } - if (method.getName().startsWith(GET_INITIALS) - && method.getName().length() > GET_INITIALS.length()) { - return true; - } - return method.getName().startsWith(IS_INITIALS) - && method.getName().length() > IS_INITIALS.length() - && (method.getReturnType().equals(boolean.class) || method - .getReturnType().equals(Boolean.class)); - } - }
Modified: trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java (128 => 129)
--- trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java 2007-06-01 14:09:52 UTC (rev 128) +++ trunk/core/src/test/java/org/codehaus/waffle/view/DefaultViewDispatcherTest.java 2007-06-02 04:09:52 UTC (rev 129) @@ -1,14 +1,5 @@ package org.codehaus.waffle.view; -import java.io.IOException; -import java.util.HashMap; -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; @@ -16,6 +7,14 @@ import org.junit.Test; import org.junit.runner.RunWith; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + /** * @author Michael Ward * @author Mauro Talevi @@ -23,102 +22,98 @@ */ @RunWith(JMock.class) public class DefaultViewDispatcherTest { - private static final String PATH = "/foobar.html"; + private static final String PATH = "/foobar.html"; + private final Mockery mockery = new Mockery(); + private final HttpServletRequest mockRequest = mockRequest(); + private final HttpServletResponse mockResponse = mockResponse(); - private Mockery mockery = new Mockery(); + class SomeResponderView extends ResponderView { - private HttpServletRequest mockRequest = mockRequest(); + private boolean responded = false; - private HttpServletResponse mockResponse = mockResponse(); + @Override + public void respond(ServletRequest req, HttpServletResponse resp) + throws IOException { + responded = true; + } - class SomeResponderView extends ResponderView { + public boolean isResponded() { + return responded; + } + } - private boolean responded = false; + @Test + public void testRespondCalled() throws IOException, ServletException { + SomeResponderView view = new SomeResponderView(); - @Override - public void respond(ServletRequest req, HttpServletResponse resp) - throws IOException { - responded = true; - } + ViewResolver viewResolver = mockViewResolver(view, PATH); - public boolean isResponded() { - return responded; - } - } + DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher( + viewResolver, null); + viewDispatcher.dispatch(mockRequest, mockResponse, view); + Assert.assertTrue(view.isResponded()); + } - @Test - public void testRespondCalled() throws IOException, ServletException { - SomeResponderView view = new SomeResponderView(); + @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); - ViewResolver viewResolver = mockViewResolver(view, PATH); + DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher( + viewResolver, dispatchAssistant); + viewDispatcher.dispatch(mockRequest, mockResponse, redirectView); + } - DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher( - viewResolver, null); - viewDispatcher.dispatch(mockRequest, mockResponse, view); - Assert.assertTrue(view.isResponded()); - } + @Test + public void testForwardCalled() throws IOException, ServletException { + View view = new View(PATH, null); + ViewResolver viewResolver = mockViewResolver(view, PATH); + DispatchAssistant dispatchAssistant = mockDispatchAssistant(null, PATH); - @Test - public void testDispatchCalled() throws IOException, ServletException { + DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher( + viewResolver, dispatchAssistant); + viewDispatcher.dispatch(mockRequest, mockResponse, view); + } - Map model = new HashMap(); - RedirectView redirectView = new RedirectView(PATH, null, model); - ViewResolver viewResolver = mockViewResolver(redirectView, PATH); - DispatchAssistant dispatchAssistant = mockDispatchAssistant(model, PATH); + 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; + } - DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher( - viewResolver, dispatchAssistant); - viewDispatcher.dispatch(mockRequest, mockResponse, redirectView); - } + 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; + } - @Test - public void testForwardCalled() throws IOException, ServletException { - View view = new View(PATH, null); - ViewResolver viewResolver = mockViewResolver(view, PATH); - DispatchAssistant dispatchAssistant = mockDispatchAssistant(null, PATH); + private HttpServletResponse mockResponse() { + return mockery.mock(HttpServletResponse.class); + } - DefaultViewDispatcher viewDispatcher = new DefaultViewDispatcher( - viewResolver, dispatchAssistant); - viewDispatcher.dispatch(mockRequest, mockResponse, view); - } + private HttpServletRequest mockRequest() { + return mockery.mock(HttpServletRequest.class); + } - 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); - } - }
Modified: trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java (128 => 129)
--- trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java 2007-06-01 14:09:52 UTC (rev 128) +++ trunk/core/src/test/java/org/codehaus/waffle/view/GetterXMLConverterTest.java 2007-06-02 04:09:52 UTC (rev 129) @@ -1,196 +1,45 @@ package org.codehaus.waffle.view; +import com.thoughtworks.xstream.XStream; +import org.codehaus.waffle.testmodel.FakeBean; import org.junit.Assert; import org.junit.Test; -import java.lang.reflect.Method; -import java.util.Map; - public class GetterXMLConverterTest { @Test - public void testChecksIfGetIsAGetter() throws SecurityException, - NoSuchMethodException { - Method get = GetterXMLConverterTestClass.class.getMethod("get"); - Assert.assertFalse(GetterXMLConverter.isGetter(get)); - } + public void unmarshalShouldThrowUnsupportedOperationException() { + GetterXMLConverter getterXMLConverter = new GetterXMLConverter(); - @Test - public void testChecksIfIsIsAGetter() throws SecurityException, - NoSuchMethodException { - Method is = GetterXMLConverterTestClass.class.getMethod("is"); - Assert.assertFalse(GetterXMLConverter.isGetter(is)); + try { + getterXMLConverter.unmarshal(null, null); + Assert.fail("UnsupportedOperationException expected"); + } catch (UnsupportedOperationException expected) { + // expected + } } @Test - public void testChecksIfANonReturnMethodIsAGetter() - throws SecurityException, NoSuchMethodException { - Method getVoidProperty = GetterXMLConverterTestClass.class.getMethod("getVoidProperty"); - Assert.assertFalse(GetterXMLConverter.isGetter(getVoidProperty)); + public void convertShouldAlwaysBeTrue() { + GetterXMLConverter getterXMLConverter = new GetterXMLConverter(); + Assert.assertTrue(getterXMLConverter.canConvert(this.getClass())); } @Test - public void testChecksIfAMethodWhichReceivesAParameterIsAGetter() - throws SecurityException, NoSuchMethodException { - Method getBizarre = GetterXMLConverterTestClass.class.getMethod("getBizarre", Integer.TYPE); - Assert.assertFalse(GetterXMLConverter.isGetter(getBizarre)); - } + public void testMarshall() { + XStream xStream = new XStream(); + xStream.registerConverter(new GetterXMLConverter(), -19); - @Test - public void testChecksIfAMethodNotStartingWithGetIsAGetter() - throws SecurityException, NoSuchMethodException { - Method bizarreGetter3 = GetterXMLConverterTestClass.class.getMethod("bizarreGetter3"); - Assert.assertFalse(GetterXMLConverter.isGetter(bizarreGetter3)); - } + FakeBean fakeBean = new FakeBean(); + String xml = xStream.toXML(fakeBean); - @Test - public void testChecksIfAnIsMethodReturningStringIsAGetter() - throws SecurityException, NoSuchMethodException { - Method isBizarre = GetterXMLConverterTestClass.class.getMethod("isBizarre"); - Assert.assertFalse(GetterXMLConverter.isGetter(isBizarre)); - } + String expected = + "<org.codehaus.waffle.testmodel.FakeBean>\n" + + " <count>0</count>\n" + + " <list/>\n" + + "</org.codehaus.waffle.testmodel.FakeBean>"; - @Test - public void testChecksForAValidGetter() throws SecurityException, - NoSuchMethodException { - Method getInternal = GetterXMLConverterTestClass.class.getMethod("getInternal"); - Assert.assertTrue(GetterXMLConverter.isGetter(getInternal)); + Assert.assertEquals(expected, xml); } - @Test - public void testChecksForAValidIs() throws SecurityException, - NoSuchMethodException { - Method isClosed = GetterXMLConverterTestClass.class.getMethod("isClosed"); - Assert.assertTrue(GetterXMLConverter.isGetter(isClosed)); - } - - @Test - public void testChecksForAStaticMethodGetter() throws SecurityException, - NoSuchMethodException { - Method getStatic = GetterXMLConverterTestClass.class.getMethod("getStatic"); - 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() { - - } - - } - }
Modified: trunk/examples/jruby-example/src/main/ruby/ruby/foo_bar.rb (128 => 129)
--- trunk/examples/jruby-example/src/main/ruby/ruby/foo_bar.rb 2007-06-01 14:09:52 UTC (rev 128) +++ trunk/examples/jruby-example/src/main/ruby/ruby/foo_bar.rb 2007-06-02 04:09:52 UTC (rev 129) @@ -12,15 +12,14 @@ #{session['waffle.session.container']} #{session.getServletContext().getRealPath('/WEB-INF/')} - - -YES } rescue Exception => e - return e + "ERROR #{e}" end end + def bar "HELLO WORLD #{request.local_name} #{request.local_port}" end + end \ No newline at end of file
To unsubscribe from this list please visit:
