Return-Path: Delivered-To: apmail-jakarta-ant-dev-archive@apache.org Received: (qmail 35148 invoked from network); 20 Feb 2002 11:54:09 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 20 Feb 2002 11:54:09 -0000 Received: (qmail 27225 invoked by uid 97); 20 Feb 2002 11:53:56 -0000 Delivered-To: qmlist-jakarta-archive-ant-dev@jakarta.apache.org Received: (qmail 27111 invoked by uid 97); 20 Feb 2002 11:53:56 -0000 Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Ant Developers List" Reply-To: "Ant Developers List" Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 27067 invoked by uid 97); 20 Feb 2002 11:53:55 -0000 Date: 20 Feb 2002 11:53:55 -0000 Message-ID: <20020220115355.93142.qmail@icarus.apache.org> From: bodewig@apache.org To: jakarta-ant-cvs@apache.org Subject: cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant IntrospectionHelperTest.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N bodewig 02/02/20 03:53:55 Modified: src/main/org/apache/tools/ant IntrospectionHelper.java src/testcases/org/apache/tools/ant IntrospectionHelperTest.java Log: simplify createAttributeSetter method. Submitted by: Jon Skeet Throw in some additional tests. Revision Changes Path 1.34 +38 -73 jakarta-ant/src/main/org/apache/tools/ant/IntrospectionHelper.java Index: IntrospectionHelper.java =================================================================== RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- IntrospectionHelper.java 20 Feb 2002 10:03:42 -0000 1.33 +++ IntrospectionHelper.java 20 Feb 2002 11:53:55 -0000 1.34 @@ -119,6 +119,24 @@ */ private static Hashtable helpers = new Hashtable(); + /** + * Map from primitive types to wrapper classes for use in + * createAttributeSetter (Class to Class). Note that char + * and boolean are in here even though they get special treatment + * - this way we only need to test for the wrapper class. + */ + private static final Hashtable PRIMITIVE_TYPE_MAP = new Hashtable(8); + + // Set up PRIMITIVE_TYPE_MAP + static { + Class[] primitives = {Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE, + Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE}; + Class[] wrappers = {Boolean.class, Byte.class, Character.class, Short.class, + Integer.class, Long.class, Float.class, Double.class}; + for (int i=0; i < primitives.length; i++) + PRIMITIVE_TYPE_MAP.put (primitives[i], wrappers[i]); + } + // XXX: (Jon Skeet) The documentation below doesn't draw a clear // distinction between addConfigured and add. It's obvious what the // code *here* does (addConfigured sets both a creator method which @@ -607,14 +625,6 @@ } /** - // XXX: (Jon Skeet) This method implementation could be made much simpler - // using a mapping from Integer.TYPE to Integer.class etc, so - // that when a primitive type is given, the wrapper is just - // automatically used. This would then fall through to the "worst case" - // where a string constructor is used - but this is what happens - // for Integer etc anyway. There would be a slight speed difference (due - // to using reflection where it's currently not being used), but the - // size of the code for this method would be reduced by 50 lines :) * Creates an implementation of AttributeSetter for the given * attribute type. Conversions (where necessary) are automatically * made for the following types: @@ -637,17 +647,20 @@ * * @param m The method to invoke on the bean when the setter is invoked. * Must not be null. - * @param arg The type of the single argument passed to the bean's method - * when the returned setter is invoked. + * @param arg The type of the single argument of the bean's method. + * Must not be null. * * @return an appropriate AttributeSetter instance, or null * if no appropriate conversion is available. */ private AttributeSetter createAttributeSetter(final Method m, - final Class arg) { + Class arg) { + // use wrappers for primitive classes, e.g. int and Integer are treated identically + final Class reflectedArg = PRIMITIVE_TYPE_MAP.containsKey (arg) ? + (Class) PRIMITIVE_TYPE_MAP.get(arg) : arg; // simplest case - setAttribute expects String - if (java.lang.String.class.equals(arg)) { + if (java.lang.String.class.equals(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException { @@ -655,9 +668,8 @@ } }; - // now for the primitive types, use their wrappers - } else if (java.lang.Character.class.equals(arg) - || java.lang.Character.TYPE.equals(arg)) { + // char and Character get special treatment - take the first character + } else if (java.lang.Character.class.equals(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException { @@ -665,59 +677,9 @@ } }; - } else if (java.lang.Byte.TYPE.equals(arg)) { - return new AttributeSetter() { - public void set(Project p, Object parent, String value) - throws InvocationTargetException, IllegalAccessException { - m.invoke(parent, new Byte[] {new Byte(value)}); - } - - }; - } else if (java.lang.Short.TYPE.equals(arg)) { - return new AttributeSetter() { - public void set(Project p, Object parent, String value) - throws InvocationTargetException, IllegalAccessException { - m.invoke(parent, new Short[] {new Short(value)}); - } - - }; - } else if (java.lang.Integer.TYPE.equals(arg)) { - return new AttributeSetter() { - public void set(Project p, Object parent, String value) - throws InvocationTargetException, IllegalAccessException { - m.invoke(parent, new Integer[] {new Integer(value)}); - } - - }; - } else if (java.lang.Long.TYPE.equals(arg)) { - return new AttributeSetter() { - public void set(Project p, Object parent, String value) - throws InvocationTargetException, IllegalAccessException { - m.invoke(parent, new Long[] {new Long(value)}); - } - - }; - } else if (java.lang.Float.TYPE.equals(arg)) { - return new AttributeSetter() { - public void set(Project p, Object parent, String value) - throws InvocationTargetException, IllegalAccessException { - m.invoke(parent, new Float[] {new Float(value)}); - } - - }; - } else if (java.lang.Double.TYPE.equals(arg)) { - return new AttributeSetter() { - public void set(Project p, Object parent, String value) - throws InvocationTargetException, IllegalAccessException { - m.invoke(parent, new Double[] {new Double(value)}); - } - - }; - - // boolean gets an extra treatment, because we have a nice method + // boolean and Boolean get special treatment because we have a nice method // in Project - } else if (java.lang.Boolean.class.equals(arg) - || java.lang.Boolean.TYPE.equals(arg)) { + } else if (java.lang.Boolean.class.equals(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException { @@ -728,7 +690,7 @@ }; // Class doesn't have a String constructor but a decent factory method - } else if (java.lang.Class.class.equals(arg)) { + } else if (java.lang.Class.class.equals(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException, BuildException { @@ -741,7 +703,7 @@ }; // resolve relative paths through Project - } else if (java.io.File.class.equals(arg)) { + } else if (java.io.File.class.equals(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException { @@ -751,7 +713,7 @@ }; // resolve relative paths through Project - } else if (org.apache.tools.ant.types.Path.class.equals(arg)) { + } else if (org.apache.tools.ant.types.Path.class.equals(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException { @@ -761,12 +723,13 @@ }; // EnumeratedAttributes have their own helper class - } else if (org.apache.tools.ant.types.EnumeratedAttribute.class.isAssignableFrom(arg)) { + } else if (org.apache.tools.ant.types.EnumeratedAttribute.class.isAssignableFrom(reflectedArg)) { return new AttributeSetter() { public void set(Project p, Object parent, String value) throws InvocationTargetException, IllegalAccessException, BuildException { try { - org.apache.tools.ant.types.EnumeratedAttribute ea = (org.apache.tools.ant.types.EnumeratedAttribute)arg.newInstance(); + org.apache.tools.ant.types.EnumeratedAttribute ea = + (org.apache.tools.ant.types.EnumeratedAttribute)reflectedArg.newInstance(); ea.setValue(value); m.invoke(parent, new EnumeratedAttribute[] {ea}); } catch (InstantiationException ie) { @@ -776,11 +739,13 @@ }; // worst case. look for a public String constructor and use it + // This is used (deliberately) for all primitives/wrappers other than + // char and boolean } else { try { final Constructor c = - arg.getConstructor(new Class[] {java.lang.String.class}); + reflectedArg.getConstructor(new Class[] {java.lang.String.class}); return new AttributeSetter() { public void set(Project p, Object parent, 1.13 +36 -0 jakarta-ant/src/testcases/org/apache/tools/ant/IntrospectionHelperTest.java Index: IntrospectionHelperTest.java =================================================================== RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/IntrospectionHelperTest.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- IntrospectionHelperTest.java 10 Jan 2002 10:13:11 -0000 1.12 +++ IntrospectionHelperTest.java 20 Feb 2002 11:53:55 -0000 1.13 @@ -359,6 +359,27 @@ } catch (BuildException be) { assertTrue(be.getException() instanceof AssertionFailedError); } + ih.setAttribute(p, this, "seventeen", "17"); + try { + ih.setAttribute(p, this, "seventeen", "3"); + fail("17 shouldn't be equals to three"); + } catch (BuildException be) { + assertTrue(be.getException() instanceof AssertionFailedError); + } + ih.setAttribute(p, this, "eightteen", "18"); + try { + ih.setAttribute(p, this, "eightteen", "3"); + fail("18 shouldn't be equals to three"); + } catch (BuildException be) { + assertTrue(be.getException() instanceof AssertionFailedError); + } + ih.setAttribute(p, this, "nineteen", "19"); + try { + ih.setAttribute(p, this, "nineteen", "3"); + fail("19 shouldn't be equals to three"); + } catch (BuildException be) { + assertTrue(be.getException() instanceof AssertionFailedError); + } } public void testGetAttributes() { @@ -373,6 +394,9 @@ h.put("fourteen", java.lang.StringBuffer.class); h.put("fifteen", java.lang.Character.TYPE); h.put("sixteen", java.lang.Character.class); + h.put("seventeen", java.lang.Byte.TYPE); + h.put("eightteen", java.lang.Short.TYPE); + h.put("nineteen", java.lang.Double.TYPE); /* * JUnit 3.7 adds a getName method to TestCase - so we now @@ -453,6 +477,18 @@ public void setSixteen(Character c) { assertEquals(c.charValue(), 'a'); + } + + public void setSeventeen(byte b) { + assertEquals(17, b); + } + + public void setEightteen(short s) { + assertEquals(18, s); + } + + public void setNineteen(double d) { + assertEquals(19, d, 1e-6); } }// IntrospectionHelperTest -- To unsubscribe, e-mail: For additional commands, e-mail: