commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dmitri Plotnikov <dplot...@yahoo.com>
Subject Re: jxpath : BasicTypeConverter problem
Date Tue, 25 Mar 2003 14:57:42 GMT
Joachim,

Thanks for reporting this problem.  I incorporates your fix, slightly
modified.  To avoid checking all those conditions twice, I simply
re-ordered clauses of the big if statement.

Thank you very much for tracking this problem.

- Dmitri

--- Joachim Maes <joachim.maes@pandora.be> wrote:
> Hi,
> 
> I started using JXPath last week (and I am very excited about it!),
> and
> think found a problem in the conversions to String types in
> BasicTypeConverter.
> I ran into it using an extension function that refers to the commons
> StringUtils class.  Basically I use the expression
> "stringutils:getChomp(type,'.')".  Due to a problem in the type
> conversion from a NodeSet to a String, the actual method gets called
> with String arguments
> "org.apache.commons.jxpath.ri.EvalContext$SimpleNodeSet@443226" and
> ".".
> 
> I added tests to the BasicTypeConverterTest class to illustrate the
> problem, and then I made a simple change to BasicTypeConverter to
> make
> the adapted test succeed.  Presumably there are other approaches
> possible to resolve the problem (like implementing toString in
> EvalContext$SimpleNodeSet).
> 
> Please find both classes/changes in attachment.
> 
> Regards,
> Joachim Maes
> 
> 
> 1) added tests BasicTypeConverterTest :
> 
>       public void testSingletonCollectionToString() {
>           assertConversion(Collections.singleton("Earth"),
> String.class,
> "Earth");
>       }
> 
>       public void testSingletonArrayToString() {
>           assertConversion(new String[] {"Earth"}, String.class,
> "Earth");
>       }
> 
>       public void testPointerToString() {
>           assertConversion(
>                   new Pointer() {
>                       public Object getValue() {
>                           return "value";
>                       }
>                       public Object getNode() {
>                           return null;
>                       }
>                       public void setValue(Object value) {
>                       }
>                       public Object getRootNode() {
>                           return null;
>                       }
>                       public String asPath() {
>                           return null;
>                       }
>                       public Object clone() {
>                           return null;
>                       }
>                       public int compareTo(Object o) {
>                           return 0;
>                       }
>                   },
>                   String.class,
>                   "value");
>       }
> 
>       public void testNodeSetToString() {
>           assertConversion(
>                   new NodeSet() {
>                       public List getNodes() {
>                           return null;
>                       }
>                       public List getPointers() {
>                           return null;
>                       }
>                       public List getValues() {
>                           return Collections.singletonList("hello");
>                       }
>                   },
>                   String.class,
>                   "hello");
>       }
> 
>       // succeeds in current version
>       public void testNodeSetToInteger() {
>           assertConversion(
>                   new NodeSet() {
>                       public List getNodes() {
>                           return null;
>                       }
>                       public List getPointers() {
>                           return null;
>                       }
>                       public List getValues() {
>                           return Collections.singletonList("9");
>                       }
>                   },
>                   Integer.class,
>                   new Integer(9));
>       }
> 
> 
> 
> 2) change to BasicTypeConverter at line 223:
> 
>           if (toType == String.class
>                   && !(object instanceof Collection)
>                   && !fromType.isArray()
>                   && !(object instanceof NodeSet)
>                   && !(object instanceof Pointer)) {
> 
>               return object.toString();
>           }
> 
> 
> 
> > /*
>  * $Header:
>
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java,v
> 1.7 2003/03/11 00:59:34 dmitri Exp $
>  * $Revision: 1.7 $
>  * $Date: 2003/03/11 00:59:34 $
>  *
>  *
> ====================================================================
>  * The Apache Software License, Version 1.1
>  *
>  *
>  * Copyright (c) 1999-2003 The Apache Software Foundation.  All
> rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above
> copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution, if
>  *    any, must include the following acknowlegement:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowlegement may appear in the software
> itself,
>  *    if and wherever such third-party acknowlegements normally
> appear.
>  *
>  * 4. The names "The Jakarta Project", "Commons", and "Apache
> Software
>  *    Foundation" must not be used to endorse or promote products
> derived
>  *    from this software without prior written permission. For
> written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache"
>  *    nor may "Apache" appear in their names without prior written
>  *    permission of the Apache Group.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  *
> ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation and was
>  * originally based on software copyright (c) 2001, Plotnix, Inc,
>  * <http://www.plotnix.com/>.
>  * For more information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
> package org.apache.commons.jxpath.util;
> 
> import java.lang.reflect.Array;
> import java.lang.reflect.Modifier;
> import java.util.ArrayList;
> import java.util.Collection;
> import java.util.Collections;
> import java.util.HashSet;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Set;
> 
> import org.apache.commons.jxpath.JXPathException;
> import org.apache.commons.jxpath.Pointer;
> import org.apache.commons.jxpath.NodeSet;
> 
> /**
>  * The default implementation of TypeConverter.
>  *
>  * @author Dmitri Plotnikov
>  * @version $Revision: 1.7 $ $Date: 2003/03/11 00:59:34 $
>  */
> public class BasicTypeConverter implements TypeConverter {
> 
>     /**
>      * Returns true if it can convert the supplied
>      * object to the specified class.
>      */
>     public boolean canConvert(Object object, Class toType) {
>         if (object == null) {
>             return true;
>         }
> 
>         if (toType == Object.class) {
>             return true;
>         }
> 
>         Class fromType = object.getClass();
>         if (fromType.equals(toType)) {
>             return true;
>         }
> 
>         if (toType.isAssignableFrom(fromType)) {
>             return true;
>         }
> 
>         if (toType == String.class) {
>             return true;
>         }
> 
>         if (object instanceof Boolean) {
>             if (toType == boolean.class
>                 || Number.class.isAssignableFrom(toType)) {
>                 return true;
>             }
>         }
>         else if (object instanceof Number) {
>             if (toType.isPrimitive()
>                 || Number.class.isAssignableFrom(toType)) {
>                 return true;
>             }
>         }
>         else if (object instanceof Character) {
>             if (toType == char.class) {
>                 return true;
>             }
>         }
>         else if (object instanceof String) {
>             if (toType.isPrimitive()) {
>                 return true;
>             }
>             if (toType == Boolean.class
>                 || toType == Character.class
>                 || toType == Byte.class
>                 || toType == Short.class
>                 || toType == Integer.class
>                 || toType == Long.class
>                 || toType == Float.class
>                 || toType == Double.class) {
>                 return true;
>             }
>         }
>         else if (fromType.isArray()) {
>             // Collection -> array
>             if (toType.isArray()) {
>                 Class cType = toType.getComponentType();
>                 int length = Array.getLength(object);
>                 for (int i = 0; i < length; i++) {
>                     Object value = Array.get(object, i);
>                     if (!canConvert(value, cType)) {
>                         return false;
>                     }
>                 }
>                 return true;
>             }
>             else if (Collection.class.isAssignableFrom(toType)) {
>                 return canCreateCollection(toType);
>             }
>             else if (Array.getLength(object) == 1) {
>                 Object value = Array.get(object, 0);
>                 return canConvert(value, toType);
>             }
>         }
>         else if (object instanceof Collection) {
>             // Collection -> array
>             if (toType.isArray()) {
>                 Class cType = toType.getComponentType();
>                 Iterator it = ((Collection) object).iterator();
>                 while (it.hasNext()) {
>                     Object value = it.next();
>                     if (!canConvert(value, cType)) {
>                         return false;
>                     }
>                 }
>                 return true;
>             }
>             else if (Collection.class.isAssignableFrom(toType)) {
>                 return canCreateCollection(toType);
>             }
>             else if (((Collection) object).size() == 1) {
>                 Object value;
>                 if (object instanceof List) {
>                     value = ((List) object).get(0);
>                 }
>                 else {
>                     Iterator it = ((Collection) object).iterator();
>                     value = it.next();
>                 }
> 
=== message truncated ===> /*
>  * $Header:
>
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/util/BasicTypeConverterTest.java,v
> 1.3 2003/03/11 00:59:40 dmitri Exp $
>  * $Revision: 1.3 $
>  * $Date: 2003/03/11 00:59:40 $
>  *
>  *
> ====================================================================
>  * The Apache Software License, Version 1.1
>  *
>  *
>  * Copyright (c) 1999-2003 The Apache Software Foundation.  All
> rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above
> copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution, if
>  *    any, must include the following acknowlegement:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowlegement may appear in the software
> itself,
>  *    if and wherever such third-party acknowlegements normally
> appear.
>  *
>  * 4. The names "The Jakarta Project", "Commons", and "Apache
> Software
>  *    Foundation" must not be used to endorse or promote products
> derived
>  *    from this software without prior written permission. For
> written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache"
>  *    nor may "Apache" appear in their names without prior written
>  *    permission of the Apache Group.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  *
> ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation and was
>  * originally based on software copyright (c) 2001, Plotnix, Inc,
>  * <http://www.plotnix.com/>.
>  * For more information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
> 
> package org.apache.commons.jxpath.util;
> 
> import java.lang.reflect.Array;
> import java.util.*;
> 
> import junit.framework.TestCase;
> import org.apache.commons.jxpath.NodeSet;
> import org.apache.commons.jxpath.Pointer;
> 
> /**
>  * Tests BasicTypeConverter
>  *
>  * @author Dmitri Plotnikov
>  * @version $Revision: 1.3 $ $Date: 2003/03/11 00:59:40 $
>  */
> 
> public class BasicTypeConverterTest extends TestCase {
>     /**
>      * Construct a new instance of this test case.
>      *
>      * @param name Name of the test case
>      */
>     public BasicTypeConverterTest(String name) {
>         super(name);
>     }
> 
>     public void testPrimitiveToString() {
>         assertConversion(new Integer(1), String.class, "1");
>     }
> 
>     public void testArrayToList() {
>         assertConversion(
>             new int[] { 1, 2 },
>             List.class,
>             Arrays.asList(new Object[] { new Integer(1), new
> Integer(2)}));
>     }
> 
>     public void testArrayToArray() {
>         assertConversion(
>             new int[] { 1, 2 },
>             String[].class,
>             Arrays.asList(new String[] { "1", "2" }));
>     }
> 
>     public void testListToArray() {
>         assertConversion(
>             Arrays.asList(new Integer[] { new Integer(1), new
> Integer(2)}),
>             String[].class,
>             Arrays.asList(new String[] { "1", "2" }));
> 
>         assertConversion(
>             Arrays.asList(new String[] { "1", "2" }),
>             int[].class,
>             Arrays.asList(new Integer[] { new Integer(1), new
> Integer(2)}));
>     }
> 
>     public void testInvalidConversion() {
>         boolean exception = false;
>         try {
>             TypeUtils.convert("'foo'", Date.class);
>         }
>         catch (Throwable ex) {
>             exception = true;
>         }
>         assertTrue("Type conversion exception", exception);
>     }
> 
>     public void testSingletonCollectionToString() {
>         assertConversion(Collections.singleton("Earth"),
> String.class, "Earth");
>     }
> 
>     public void testSingletonArrayToString() {
>         assertConversion(new String[] {"Earth"}, String.class,
> "Earth");
>     }
> 
>     public void testPointerToString() {
>         assertConversion(
>                 new Pointer() {
>                     public Object getValue() {
>                         return "value";
>                     }
>                     public Object getNode() {
>                         return null;
>                     }
>                     public void setValue(Object value) {
>                     }
>                     public Object getRootNode() {
>                         return null;
>                     }
>                     public String asPath() {
>                         return null;
>                     }
>                     public Object clone() {
>                         return null;
>                     }
>                     public int compareTo(Object o) {
>                         return 0;
>                     }
>                 },
>                 String.class,
>                 "value");
>     }
> 
>     public void testNodeSetToString() {
>         assertConversion(
>                 new NodeSet() {
>                     public List getNodes() {
>                         return null;
>                     }
>                     public List getPointers() {
>                         return null;
>                     }
>                     public List getValues() {
>                         return Collections.singletonList("hello");
>                     }
>                 },
>                 String.class,
>                 "hello");
>     }
> 
>     // succeeds in current version
>     public void testNodeSetToInteger() {
> 
=== message truncated ===>
---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org


__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message