[ 
https://issues.apache.org/jira/browse/SANDBOX-501?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15006027#comment-15006027
 ] 

Matthew P Mann edited comment on SANDBOX-501 at 11/15/15 9:03 PM:
------------------------------------------------------------------

... and more tinkering. See [attached 
patch|https://issues.apache.org/jira/secure/attachment/12772417/commons-beanutils2.2015-11-15.patch].

{code}

public class StringToArrayTest {

        private StringToArray converter;
        private ConverterRegistry converterRegistry;

        @Before
        public void setUp() {
                converter = new StringToArray();
                converterRegistry = new ConverterRegistry()
                        .register(converter)
                        .register(new JsonNumberConverter())
                        .register(new JsonStringConverter())
                        .register(new JsonArrayToArray())
                        .register(BigDecimal::toBigIntegerExact)
                        .register(Address::parse)
                        
.register(FunctionConverter.from(BigDecimal.class).to(double.class).using(BigDecimal::doubleValue))
                        
.register(FunctionConverter.from(BigDecimal.class).to(int.class).using(BigDecimal::intValueExact))
                        
.register(FunctionConverter.from(String.class).to(BigDecimal.class).using(BigDecimal::new))
                        
.register(FunctionConverter.from(String.class).to(char.class).using(string -> {
                                if (length(string) != 1) {
                                        throw new 
IllegalArgumentException(string);
                                }
                                return string.charAt(0);
                        }));
        }

        @Test
        public void convert_StringToAddressArray() {
                final String source = "[ \"1600 Pennsylvania Avenue Northwest, 
Washington, DC  20500\", \"11 Wall Street, New York, NY  10005, US\", \"350 
Fifth Avenue, New York, NY  10118\", \"4059 Mt Lee Drive, Hollywood, CA  
90068\"]";
                assertTrue(converter.canConvert(String.class, Address[].class));
                final Address[] addresses = converter.convert(source, 
Address[].class, converterRegistry);
                assertEquals(4, addresses.length);
                assertEquals("1600 Pennsylvania Avenue Northwest", 
addresses[0].getStreetAddress());
                assertEquals("Washington", addresses[0].getCity());
                assertEquals(State.DC, addresses[0].getStateCode());
                assertEquals("20500", addresses[0].getPostalCode());
                assertNull(addresses[0].getCountryCode());
                assertEquals("11 Wall Street", addresses[1].getStreetAddress());
                assertEquals("New York", addresses[1].getCity());
                assertEquals(State.NY, addresses[1].getStateCode());
                assertEquals("10005", addresses[1].getPostalCode());
                assertEquals("US", addresses[1].getCountryCode());
                assertEquals("350 Fifth Avenue", 
addresses[2].getStreetAddress());
                assertEquals("New York", addresses[2].getCity());
                assertEquals(State.NY, addresses[2].getStateCode());
                assertEquals("10118", addresses[2].getPostalCode());
                assertNull(addresses[2].getCountryCode());
                assertEquals("4059 Mt Lee Drive", 
addresses[3].getStreetAddress());
                assertEquals("Hollywood", addresses[3].getCity());
                assertEquals(State.CA, addresses[3].getStateCode());
                assertEquals("90068", addresses[3].getPostalCode());
                assertNull(addresses[3].getCountryCode());
        }

...

}
{code}


was (Author: mattmann):
... and more tinkering. See [attached 
patch|https://issues.apache.org/jira/secure/attachment/12772417/commons-beanutils2.2015-11-15.patch].

{code}
package org.apache.commons.beanutils2.converters;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import org.apache.commons.beanutils2.Address;
import org.apache.commons.beanutils2.ConverterRegistry;
import org.apache.commons.beanutils2.State;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static java.lang.String.format;
import static org.apache.commons.beanutils2.utils.StringUtils.length;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

public class StringToArrayTest {

        private StringToArray converter;
        private ConverterRegistry converterRegistry;

        @Before
        public void setUp() {
                converter = new StringToArray();
                converterRegistry = new ConverterRegistry()
                        .register(converter)
                        .register(new JsonNumberConverter())
                        .register(new JsonStringConverter())
                        .register(new JsonArrayToArray())
                        .register(BigDecimal::toBigIntegerExact)
                        .register(Address::parse)
                        
.register(FunctionConverter.from(BigDecimal.class).to(double.class).using(BigDecimal::doubleValue))
                        
.register(FunctionConverter.from(BigDecimal.class).to(int.class).using(BigDecimal::intValueExact))
                        
.register(FunctionConverter.from(String.class).to(BigDecimal.class).using(BigDecimal::new))
                        
.register(FunctionConverter.from(String.class).to(char.class).using(string -> {
                                if (length(string) != 1) {
                                        throw new 
IllegalArgumentException(string);
                                }
                                return string.charAt(0);
                        }));
        }

        @Test
        public void convert_StringToAddressArray() {
                final String source = "[ \"1600 Pennsylvania Avenue Northwest, 
Washington, DC  20500\", \"11 Wall Street, New York, NY  10005, US\", \"350 
Fifth Avenue, New York, NY  10118\", \"4059 Mt Lee Drive, Hollywood, CA  
90068\"]";
                assertTrue(converter.canConvert(String.class, Address[].class));
                final Address[] addresses = converter.convert(source, 
Address[].class, converterRegistry);
                assertEquals(4, addresses.length);
                assertEquals("1600 Pennsylvania Avenue Northwest", 
addresses[0].getStreetAddress());
                assertEquals("Washington", addresses[0].getCity());
                assertEquals(State.DC, addresses[0].getStateCode());
                assertEquals("20500", addresses[0].getPostalCode());
                assertNull(addresses[0].getCountryCode());
                assertEquals("11 Wall Street", addresses[1].getStreetAddress());
                assertEquals("New York", addresses[1].getCity());
                assertEquals(State.NY, addresses[1].getStateCode());
                assertEquals("10005", addresses[1].getPostalCode());
                assertEquals("US", addresses[1].getCountryCode());
                assertEquals("350 Fifth Avenue", 
addresses[2].getStreetAddress());
                assertEquals("New York", addresses[2].getCity());
                assertEquals(State.NY, addresses[2].getStateCode());
                assertEquals("10118", addresses[2].getPostalCode());
                assertNull(addresses[2].getCountryCode());
                assertEquals("4059 Mt Lee Drive", 
addresses[3].getStreetAddress());
                assertEquals("Hollywood", addresses[3].getCity());
                assertEquals(State.CA, addresses[3].getStateCode());
                assertEquals("90068", addresses[3].getPostalCode());
                assertNull(addresses[3].getCountryCode());
        }
        
        @Test
        public void convert_StringToNumberArray() {
                final BigDecimal a = 
BigDecimal.valueOf(Double.MAX_VALUE).pow(2);
                final BigInteger b = BigInteger.valueOf(Long.MAX_VALUE).pow(2);
                final int c = Integer.MAX_VALUE;
                final long d = Long.MAX_VALUE;
                final double e = Double.MAX_VALUE;
                final float f = Float.MAX_VALUE;
                final String source = format("[%f, %d, %d, %d, %f, %f]", a, b, 
c, d, e, f);
                assertTrue(converter.canConvert(String.class, Object[].class));
                final Number[] array = converter.convert(source, 
Number[].class, converterRegistry);
                assertEquals(6, array.length);
                assertEquals(0, a.compareTo((BigDecimal) array[0]));
                assertEquals(0, new BigDecimal(b).compareTo((BigDecimal) 
array[1]));
                assertEquals(0, BigDecimal.valueOf(c).compareTo((BigDecimal) 
array[2]));
                assertEquals(0, BigDecimal.valueOf(d).compareTo((BigDecimal) 
array[3]));
                assertEquals(0, BigDecimal.valueOf(e).compareTo((BigDecimal) 
array[4]));
                assertEquals(0, BigDecimal.valueOf(f).compareTo((BigDecimal) 
array[5]));
        }

        @Test
        public void canConvert_IntegerToByteArray() {
                assertFalse(converter.canConvert(Integer.class, byte[].class));
        }

        @Test
        public void canConvert_StringToShort() {
                assertFalse(converter.canConvert(String.class, short.class));
        }
        
        @Test
        public void convert_StringToBigDecimalArray() {
                final String source = "[\"1.01\", 2.12, \"3.23\", 4.34, 
\"5.45\"]";
                assertTrue(converter.canConvert(String.class, 
BigDecimal[].class));
                final BigDecimal[] array = converter.convert(source, 
BigDecimal[].class, converterRegistry);
                assertEquals(5, array.length);
                assertEquals(BigDecimal.valueOf(1.01), array[0]);
                assertEquals(BigDecimal.valueOf(2.12), array[1]);
                assertEquals(BigDecimal.valueOf(3.23), array[2]);
                assertEquals(BigDecimal.valueOf(4.34), array[3]);
                assertEquals(BigDecimal.valueOf(5.45), array[4]);
        }

        @Test
        public void convert_StringToDoubleArray() {
                final String source = "[1.01, 2.12, 3.23, 4.34, 5.45]";
                assertTrue(converter.canConvert(String.class, double[].class));
                final double[] array = converter.convert(source, 
double[].class, converterRegistry);
                assertEquals(5, array.length);
                assertEquals(Double.valueOf(1.01), Double.valueOf(array[0]));
                assertEquals(Double.valueOf(2.12), Double.valueOf(array[1]));
                assertEquals(Double.valueOf(3.23), Double.valueOf(array[2]));
                assertEquals(Double.valueOf(4.34), Double.valueOf(array[3]));
                assertEquals(Double.valueOf(5.45), Double.valueOf(array[4]));
        }
        
        @Test
        public void convert_StringToBigIntegerArray() {
                final String source = "[1, 2, 3, 4, 5]";
                assertTrue(converter.canConvert(String.class, 
BigInteger[].class));
                final BigInteger[] array = converter.convert(source, 
BigInteger[].class, converterRegistry);
                assertEquals(5, array.length);
                assertEquals(1, array[0].intValue());
                assertEquals(2, array[1].intValue());
                assertEquals(3, array[2].intValue());
                assertEquals(4, array[3].intValue());
                assertEquals(5, array[4].intValue());
        }
        
        @Test
        public void convert_StringToArrayOfCharArray() {
                final String source = "[[\"a\", \"b\", \"c\"], [\"d\", \"e\"], 
[\"f\"], [\"g\", \"h\"]]";
                assertTrue(converter.canConvert(String.class, char[][].class));
                final char[][] array = converter.convert(source, 
char[][].class, converterRegistry);
                assertEquals(4, array.length);
                assertEquals(3, array[0].length);
                assertEquals(2, array[1].length);
                assertEquals(1, array[2].length);
                assertEquals(2, array[3].length);
                assertEquals('a', array[0][0]);
                assertEquals('b', array[0][1]);
                assertEquals('c', array[0][2]);
                assertEquals('d', array[1][0]);
                assertEquals('e', array[1][1]);
                assertEquals('f', array[2][0]);
                assertEquals('g', array[3][0]);
                assertEquals('h', array[3][1]);
        }
        
        @Test
        public void convert_StringToArrayOfIntArray() {
                final String source = "[[1, 2, 3], [4], [5, 6]]";
                assertTrue(converter.canConvert(String.class, int[][].class));
                final int[][] array = converter.convert(source, int[][].class, 
converterRegistry);
                assertEquals(3, array.length);
                assertEquals(3, array[0].length);
                assertEquals(1, array[1].length);
                assertEquals(2, array[2].length);
                assertEquals(1, array[0][0]);
                assertEquals(2, array[0][1]);
                assertEquals(3, array[0][2]);
                assertEquals(4, array[1][0]);
                assertEquals(5, array[2][0]);
                assertEquals(6, array[2][1]);
        }

        @Test
        public void convert_StringToStringArray() {
                final String source = "[\"The\", \"quick\", \"brown\", \"fox\", 
\"jumped\", \"over\", \"the\", \"lazy\", \"dog.\"]";
                assertTrue(converter.canConvert(String.class, String[].class));
                final String[] array = converter.convert(source, 
String[].class, converterRegistry);
                assertEquals(9, array.length);
                assertEquals("The", array[0]);
                assertEquals("quick", array[1]);
                assertEquals("brown", array[2]);
                assertEquals("fox", array[3]);
                assertEquals("jumped", array[4]);
                assertEquals("over", array[5]);
                assertEquals("the", array[6]);
                assertEquals("lazy", array[7]);
                assertEquals("dog.", array[8]);
        }

    public static final Answer<Object> UNSUPPORTED = new Answer<Object>() {
        public Object answer(InvocationOnMock invocation) throws Throwable {
            final Method method = invocation.getMethod();
            final Object[] arguments = invocation.getArguments();
            if (0 == arguments.length) {
                if (method.getName().equals("finalize")) {
                    return null;
                }
                if (method.getName().equals("toString")) {
                    return invocation.getMock().getClass().getName();
                }
            }
            final String message = String.format("%s %s", method, 
Arrays.toString(arguments));
            System.err.println(message);
            throw new UnsupportedOperationException(message);
        }
    };
}
{code}

> Add configurable type conversion support
> ----------------------------------------
>
>                 Key: SANDBOX-501
>                 URL: https://issues.apache.org/jira/browse/SANDBOX-501
>             Project: Commons Sandbox
>          Issue Type: New Feature
>          Components: BeanUtils2
>            Reporter: Benedikt Ritter
>         Attachments: commons-beanutils2.2015-11-13.patch, 
> commons-beanutils2.2015-11-14.patch, commons-beanutils2.2015-11-15.patch, 
> commons-beanutils2.java8.patch
>
>
> BeanUtils1 supports automatic type conversion when setting properties. This 
> should be added to BeanUtils2. 
> A problem of the implementation of BeanUtils1 is, that the registry of 
> converts is cached in the BeanUtils class. BeanUtils2 should provide an API 
> for creating new instances of the o.a.c.beanutils2.BeanUtils with a 
> customized typ conversion registry.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to