This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.models.impl-1.0.6 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git
commit 4fd9d71808bc0cd8a1a739f7f57e96834d467211 Author: Justin Edelson <[email protected]> AuthorDate: Tue Jun 17 13:12:54 2014 +0000 SLING-3674 - automatically wrapping/unwrapping arrays where possible during value map injection git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/impl@1603159 13f79535-47bb-0310-9956-ffa450edef68 --- .../models/impl/injectors/ValueMapInjector.java | 99 +++++++++++++++++++++- .../models/impl/ResourceModelClassesTest.java | 46 ++++++++++ .../testmodels/classes/ArrayPrimitivesModel.java | 40 +++++++++ .../testmodels/classes/ArrayWrappersModel.java | 40 +++++++++ 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java index b5a6a2d..1aebadd 100644 --- a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java +++ b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java @@ -17,6 +17,7 @@ package org.apache.sling.models.impl.injectors; import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Array; import java.lang.reflect.Type; import org.apache.commons.lang.StringUtils; @@ -54,7 +55,33 @@ public class ValueMapInjector implements InjectAnnotationProcessorFactory, Injec if (map == null) { return null; } else if (type instanceof Class<?>) { - return map.get(name, (Class<?>) type); + Class<?> clazz = (Class<?>) type; + try { + return map.get(name, clazz); + } catch (ClassCastException e) { + // handle case of primitive/wrapper arrays + if (clazz.isArray()) { + Class<?> componentType = clazz.getComponentType(); + if (componentType.isPrimitive()) { + Class<?> wrapper = getWrapperForPrimitive(componentType); + if (wrapper != null) { + Object wrapperArray = map.get(name, Array.newInstance(wrapper, 0).getClass()); + if (wrapperArray != null) { + return unwrapArray(wrapperArray, componentType); + } + } + } else { + Class<?> primitiveType = getPrimitiveForWrapper(componentType); + if (primitiveType != null) { + Object primitiveArray = map.get(name, Array.newInstance(primitiveType, 0).getClass()); + if (primitiveArray != null) { + return wrapArray(primitiveArray, componentType); + } + } + } + } + return null; + } } else { log.debug("ValueMapInjector doesn't support non-class types {}", type); return null; @@ -72,6 +99,76 @@ public class ValueMapInjector implements InjectAnnotationProcessorFactory, Injec } } + private Object unwrapArray(Object wrapperArray, Class<?> primitiveType) { + int length = Array.getLength(wrapperArray); + Object primitiveArray = Array.newInstance(primitiveType, length); + for (int i = 0; i < length; i++) { + Array.set(primitiveArray, i, Array.get(wrapperArray, i)); + } + return primitiveArray; + } + + private Object wrapArray(Object primitiveArray, Class<?> wrapperType) { + int length = Array.getLength(primitiveArray); + Object wrapperArray = Array.newInstance(wrapperType, length); + for (int i = 0; i < length; i++) { + Array.set(wrapperArray, i, Array.get(primitiveArray, i)); + } + return wrapperArray; + } + + private Class<?> getPrimitiveForWrapper(Class<?> clazz) { + if (clazz == Integer.class) { + return Integer.TYPE; + } + if (clazz == Long.class) { + return Long.TYPE; + } + if (clazz == Boolean.class) { + return Boolean.TYPE; + } + if (clazz == Double.class) { + return Double.TYPE; + } + if (clazz == Float.class) { + return Float.TYPE; + } + if (clazz == Short.class) { + return Short.TYPE; + } + if (clazz == Character.class) { + return Character.TYPE; + } + + return null; + } + + private Class<?> getWrapperForPrimitive(Class<?> clazz) { + if (clazz == Integer.TYPE) { + return Integer.class; + } + if (clazz == Long.TYPE) { + return Long.class; + } + if (clazz == Boolean.TYPE) { + return Boolean.class; + } + if (clazz == Double.TYPE) { + return Double.class; + } + if (clazz == Float.TYPE) { + return Float.class; + } + if (clazz == Short.TYPE) { + return Short.class; + } + if (clazz == Character.TYPE) { + return Character.class; + } + + return null; + } + @Override public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) { // check if the element has the expected annotation diff --git a/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java b/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java index a4de53f..5818f44 100644 --- a/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java +++ b/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java @@ -29,6 +29,8 @@ import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.models.impl.injectors.ChildResourceInjector; import org.apache.sling.models.impl.injectors.ValueMapInjector; +import org.apache.sling.models.testmodels.classes.ArrayPrimitivesModel; +import org.apache.sling.models.testmodels.classes.ArrayWrappersModel; import org.apache.sling.models.testmodels.classes.ChildModel; import org.apache.sling.models.testmodels.classes.ChildResourceModel; import org.apache.sling.models.testmodels.classes.ChildValueMapModel; @@ -93,6 +95,50 @@ public class ResourceModelClassesTest { } @Test + public void testArrayPrimitivesModel() { + Map<String, Object> map = new HashMap<String, Object>(); + map.put("intArray", new int[] { 1, 2, 9, 8 }); + map.put("secondIntArray", new Integer[] {1, 2, 9, 8}); + + ValueMap vm = new ValueMapDecorator(map); + Resource res = mock(Resource.class); + when(res.adaptTo(ValueMap.class)).thenReturn(vm); + + ArrayPrimitivesModel model = factory.getAdapter(res, ArrayPrimitivesModel.class); + assertNotNull(model); + + int[] primitiveIntArray = model.getIntArray(); + assertEquals(4, primitiveIntArray.length); + assertEquals(2, primitiveIntArray[1]); + + int[] secondPrimitiveIntArray = model.getSecondIntArray(); + assertEquals(4, secondPrimitiveIntArray.length); + assertEquals(2, secondPrimitiveIntArray[1]); + } + + @Test + public void testArrayWrappersModel() { + Map<String, Object> map = new HashMap<String, Object>(); + map.put("intArray", new Integer[] {1, 2, 9, 8}); + map.put("secondIntArray", new int[] {1, 2, 9, 8}); + + ValueMap vm = new ValueMapDecorator(map); + Resource res = mock(Resource.class); + when(res.adaptTo(ValueMap.class)).thenReturn(vm); + + ArrayWrappersModel model = factory.getAdapter(res, ArrayWrappersModel.class); + assertNotNull(model); + + Integer[] intArray = model.getIntArray(); + assertEquals(4, intArray.length); + assertEquals(new Integer(2), intArray[1]); + + Integer[] secondIntArray = model.getSecondIntArray(); + assertEquals(4, secondIntArray.length); + assertEquals(new Integer(2), secondIntArray[1]); + } + + @Test public void testRequiredPropertyModel() { Map<String, Object> map = new HashMap<String, Object>(); map.put("first", "first-value"); diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/ArrayPrimitivesModel.java b/src/test/java/org/apache/sling/models/testmodels/classes/ArrayPrimitivesModel.java new file mode 100644 index 0000000..d89384f --- /dev/null +++ b/src/test/java/org/apache/sling/models/testmodels/classes/ArrayPrimitivesModel.java @@ -0,0 +1,40 @@ +/* + * 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 org.apache.sling.models.testmodels.classes; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Model; + +import javax.inject.Inject; + +@Model(adaptables = Resource.class) +public class ArrayPrimitivesModel { + + @Inject + private int[] intArray; + + @Inject + private int[] secondIntArray; + + public int[] getIntArray() { + return intArray; + } + + public int[] getSecondIntArray() { + return secondIntArray; + } +} \ No newline at end of file diff --git a/src/test/java/org/apache/sling/models/testmodels/classes/ArrayWrappersModel.java b/src/test/java/org/apache/sling/models/testmodels/classes/ArrayWrappersModel.java new file mode 100644 index 0000000..e691e06 --- /dev/null +++ b/src/test/java/org/apache/sling/models/testmodels/classes/ArrayWrappersModel.java @@ -0,0 +1,40 @@ +/* + * 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 org.apache.sling.models.testmodels.classes; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Model; + +import javax.inject.Inject; + +@Model(adaptables = Resource.class) +public class ArrayWrappersModel { + + @Inject + private Integer[] intArray; + + @Inject + private Integer[] secondIntArray; + + public Integer[] getIntArray() { + return intArray; + } + + public Integer[] getSecondIntArray() { + return secondIntArray; + } +} \ No newline at end of file -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
