| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package com.opensymphony.xwork2.conversion.impl; |
| |
| import com.opensymphony.xwork2.*; |
| import com.opensymphony.xwork2.test.AnnotationUser; |
| import com.opensymphony.xwork2.test.ModelDrivenAnnotationAction2; |
| import com.opensymphony.xwork2.util.Bar; |
| import com.opensymphony.xwork2.util.ValueStack; |
| import com.opensymphony.xwork2.util.reflection.ReflectionContextState; |
| import ognl.OgnlRuntime; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| import java.text.DateFormat; |
| import java.text.ParseException; |
| import java.text.SimpleDateFormat; |
| import java.util.*; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| |
| |
| /** |
| * @author $Author$ |
| * @author Rainer Hermanns |
| * @version $Revision$ |
| */ |
| public class AnnotationXWorkConverterTest extends XWorkTestCase { |
| |
| ActionContext ac; |
| Map<String, Object> context; |
| XWorkConverter converter; |
| |
| // public void testConversionToSetKeepsOriginalSetAndReplacesContents() { |
| // ValueStack stack = ValueStackFactory.getFactory().createValueStack(); |
| // |
| // Map stackContext = stack.getContext(); |
| // stackContext.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE); |
| // stackContext.put(XWorkMethodAccessor.DENY_METHOD_EXECUTION, Boolean.TRUE); |
| // stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); |
| // |
| // String[] param = new String[] {"abc", "def", "ghi"}; |
| // List paramList = Arrays.asList(param); |
| // |
| // List originalList = new ArrayList(); |
| // originalList.add("jkl"); |
| // originalList.add("mno"); |
| // |
| // AnnotationUser user = new AnnotationUser(); |
| // user.setList(originalList); |
| // stack.push(user); |
| // |
| // stack.setValue("list", param); |
| // |
| // List userList = user.getList(); |
| // assertEquals(3,userList.size()); |
| // assertEquals(paramList,userList); |
| // assertSame(originalList,userList); |
| // } |
| |
| public void testArrayToNumberConversion() { |
| String[] value = new String[]{"12345"}; |
| assertEquals(12345, converter.convertValue(context, null, null, null, value, Integer.class)); |
| assertEquals(12345L, converter.convertValue(context, null, null, null, value, Long.class)); |
| value[0] = "123.45"; |
| assertEquals(123.45f, converter.convertValue(context, null, null, null, value, Float.class)); |
| assertEquals(123.45, converter.convertValue(context, null, null, null, value, Double.class)); |
| value[0] = "1234567890123456789012345678901234567890"; |
| assertEquals(new BigInteger(value[0]), converter.convertValue(context, null, null, null, value, BigInteger.class)); |
| value[0] = "1234567890123456789.012345678901234567890"; |
| assertEquals(new BigDecimal(value[0]), converter.convertValue(context, null, null, null, value, BigDecimal.class)); |
| } |
| |
| public void testDateConversion() throws ParseException { |
| java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis()); |
| assertEquals(sqlDate, converter.convertValue(context, null, null, null, sqlDate, Date.class)); |
| |
| SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"); |
| Date date = format.parse("01/10/2001 00:00:00"); |
| String dateStr = (String) converter.convertValue(context, null, null, null, date, String.class); |
| Date date2 = (Date) converter.convertValue(context, null, null, null, dateStr, Date.class); |
| assertEquals(date, date2); |
| } |
| |
| public void testFieldErrorMessageAddedForComplexProperty() { |
| SimpleAnnotationAction action = new SimpleAnnotationAction(); |
| action.setBean(new AnnotatedTestBean()); |
| |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| stack.push(action); |
| |
| Map<String, Object> ognlStackContext = stack.getContext(); |
| ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); |
| ognlStackContext.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, "bean.birth"); |
| |
| String[] value = new String[]{"invalid date"}; |
| assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action.getBean(), null, "birth", value, Date.class)); |
| stack.pop(); |
| |
| Map<String, ConversionData> conversionErrors = stack.getActionContext().getConversionErrors(); |
| assertNotNull(conversionErrors); |
| assertEquals(1, conversionErrors.size()); |
| assertEquals(value, conversionErrors.get("bean.birth").getValue()); |
| } |
| |
| public void testFieldErrorMessageAddedWhenConversionFails() { |
| SimpleAnnotationAction action = new SimpleAnnotationAction(); |
| action.setDate(null); |
| |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| stack.push(action); |
| |
| Map<String, Object> ognlStackContext = stack.getContext(); |
| ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); |
| |
| String[] value = new String[]{"invalid date"}; |
| assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action, null, "date", value, Date.class)); |
| stack.pop(); |
| |
| Map<String, ConversionData> conversionErrors = ActionContext.of(ognlStackContext).getConversionErrors(); |
| assertNotNull(conversionErrors); |
| assertEquals(1, conversionErrors.size()); |
| assertNotNull(conversionErrors.get("date")); |
| assertEquals(value, conversionErrors.get("date").getValue()); |
| } |
| |
| public void testFieldErrorMessageAddedWhenConversionFailsOnModelDriven() { |
| ModelDrivenAnnotationAction action = new ModelDrivenAnnotationAction(); |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| stack.push(action); |
| stack.push(action.getModel()); |
| |
| Map<String, Object> ognlStackContext = stack.getContext(); |
| ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); |
| |
| String[] value = new String[]{"invalid date"}; |
| assertEquals("Conversion should have failed.", OgnlRuntime.NoConversionPossible, converter.convertValue(ognlStackContext, action, null, "birth", value, Date.class)); |
| stack.pop(); |
| stack.pop(); |
| |
| Map<String, ConversionData> conversionErrors = ActionContext.of(ognlStackContext).getConversionErrors(); |
| assertNotNull(conversionErrors); |
| assertEquals(1, conversionErrors.size()); |
| assertNotNull(conversionErrors.get("birth")); |
| assertEquals(value, conversionErrors.get("birth").getValue()); |
| } |
| |
| public void testFindConversionErrorMessage() { |
| ModelDrivenAnnotationAction action = new ModelDrivenAnnotationAction(); |
| container.inject(action); |
| |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| stack.push(action); |
| stack.push(action.getModel()); |
| |
| String message = XWorkConverter.getConversionErrorMessage("birth", Integer.class, stack); |
| assertNotNull(message); |
| assertEquals("Invalid date for birth.", message); |
| |
| message = XWorkConverter.getConversionErrorMessage("foo", Integer.class, stack); |
| assertNotNull(message); |
| assertEquals("Invalid field value for field \"foo\".", message); |
| } |
| |
| public void testFindConversionMappingForInterfaceAndSuperclass() { |
| ModelDrivenAnnotationAction2 action = new ModelDrivenAnnotationAction2(); |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| stack.push(action); |
| stack.push(action.getModel()); |
| |
| Map<String, Object> ognlStackContext = stack.getContext(); |
| ognlStackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); |
| |
| String value = "asdf:123"; |
| Object o = converter.convertValue(ognlStackContext, action.getModel(), null, "barObj", value, Bar.class); |
| assertNotNull(o); |
| assertTrue("class is: " + o.getClass(), o instanceof Bar); |
| |
| Bar b = (Bar) o; |
| assertEquals(value, b.getTitle() + ":" + b.getSomethingElse()); |
| |
| String value2 = "qwer:456"; |
| Object o2 = converter.convertValue(ognlStackContext, action.getModel(), null, "supperBarObj", value2, Bar.class); |
| assertNotNull(o2); |
| assertTrue("class is: " + o.getClass(), o2 instanceof Bar); |
| |
| Bar b2 = (Bar) o2; |
| assertEquals(value2, b2.getTitle() + ":" + b2.getSomethingElse()); |
| } |
| |
| public void testLocalizedDateConversion() { |
| Date date = new Date(System.currentTimeMillis()); |
| Locale locale = Locale.GERMANY; |
| DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); |
| String dateString = df.format(date); |
| context = ActionContext.of(context).withLocale(locale).getContextMap(); |
| assertEquals(dateString, converter.convertValue(context, null, null, null, date, String.class)); |
| } |
| |
| public void testStringArrayToCollection() { |
| List<String> list = new ArrayList<>(); |
| list.add("foo"); |
| list.add("bar"); |
| list.add("baz"); |
| assertEquals(list, converter.convertValue(context, null, null, null, new String[]{ |
| "foo", "bar", "baz" |
| }, Collection.class)); |
| } |
| |
| public void testStringArrayToList() { |
| List<String> list = new ArrayList<>(); |
| list.add("foo"); |
| list.add("bar"); |
| list.add("baz"); |
| assertEquals(list, converter.convertValue(context, null, null, null, new String[]{ |
| "foo", "bar", "baz" |
| }, List.class)); |
| } |
| |
| public void testStringArrayToPrimitiveWrappers() { |
| Long[] longs = (Long[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, Long[].class); |
| assertNotNull(longs); |
| assertArrayEquals(new Long[]{123L, 456L}, longs); |
| |
| Integer[] ints = (Integer[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, Integer[].class); |
| assertNotNull(ints); |
| assertArrayEquals(new Integer[]{123, 456}, ints); |
| |
| Double[] doubles = (Double[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, Double[].class); |
| assertNotNull(doubles); |
| assertArrayEquals(new Double[]{123D, 456D}, doubles); |
| |
| Float[] floats = (Float[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, Float[].class); |
| assertNotNull(floats); |
| assertArrayEquals(new Float[]{123F, 456F}, floats); |
| |
| Boolean[] booleans = (Boolean[]) converter.convertValue(context, null, null, null, new String[]{ |
| "true", "false" |
| }, Boolean[].class); |
| assertNotNull(booleans); |
| assertArrayEquals(new Boolean[]{Boolean.TRUE, Boolean.FALSE}, booleans); |
| } |
| |
| public void testStringArrayToPrimitives() { |
| long[] longs = (long[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, long[].class); |
| assertNotNull(longs); |
| assertArrayEquals(new long[]{123, 456}, longs); |
| |
| int[] ints = (int[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, int[].class); |
| assertNotNull(ints); |
| assertArrayEquals(new int[]{123, 456}, ints); |
| |
| double[] doubles = (double[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, double[].class); |
| assertNotNull(doubles); |
| assertArrayEquals(new double[]{123, 456}, doubles, 0.0); |
| |
| float[] floats = (float[]) converter.convertValue(context, null, null, null, new String[]{ |
| "123", "456" |
| }, float[].class); |
| assertNotNull(floats); |
| assertArrayEquals(new float[]{123, 456}, floats, 0.0f); |
| |
| boolean[] booleans = (boolean[]) converter.convertValue(context, null, null, null, new String[]{ |
| "true", "false" |
| }, boolean[].class); |
| assertNotNull(booleans); |
| assertArrayEquals(new boolean[]{true, false}, booleans); |
| } |
| |
| public void testStringArrayToSet() { |
| Set<String> list = new HashSet<>(); |
| list.add("foo"); |
| list.add("bar"); |
| list.add("baz"); |
| assertEquals(list, converter.convertValue(context, null, null, null, new String[]{ |
| "foo", "bar", "bar", "baz" |
| }, Set.class)); |
| } |
| |
| // TODO: Fixme... This test does not work with GenericsObjectDeterminer! |
| public void testStringToCollectionConversion() { |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| Map<String, Object> stackContext = stack.getContext(); |
| stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.TRUE); |
| stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE); |
| stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE); |
| |
| AnnotationUser user = new AnnotationUser(); |
| stack.push(user); |
| |
| stack.setValue("list", "asdf"); |
| assertNotNull(user.getList()); |
| assertEquals(1, user.getList().size()); |
| assertEquals(String.class, user.getList().get(0).getClass()); |
| assertEquals("asdf", user.getList().get(0)); |
| } |
| |
| public void testStringToCustomTypeUsingCustomConverter() { |
| // the converter needs to be registered as the Bar.class converter |
| // it won't be detected from the Foo-conversion.properties |
| // because the Foo-conversion.properties file is only used when converting a property of Foo |
| converter.registerConverter(Bar.class.getName(), new FooBarConverter()); |
| |
| Bar bar = (Bar) converter.convertValue(null, null, null, null, "blah:123", Bar.class); |
| assertNotNull("conversion failed", bar); |
| assertEquals(123, bar.getSomethingElse()); |
| assertEquals("blah", bar.getTitle()); |
| } |
| |
| public void testStringToPrimitiveWrappers() { |
| assertEquals(123L, converter.convertValue(context, null, null, null, "123", Long.class)); |
| assertEquals(123, converter.convertValue(context, null, null, null, "123", Integer.class)); |
| assertEquals(123.5, converter.convertValue(context, null, null, null, "123.5", Double.class)); |
| assertEquals(123.5f, converter.convertValue(context, null, null, null, "123.5", float.class)); |
| assertEquals(false, converter.convertValue(context, null, null, null, "false", Boolean.class)); |
| assertEquals(true, converter.convertValue(context, null, null, null, "true", Boolean.class)); |
| } |
| |
| public void testStringToPrimitives() { |
| assertEquals(123L, converter.convertValue(context, null, null, null, "123", long.class)); |
| assertEquals(123, converter.convertValue(context, null, null, null, "123", int.class)); |
| assertEquals(123.5, converter.convertValue(context, null, null, null, "123.5", double.class)); |
| assertEquals(123.5f, converter.convertValue(context, null, null, null, "123.5", float.class)); |
| assertEquals(false, converter.convertValue(context, null, null, null, "false", boolean.class)); |
| assertEquals(true, converter.convertValue(context, null, null, null, "true", boolean.class)); |
| assertEquals(new BigDecimal("123.5"), converter.convertValue(context, null, null, null, "123.5", BigDecimal.class)); |
| assertEquals(new BigInteger("123"), converter.convertValue(context, null, null, null, "123", BigInteger.class)); |
| } |
| |
| public void testValueStackWithTypeParameter() { |
| ValueStack stack = ActionContext.getContext().getValueStack(); |
| stack.push(new Foo1()); |
| Bar1 bar = (Bar1) stack.findValue("bar", Bar1.class); |
| assertNotNull(bar); |
| } |
| |
| public void testGenericProperties() { |
| GenericsBean gb = new GenericsBean(); |
| ValueStack stack = ac.getValueStack(); |
| stack.push(gb); |
| |
| String[] value = new String[] {"123.12", "123.45"}; |
| stack.setValue("doubles", value); |
| assertEquals(2, gb.getDoubles().size()); |
| assertEquals(Double.class, gb.getDoubles().get(0).getClass()); |
| assertEquals(123.12, gb.getDoubles().get(0)); |
| assertEquals(123.45, gb.getDoubles().get(1)); |
| } |
| |
| public void testGenericPropertiesFromField() { |
| GenericsBean gb = new GenericsBean(); |
| ValueStack stack = ac.getValueStack(); |
| stack.push(gb); |
| |
| stack.setValue("genericMap[123.12]", "66"); |
| stack.setValue("genericMap[456.12]", "42"); |
| |
| assertEquals(2, gb.getGenericMap().size()); |
| assertEquals("66", stack.findValue("genericMap.get(123.12).toString()")); |
| assertEquals("42", stack.findValue("genericMap.get(456.12).toString()")); |
| assertEquals(66, stack.findValue("genericMap.get(123.12)")); |
| assertEquals(42, stack.findValue("genericMap.get(456.12)")); |
| assertEquals(true, stack.findValue("genericMap.containsValue(66)")); |
| assertEquals(true, stack.findValue("genericMap.containsValue(42)")); |
| assertEquals(true, stack.findValue("genericMap.containsKey(123.12)")); |
| assertEquals(true, stack.findValue("genericMap.containsKey(456.12)")); |
| } |
| |
| public void testGenericPropertiesFromSetter() { |
| GenericsBean gb = new GenericsBean(); |
| ValueStack stack = ac.getValueStack(); |
| stack.push(gb); |
| |
| stack.setValue("genericMap[123.12]", "66"); |
| stack.setValue("genericMap[456.12]", "42"); |
| |
| assertEquals(2, gb.getGenericMap().size()); |
| assertEquals("66", stack.findValue("genericMap.get(123.12).toString()")); |
| assertEquals("42", stack.findValue("genericMap.get(456.12).toString()")); |
| assertEquals(66, stack.findValue("genericMap.get(123.12)")); |
| assertEquals(42, stack.findValue("genericMap.get(456.12)")); |
| assertEquals(true, stack.findValue("genericMap.containsValue(66)")); |
| assertEquals(true, stack.findValue("genericMap.containsValue(42)")); |
| assertEquals(true, stack.findValue("genericMap.containsKey(123.12)")); |
| assertEquals(true, stack.findValue("genericMap.containsKey(456.12)")); |
| } |
| |
| public void testGenericPropertiesFromGetter() { |
| GenericsBean gb = new GenericsBean(); |
| ValueStack stack = ac.getValueStack(); |
| stack.push(gb); |
| |
| assertEquals(1, gb.getGetterList().size()); |
| assertEquals("42.42", stack.findValue("getterList.get(0).toString()")); |
| assertEquals(42.42, stack.findValue("getterList.get(0)")); |
| assertEquals(42.42, gb.getGetterList().get(0)); |
| |
| } |
| |
| |
| // FIXME: Implement nested Generics such as: List of Generics List, Map of Generic keys/values, etc... |
| public void no_testGenericPropertiesWithNestedGenerics() { |
| GenericsBean gb = new GenericsBean(); |
| ValueStack stack = ac.getValueStack(); |
| stack.push(gb); |
| |
| stack.setValue("extendedMap[123.12]", new String[] {"1", "2", "3", "4"}); |
| stack.setValue("extendedMap[456.12]", new String[] {"5", "6", "7", "8", "9"}); |
| |
| System.out.println("gb.getExtendedMap(): " + gb.getExtendedMap()); |
| |
| assertEquals(2, gb.getExtendedMap().size()); |
| System.out.println(stack.findValue("extendedMap")); |
| assertEquals(4, stack.findValue("extendedMap.get(123.12).size")); |
| assertEquals(5, stack.findValue("extendedMap.get(456.12).size")); |
| |
| assertEquals("1", stack.findValue("extendedMap.get(123.12).get(0)")); |
| assertEquals("5", stack.findValue("extendedMap.get(456.12).get(0)")); |
| assertEquals(Integer.class, stack.findValue("extendedMap.get(123.12).get(0).class")); |
| assertEquals(Integer.class, stack.findValue("extendedMap.get(456.12).get(0).class")); |
| |
| assertEquals(List.class, stack.findValue("extendedMap.get(123.12).class")); |
| assertEquals(List.class, stack.findValue("extendedMap.get(456.12).class")); |
| |
| } |
| |
| public static class Foo1 { |
| public Bar1 getBar() { |
| return new Bar1Impl(); |
| } |
| } |
| |
| public interface Bar1 { |
| } |
| |
| public static class Bar1Impl implements Bar1 { |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| converter = container.getInstance(XWorkConverter.class); |
| |
| ac = ActionContext.getContext().withLocale(Locale.US); |
| context = ac.getContextMap(); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| ActionContext.clear(); |
| } |
| } |