Author: sseifert Date: Fri Mar 10 14:58:17 2017 New Revision: 1786361 URL: http://svn.apache.org/viewvc?rev=1786361&view=rev Log: SLING-6537 BigDecimal support, use copy of enhanced ValueMap with proper type converstion from Sling API 2.17.0
Added: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java (with props) sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java (with props) sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java (with props) sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java (with props) sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java (with props) sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java (with props) sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java (with props) sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java (with props) Removed: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtilTest.java Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java?rev=1786361&r1=1786360&r2=1786361&view=diff ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java (original) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java Fri Mar 10 14:58:17 2017 @@ -18,13 +18,14 @@ */ package org.apache.sling.fsprovider.internal; +import static org.apache.jackrabbit.vault.util.Constants.DOT_CONTENT_XML; + import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -import static org.apache.jackrabbit.vault.util.Constants.DOT_CONTENT_XML; import org.apache.commons.collections.IteratorUtils; import org.apache.commons.collections.Predicate; Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java?rev=1786361&r1=1786360&r2=1786361&view=diff ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java (original) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java Fri Mar 10 14:58:17 2017 @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.commons.collections.IteratorUtils; import org.apache.commons.collections.Predicate; import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.fsprovider.internal.mapper.valuemap.ValueMapUtil; import org.apache.sling.fsprovider.internal.parser.ContentFileCache; /** Modified: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java?rev=1786361&r1=1786360&r2=1786361&view=diff ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java (original) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java Fri Mar 10 14:58:17 2017 @@ -37,8 +37,8 @@ import org.apache.sling.api.resource.Res import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ValueMap; -import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.fsprovider.internal.FsResourceProvider; +import org.apache.sling.fsprovider.internal.mapper.valuemap.ValueMapDecorator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; Added: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,99 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import java.util.Calendar; +import java.util.Date; + +import org.apache.jackrabbit.util.ISO8601; + +/** + * This is copied from org.apache.sling.api.wrappers.impl.DateUtils + * to avoid dependency to latest Sling API. + * This can be removed when Sling API 2.17.0 or higher is referenced. + */ +final class DateUtils { + + private DateUtils() { + // static methods only + } + + /** + * @param date Date value + * @return Calendar value or null + */ + public static Calendar toCalendar(Date input) { + if (input == null) { + return null; + } + Calendar result = Calendar.getInstance(); + result.setTime(input); + return result; + } + + /** + * @param calendar Calendar value + * @return Date value or null + */ + public static Date toDate(Calendar input) { + if (input == null) { + return null; + } + return input.getTime(); + } + + /** + * @param input Date value + * @return ISO8601 string representation or null + */ + public static String dateToString(Date input) { + return calendarToString(toCalendar(input)); + } + + /** + * @param input Calendar value + * @return ISO8601 string representation or null + */ + public static String calendarToString(Calendar input) { + if (input == null) { + return null; + } + return ISO8601.format(input); + } + + /** + * @param input ISO8601 string representation + * @return Date value or null + */ + public static Date dateFromString(String input) { + return toDate(calendarFromString(input)); + } + + /** + * @param input ISO8601 string representation + * @return Calendar value or null + */ + public static Calendar calendarFromString(String input) { + if (input == null) { + return null; + } + return ISO8601.parse(input); + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/DateUtils.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,185 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import java.lang.reflect.Array; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * This is copied from org.apache.sling.api.wrappers.impl.ObjectConverter + * to avoid dependency to latest Sling API. + * This can be removed when Sling API 2.17.0 or higher is referenced. + */ +final class ObjectConverter { + + private ObjectConverter() { + // static methods only + } + + /** + * Converts the object to the given type. + * @param obj object + * @param type type + * @return the converted object + */ + @SuppressWarnings("unchecked") + public static <T> T convert(Object obj, Class<T> type) { + if (obj == null) { + return null; + } + + // check if direct assignment is possible + if (type.isAssignableFrom(obj.getClass())) { + return (T)obj; + } + + // convert array elements individually + if (type.isArray()) { + return (T)convertToArray(obj, type.getComponentType()); + } + + // convert Calendar in Date and vice versa + if (Calendar.class.isAssignableFrom(type) && obj instanceof Date) { + return (T)DateUtils.toCalendar((Date)obj); + } + if (type == Date.class && obj instanceof Calendar) { + return (T)DateUtils.toDate((Calendar)obj); + } + + // no direct conversion - format to string and try to parse to target type + String result = getSingleValue(obj); + if (result == null) { + return null; + } + if (type == String.class) { + return (T)result.toString(); + } + if (type == Boolean.class) { + // do not rely on Boolean.parseBoolean to avoid converting nonsense to "false" without noticing + if ("true".equalsIgnoreCase(result)) { + return (T)Boolean.TRUE; + } + else if ("false".equalsIgnoreCase(result)) { + return (T)Boolean.FALSE; + } + else { + return null; + } + } + try { + if (type == Byte.class) { + return (T)(Byte)Byte.parseByte(result); + } + if (type == Short.class) { + return (T)(Short)Short.parseShort(result); + } + if (type == Integer.class) { + return (T)(Integer)Integer.parseInt(result); + } + if (type == Long.class) { + return (T)(Long)Long.parseLong(result); + } + if (type == Float.class) { + return (T)(Float)Float.parseFloat(result); + } + if (type == Double.class) { + return (T)(Double)Double.parseDouble(result); + } + if (type == BigDecimal.class) { + return (T)new BigDecimal(result); + } + } + catch (NumberFormatException e) { + return null; + } + if (Calendar.class.isAssignableFrom(type)) { + return (T)DateUtils.calendarFromString(result); + } + if (type == Date.class) { + return (T)DateUtils.dateFromString(result); + } + return null; + } + + /** + * Gets a single value of String from the object. If the object is an array it returns it's first element. + * @param obj object or object array. + * @return result of <code>toString()</code> on object or first element of an object array. If @param obj is null + * or it's an array with first element that is null, then null is returned. + */ + private static String getSingleValue(Object obj) { + final String result; + if (obj == null) { + result = null; + } + else if (obj.getClass().isArray()) { + if (Array.getLength(obj) == 0) { + result = null; + } + else { + result = getSingleValue(Array.get(obj, 0)); + } + } + else if (obj instanceof Calendar) { + result = DateUtils.calendarToString((Calendar)obj); + } + else if (obj instanceof Date) { + result = DateUtils.dateToString((Date)obj); + } + else { + result = obj.toString(); + } + return result; + } + + /** + * Converts the object to an array of the given type + * @param obj the object or object array + * @param type the component type of the array + * @return and array of type T + */ + @SuppressWarnings("unchecked") + private static <T> T[] convertToArray(Object obj, Class<T> type) { + if (obj.getClass().isArray()) { + List<Object> resultList = new ArrayList<Object>(); + for (int i = 0; i < Array.getLength(obj); i++) { + T singleValueResult = convert(Array.get(obj, i), type); + if (singleValueResult != null) { + resultList.add(singleValueResult); + } + } + return resultList.toArray((T[])Array.newInstance(type, resultList.size())); + } + else { + final T singleValueResult = convert(obj, type); + // return null for type conversion errors instead of single element array with value null + if (singleValueResult == null) { + return (T[])Array.newInstance(type, 0); + } + final T[] arrayResult = (T[])Array.newInstance(type, 1); + arrayResult[0] = singleValueResult; + return arrayResult; + } + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,179 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.sling.api.resource.ValueMap; + +/** + * This is copied from org.apache.sling.api.wrappers.ValueMapDectorator + * to avoid dependency to latest Sling API. + * This can be removed when Sling API 2.17.0 or higher is referenced. + */ +public final class ValueMapDecorator implements ValueMap { + + /** + * underlying map + */ + private final Map<String, Object> base; + + /** + * Creates a new wrapper around a given map. + * @param base wrapped object + */ + public ValueMapDecorator(Map<String, Object> base) { + this.base = base; + } + + /** + * {@inheritDoc} + */ + public <T> T get(String name, Class<T> type) { + if (base instanceof ValueMap) { + // shortcut if decorated map is ValueMap + return ((ValueMap)base).get(name, type); + } + return ObjectConverter.convert(get(name), type); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public <T> T get(String name, T defaultValue) { + if (base instanceof ValueMap) { + // shortcut if decorated map is ValueMap + return ((ValueMap)base).get(name, defaultValue); + } + if (defaultValue == null) { + return (T)get(name); + } + T value = get(name, (Class<T>) defaultValue.getClass()); + return value == null ? defaultValue : value; + } + + /** + * {@inheritDoc} + */ + public int size() { + return base.size(); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() { + return base.isEmpty(); + } + + /** + * {@inheritDoc} + */ + public boolean containsKey(Object key) { + return base.containsKey(key); + } + + /** + * {@inheritDoc} + */ + public boolean containsValue(Object value) { + return base.containsValue(value); + } + + /** + * {@inheritDoc} + */ + public Object get(Object key) { + return base.get(key); + } + + /** + * {@inheritDoc} + */ + public Object put(String key, Object value) { + return base.put(key, value); + } + + /** + * {@inheritDoc} + */ + public Object remove(Object key) { + return base.remove(key); + } + + /** + * {@inheritDoc} + */ + public void putAll(Map<? extends String, ?> t) { + base.putAll(t); + } + + /** + * {@inheritDoc} + */ + public void clear() { + base.clear(); + } + + /** + * {@inheritDoc} + */ + public Set<String> keySet() { + return base.keySet(); + } + + /** + * {@inheritDoc} + */ + public Collection<Object> values() { + return base.values(); + } + + /** + * {@inheritDoc} + */ + public Set<Entry<String, Object>> entrySet() { + return base.entrySet(); + } + + @Override + public String toString() { + return super.toString() + " : " + this.base.toString(); + } + + @Override + /** + * {@inheritDoc} + */ + public int hashCode() { + return base.hashCode(); + } + + @Override + /** + * {@inheritDoc} + */ + public boolean equals(Object obj) { + return base.equals(obj); + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecorator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,58 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.sling.api.resource.ValueMap; + +public final class ValueMapUtil { + + private ValueMapUtil() { + // static methods only + } + + /** + * Convert map to value map. + * @param content Content map. + * @return Value map. + */ + public static ValueMap toValueMap(Map<String,Object> content) { + Map<String,Object> props = new HashMap<>(); + + for (Map.Entry<String, Object> entry : ((Map<String,Object>)content).entrySet()) { + if (entry.getValue() instanceof Map) { + // skip child resources + continue; + } + else if (entry.getValue() instanceof Collection) { + // convert lists to arrays + props.put(entry.getKey(), ((Collection)entry.getValue()).toArray()); + } + else { + props.put(entry.getKey(), entry.getValue()); + } + } + + return new ValueMapDecorator(props); + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtil.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java?rev=1786361&r1=1786360&r2=1786361&view=diff ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java (original) +++ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java Fri Mar 10 14:58:17 2017 @@ -28,6 +28,7 @@ import static org.junit.Assert.assertNul import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import java.math.BigDecimal; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -138,6 +139,7 @@ public class JsonContentTest { assertEquals(true, props.get("booleanProp", false)); assertEquals((Long)1234567890123L, props.get("longProp", Long.class)); assertEquals((Double)1.2345d, props.get("decimalProp", Double.class), 0.00001d); + assertEquals(new BigDecimal("1.2345"), props.get("decimalProp", BigDecimal.class)); assertArrayEquals(new String[] { "aa", "bb", "cc" }, props.get("stringPropMulti", String[].class)); assertArrayEquals(new Long[] { 1234567890123L, 55L }, props.get("longPropMulti", Long[].class)); @@ -162,8 +164,9 @@ public class JsonContentTest { assertEquals(true, node.getProperty("booleanProp").getBoolean()); assertEquals(PropertyType.LONG, node.getProperty("longProp").getType()); assertEquals(1234567890123L, node.getProperty("longProp").getLong()); - assertEquals(PropertyType.DOUBLE, node.getProperty("decimalProp").getType()); + assertEquals(PropertyType.DECIMAL, node.getProperty("decimalProp").getType()); assertEquals(1.2345d, node.getProperty("decimalProp").getDouble(), 0.00001d); + assertEquals(new BigDecimal("1.2345"), node.getProperty("decimalProp").getDecimal()); assertEquals(PropertyType.STRING, node.getProperty("stringPropMulti").getType()); assertTrue(node.getProperty("stringPropMulti").isMultiple()); Modified: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java?rev=1786361&r1=1786360&r2=1786361&view=diff ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java (original) +++ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java Fri Mar 10 14:58:17 2017 @@ -38,8 +38,8 @@ import org.apache.commons.lang3.CharEnco import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.observation.ResourceChange; -import org.apache.sling.api.resource.observation.ResourceChangeListener; import org.apache.sling.api.resource.observation.ResourceChange.ChangeType; +import org.apache.sling.api.resource.observation.ResourceChangeListener; import org.apache.sling.hamcrest.ResourceMatchers; import org.apache.sling.testing.mock.osgi.MapUtil; import org.apache.sling.testing.mock.osgi.context.AbstractContextPlugin; Added: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,242 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.lang.reflect.Array; +import java.util.Calendar; +import java.util.Date; + +import org.apache.commons.lang3.ClassUtils; + +/** + * This is copied from org.apache.sling.api.wrappers.impl.Convert + */ +final class Convert { + + private Convert() { + // static methods only + } + + @SuppressWarnings("unchecked") + public static class ConversionAssert<T,U> { + private final T input1; + private final T input2; + private Class<T> inputType; + private U expected1; + private U expected2; + private U nullValue; + private Class<U> expectedType; + + private ConversionAssert(T input1, T input2, boolean inputTypePrimitive) { + this.input1 = input1; + this.input2 = input2; + this.inputType = (Class<T>)input1.getClass(); + if (inputTypePrimitive) { + this.inputType = (Class<T>)ClassUtils.wrapperToPrimitive(this.inputType); + } + } + + private void expected(U expected1, U expected2, boolean expectedTypePrimitive) { + this.expected1 = expected1; + this.expected2 = expected2; + this.expectedType = (Class<U>)expected1.getClass(); + if (expectedTypePrimitive) { + expectedType = (Class<U>)ClassUtils.wrapperToPrimitive(this.expectedType); + } + } + + /** + * @param expected1 Singleton or first array expected result value + * @param expected2 Second array expected result value + * @return this + */ + public ConversionAssert<T,U> to(U expected1, U expected2) { + expected(expected1, expected2, false); + return this; + } + + /** + * @param expected1 Singleton or first array expected result value + * @param expected2 Second array expected result value + * @return this + */ + public ConversionAssert<T,U> toPrimitive(U expected1, U expected2) { + expected(expected1, expected2, true); + return this; + } + + /** + * @param expected1 Singleton or first array expected result value + * @param expected2 Second array expected result value + * @return this + */ + public ConversionAssert<T,U> toNull(Class<U> expectedType) { + expected1 = null; + expected2 = null; + this.expectedType = expectedType; + return this; + } + + /** + * @param nullValue Result value in case of null + */ + public ConversionAssert<T,U> nullValue(U nullValue) { + this.nullValue = nullValue; + return this; + } + + /** + * Do assertion + */ + public void test() { + Class<U[]> expectedArrayType = (Class<U[]>)Array.newInstance(this.expectedType, 0).getClass(); + assertPermuations(input1, input2, inputType, expected1, expected2, nullValue, expectedType, expectedArrayType); + } + } + + /** + * @param input1 Singleton or first array input value + * @param input2 Second array input value + */ + public static <T,U> ConversionAssert<T,U> from(T input1, T input2) { + return new ConversionAssert<T,U>(input1, input2, false); + } + + /** + * @param input1 Singleton or first array input value + * @param input2 Second array input value + */ + public static <T,U> ConversionAssert<T,U> fromPrimitive(T input1, T input2) { + return new ConversionAssert<T,U>(input1, input2, true); + } + + private static <T,U> void assertPermuations(T input1, T input2, Class<T> inputType, + U expected1, U expected2, U nullValue, Class<U> expectedType, Class<U[]> expectedArrayType) { + + // single value to single value + assertConversion(expected1, input1, expectedType); + + // single value to array + Object expectedSingletonArray; + if (expected1 == null && expected2 == null) { + expectedSingletonArray = Array.newInstance(expectedType, 0); + } + else { + expectedSingletonArray = Array.newInstance(expectedType, 1); + Array.set(expectedSingletonArray, 0, expected1); + } + assertConversion(expectedSingletonArray, input1, expectedArrayType); + + // array to array + Object inputDoubleArray = Array.newInstance(inputType, 2); + Array.set(inputDoubleArray, 0, input1); + Array.set(inputDoubleArray, 1, input2); + Object expectedDoubleArray; + if (expected1 == null && expected2 == null) { + expectedDoubleArray = Array.newInstance(expectedType, 0); + } + else { + expectedDoubleArray = Array.newInstance(expectedType, 2); + Array.set(expectedDoubleArray, 0, expected1); + Array.set(expectedDoubleArray, 1, expected2); + } + assertConversion(expectedDoubleArray, inputDoubleArray, expectedArrayType); + + // array to single (first) value + assertConversion(expected1, inputDoubleArray, expectedType); + + // null to single value + assertConversion(nullValue, null, expectedType); + + // null to array + assertConversion(null, null, expectedArrayType); + + // empty array to single value + Object inputEmptyArray = Array.newInstance(inputType, 0); + assertConversion(nullValue, inputEmptyArray, expectedType); + + // empty array to array + Object expectedEmptyArray = Array.newInstance(expectedType, 0); + assertConversion(expectedEmptyArray, inputEmptyArray, expectedArrayType); + } + + @SuppressWarnings("unchecked") + private static <T,U> void assertConversion(Object expected, Object input, Class<U> type) { + U result = ObjectConverter.convert(input, type); + String msg = "Convert '" + toString(input) + "' to " + type.getSimpleName(); + if (expected == null) { + assertNull(msg, result); + } + else if (expected.getClass().isArray()) { + assertArrayEquals(msg, (U[])toStringIfDate(expected), (U[])toStringIfDate(result)); + } + else { + assertEquals(msg, toStringIfDate(expected), toStringIfDate(result)); + } + } + + private static String toString(Object input) { + if (input == null) { + return "null"; + } + else if (input.getClass().isArray()) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i=0; i<Array.getLength(input); i++) { + if (i > 0) { + sb.append(","); + } + sb.append(toString(Array.get(input, i))); + } + sb.append("]"); + return sb.toString(); + } + else { + return toStringIfDate(input).toString(); + } + } + + private static Object toStringIfDate(Object input) { + if (input == null) { + return null; + } + if (input instanceof Calendar) { + return "(Calendar)" + DateUtils.calendarToString((Calendar)input); + } + if (input instanceof Date) { + return "(Date)" + DateUtils.dateToString((Date)input); + } + if (input.getClass().isArray()) { + if (Calendar.class.isAssignableFrom(input.getClass().getComponentType()) + || input.getClass().getComponentType() == Date.class) { + Object[] resultArray = new String[Array.getLength(input)]; + for (int i=0; i<Array.getLength(input); i++) { + resultArray[i] = toStringIfDate(Array.get(input, i)); + } + return resultArray; + } + } + return input; + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/Convert.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,233 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import static org.apache.sling.fsprovider.internal.mapper.valuemap.DateUtils.calendarToString; +import static org.apache.sling.fsprovider.internal.mapper.valuemap.DateUtils.toCalendar; +import static org.apache.sling.fsprovider.internal.mapper.valuemap.DateUtils.toDate; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNull; + +import java.math.BigDecimal; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.junit.Test; + +/** + * This is copied from org.apache.sling.api.wrappers.impl.ObjectConverterTest + */ +public class ObjectConverterTest { + + private static final String STRING_1 = "item1"; + private static final String STRING_2 = "item2"; + private static final boolean BOOLEAN_1 = true; + private static final boolean BOOLEAN_2 = false; + private static final byte BYTE_1 = (byte)0x01; + private static final byte BYTE_2 = (byte)0x02; + private static final short SHORT_1 = (short)12; + private static final short SHORT_2 = (short)34; + private static final int INT_1 = 55; + private static final int INT_2 = -123; + private static final long LONG_1 = 1234L; + private static final long LONG_2 = -4567L; + private static final float FLOAT_1 = 1.23f; + private static final float FLOAT_2 = -4.56f; + private static final double DOUBLE_1 = 12.34d; + private static final double DOUBLE_2 = -45.67d; + private static final BigDecimal BIGDECIMAL_1 = new BigDecimal("12345.67"); + private static final BigDecimal BIGDECIMAL_2 = new BigDecimal("-23456.78"); + private static final Calendar CALENDAR_1 = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US); + private static final Calendar CALENDAR_2 = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US); + { + CALENDAR_1.set(2016, 10, 15, 8, 20, 30); + CALENDAR_2.set(2015, 6, 31, 19, 10, 20); + } + private static final Date DATE_1 = toDate(CALENDAR_1); + private static final Date DATE_2 = toDate(CALENDAR_2); + + @Test + public void testDateToString() { + Convert.from(STRING_1, STRING_2).to(STRING_1, STRING_2).test(); + Convert.fromPrimitive(BOOLEAN_1, BOOLEAN_2).to(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2)).test(); + Convert.from(BOOLEAN_1, BOOLEAN_2).to(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2)).test(); + Convert.fromPrimitive(BYTE_1, BYTE_2).to(Byte.toString(BYTE_1), Byte.toString(BYTE_2)).test(); + Convert.from(BYTE_1, BYTE_2).to(Byte.toString(BYTE_1), Byte.toString(BYTE_2)).test(); + Convert.fromPrimitive(SHORT_1, SHORT_2).to(Short.toString(SHORT_1), Short.toString(SHORT_2)).test(); + Convert.from(SHORT_1, SHORT_2).to(Short.toString(SHORT_1), Short.toString(SHORT_2)).test(); + Convert.fromPrimitive(INT_1, INT_2).to(Integer.toString(INT_1), Integer.toString(INT_2)).test(); + Convert.from(INT_1, INT_2).to(Integer.toString(INT_1), Integer.toString(INT_2)).test(); + Convert.fromPrimitive(LONG_1, LONG_2).to(Long.toString(LONG_1), Long.toString(LONG_2)).test(); + Convert.from(LONG_1, LONG_2).to(Long.toString(LONG_1), Long.toString(LONG_2)).test(); + Convert.fromPrimitive(FLOAT_1, FLOAT_2).to(Float.toString(FLOAT_1), Float.toString(FLOAT_2)).test(); + Convert.from(FLOAT_1, FLOAT_2).to(Float.toString(FLOAT_1), Float.toString(FLOAT_2)).test(); + Convert.fromPrimitive(DOUBLE_1, DOUBLE_2).to(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2)).test(); + Convert.from(DOUBLE_1, DOUBLE_2).to(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2)).test(); + Convert.from(BIGDECIMAL_1, BIGDECIMAL_2).to(BIGDECIMAL_1.toString(), BIGDECIMAL_2.toString()).test(); + Convert.from(CALENDAR_1, CALENDAR_2).to(calendarToString(CALENDAR_1), calendarToString(CALENDAR_2)).test(); + Convert.from(DATE_1, DATE_2).to(calendarToString(toCalendar(DATE_1)), calendarToString(toCalendar(DATE_2))).test(); + } + + @Test + public void testToBoolean() { + Convert.fromPrimitive(BOOLEAN_1, BOOLEAN_2).to(BOOLEAN_1, BOOLEAN_2).test(); + Convert.from(BOOLEAN_1, BOOLEAN_2).to(BOOLEAN_1, BOOLEAN_2).test(); + Convert.from(Boolean.toString(BOOLEAN_1), Boolean.toString(BOOLEAN_2)).to(BOOLEAN_1, BOOLEAN_2).test(); + + // test other types that should not be converted + Convert.<Integer,Boolean>from(INT_1, INT_2).toNull(Boolean.class).test(); + Convert.<Date,Boolean>from(DATE_1, DATE_2).toNull(Boolean.class).test(); + } + + @Test + public void testToByte() { + Convert.fromPrimitive(BYTE_1, BYTE_2).to(BYTE_1, BYTE_2).test(); + Convert.from(BYTE_1, BYTE_2).to(BYTE_1, BYTE_2).test(); + Convert.from(Byte.toString(BYTE_1), Byte.toString(BYTE_2)).to(BYTE_1, BYTE_2).test(); + + // test conversion from other number types + Convert.from(INT_1, INT_2).to((byte)INT_1, (byte)INT_2).test(); + Convert.fromPrimitive(INT_1, INT_2).to((byte)INT_1, (byte)INT_2).test(); + + // test other types that should not be converted + Convert.<Date,Byte>from(DATE_1, DATE_2).toNull(Byte.class).test(); + } + + @Test + public void testToShort() { + Convert.fromPrimitive(SHORT_1, SHORT_2).to(SHORT_1, SHORT_2).test(); + Convert.from(SHORT_1, SHORT_2).to(SHORT_1, SHORT_2).test(); + Convert.from(Short.toString(SHORT_1), Short.toString(SHORT_2)).to(SHORT_1, SHORT_2).test(); + + // test conversion from other number types + Convert.from(INT_1, INT_2).to((short)INT_1, (short)INT_2).test(); + Convert.fromPrimitive(INT_1, INT_2).to((short)INT_1, (short)INT_2).test(); + + // test other types that should not be converted + Convert.<Date,Short>from(DATE_1, DATE_2).toNull(Short.class).test(); + } + + @Test + public void testToInteger() { + Convert.fromPrimitive(INT_1, INT_2).to(INT_1, INT_2).test(); + Convert.from(INT_1, INT_2).to(INT_1, INT_2).test(); + Convert.from(Integer.toString(INT_1), Integer.toString(INT_2)).to(INT_1, INT_2).test(); + + // test conversion from other number types + Convert.from(SHORT_1, SHORT_2).to((int)SHORT_1, (int)SHORT_2).test(); + Convert.fromPrimitive(SHORT_1, SHORT_2).to((int)SHORT_1, (int)SHORT_2).test(); + + // test other types that should not be converted + Convert.<Date,Integer>from(DATE_1, DATE_2).toNull(Integer.class).test(); + } + + @Test + public void testToLong() { + Convert.fromPrimitive(LONG_1, LONG_2).to(LONG_1, LONG_2).test(); + Convert.from(LONG_1, LONG_2).to(LONG_1, LONG_2).test(); + Convert.from(Long.toString(LONG_1), Long.toString(LONG_2)).to(LONG_1, LONG_2).test(); + + // test conversion from other number types + Convert.from(SHORT_1, SHORT_2).to((long)SHORT_1, (long)SHORT_2).test(); + Convert.fromPrimitive(SHORT_1, SHORT_2).to((long)SHORT_1, (long)SHORT_2).test(); + + // test other types that should not be converted + Convert.<Date,Long>from(DATE_1, DATE_2).toNull(Long.class).test(); + } + + @Test + public void testToFloat() { + Convert.fromPrimitive(FLOAT_1, FLOAT_2).to(FLOAT_1, FLOAT_2).test(); + Convert.from(FLOAT_1, FLOAT_2).to(FLOAT_1, FLOAT_2).test(); + Convert.from(Float.toString(FLOAT_1), Float.toString(FLOAT_2)).to(FLOAT_1, FLOAT_2).test(); + + // test conversion from other number types + Convert.from(SHORT_1, SHORT_2).to((float)SHORT_1, (float)SHORT_2).test(); + Convert.fromPrimitive(SHORT_1, SHORT_2).to((float)SHORT_1, (float)SHORT_2).test(); + + // test other types that should not be converted + Convert.<Date,Float>from(DATE_1, DATE_2).toNull(Float.class).test(); + } + + @Test + public void testToDouble() { + Convert.fromPrimitive(DOUBLE_1, DOUBLE_2).to(DOUBLE_1, DOUBLE_2).test(); + Convert.from(DOUBLE_1, DOUBLE_2).to(DOUBLE_1, DOUBLE_2).test(); + Convert.from(Double.toString(DOUBLE_1), Double.toString(DOUBLE_2)).to(DOUBLE_1, DOUBLE_2).test(); + + // test conversion from other number types + Convert.from(SHORT_1, SHORT_2).to((double)SHORT_1, (double)SHORT_2).test(); + Convert.fromPrimitive(SHORT_1, SHORT_2).to((double)SHORT_1, (double)SHORT_2).test(); + + // test other types that should not be converted + Convert.<Date,Double>from(DATE_1, DATE_2).toNull(Double.class).test(); + } + + @Test + public void testToBigDecimal() { + Convert.from(BIGDECIMAL_1, BIGDECIMAL_2).to(BIGDECIMAL_1, BIGDECIMAL_2).test(); + Convert.from(BIGDECIMAL_1.toString(), BIGDECIMAL_2.toString()).to(BIGDECIMAL_1, BIGDECIMAL_2).test(); + + // test conversion from other number types + Convert.from(LONG_1, LONG_2).to(BigDecimal.valueOf(LONG_1), BigDecimal.valueOf(LONG_2)).test(); + Convert.fromPrimitive(LONG_1, LONG_2).to(BigDecimal.valueOf(LONG_1), BigDecimal.valueOf(LONG_2)).test(); + Convert.from(DOUBLE_1, DOUBLE_2).to(BigDecimal.valueOf(DOUBLE_1), BigDecimal.valueOf(DOUBLE_2)).test(); + Convert.fromPrimitive(DOUBLE_1, DOUBLE_2).to(BigDecimal.valueOf(DOUBLE_1), BigDecimal.valueOf(DOUBLE_2)).test(); + + // test other types that should not be converted + Convert.<Date,BigDecimal>from(DATE_1, DATE_2).toNull(BigDecimal.class).test(); + } + + @Test + public void testToCalendar() { + Convert.from(CALENDAR_1, CALENDAR_2).to(CALENDAR_1, CALENDAR_2).test(); + Convert.from(DateUtils.calendarToString(CALENDAR_1), DateUtils.calendarToString(CALENDAR_2)).to(CALENDAR_1, CALENDAR_2).test(); + + // test conversion from other date types + Convert.from(DATE_1, DATE_2).to(toCalendar(DATE_1), toCalendar(DATE_2)).test(); + + // test other types that should not be converted + Convert.<String,Calendar>from(STRING_1, STRING_2).toNull(Calendar.class).test(); + Convert.<Boolean,Calendar>from(BOOLEAN_1, BOOLEAN_2).toNull(Calendar.class).test(); + } + + @Test + public void testToDate() { + Convert.from(DATE_1, DATE_2).to(DATE_1, DATE_2).test(); + Convert.from(DateUtils.dateToString(DATE_1), DateUtils.dateToString(DATE_2)).to(DATE_1, DATE_2).test(); + + // test conversion from other date types + Convert.from(CALENDAR_1, CALENDAR_2).to(toDate(CALENDAR_1), toDate(CALENDAR_2)).test(); + + // test other types that should not be converted + Convert.<String,Date>from(STRING_1, STRING_2).toNull(Date.class).test(); + Convert.<Boolean,Date>from(BOOLEAN_1, BOOLEAN_2).toNull(Date.class).test(); + } + + @Test + public void testPrimitiveByteArray() { + byte[] array = new byte[] { 0x01, 0x02, 0x03 }; + assertArrayEquals(array, ObjectConverter.convert(array, byte[].class)); + assertArrayEquals(new byte[0], ObjectConverter.convert(new byte[0], byte[].class)); + assertNull(ObjectConverter.convert(null, byte[].class)); + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ObjectConverterTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,157 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.sling.api.resource.ValueMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +/** + * This is copied from org.apache.sling.api.wrappers.ValueMapDecoratorTest + */ +public class ValueMapDecoratorTest { + + private Map<String, Object> map; + private ValueMap valueMap; + + @Before + public void setUp() { + map = new HashMap<String, Object>(); + valueMap = new ValueMapDecorator(map); + } + + // SLING-4178 + @Test + public void testIncompatibleTypeInArray() { + map.put("prop1", new String[] { "test", "test2" }); + map.put("prop2", "test"); + Assert.assertArrayEquals("Not convertible type should return empty array", new Integer[0], valueMap.get("prop1", Integer[].class)); + Assert.assertArrayEquals("Not convertible type should return empt array", new Integer[0], valueMap.get("prop2", Integer[].class)); + } + + // SLING-662 + @Test + public void testGettingArraysFromSingleValueEntries() { + map.put("prop1", "test"); + map.put("prop2", "1"); + Assert.assertArrayEquals( + "Even though the underlying entry is single-value if should be enclosed in a single element array", + new String[] { "test" }, valueMap.get("prop1", String[].class)); + Assert.assertArrayEquals( + "Even though the underlying entry is single-value if should be enclosed in a single element array", + new Integer[] { 1 }, valueMap.get("prop2", Integer[].class)); + } + + @Test + public void testGettingArraysFromMultiValueEntries() { + map.put("prop1", new String[] { "test", "test2" }); + map.put("prop2", new String[] { "1", "2" }); + Assert.assertArrayEquals("Could not get values from underlying array", new String[] { "test", "test2" }, + valueMap.get("prop1", String[].class)); + Assert.assertArrayEquals("Conversion to Integer was not possible", new Integer[] { 1, 2 }, + valueMap.get("prop2", Integer[].class)); + } + + @Test + public void testGettingSingleValuesFromMultiValueEntries() { + map.put("prop1", new String[] { "test", "test2" }); + map.put("prop2", new String[] { "1", "2" }); + Assert.assertEquals("First element from underlying array should be returned", "test", + valueMap.get("prop1", String.class)); + Assert.assertEquals("First element from underlying array should be returned", Integer.valueOf(1), + valueMap.get("prop2", Integer.class)); + } + + @Test + public void testGettingInvalidEntryWithDefaultValue() { + Assert.assertEquals(Integer.valueOf(1), valueMap.get("prop1", 1)); + Assert.assertEquals("test", valueMap.get("prop1", "test")); + } + + @Test + public void testPrimitiveTypes() { + map.put("prop1", new String[] { "1", "2" }); + Assert.assertNull("ValueMap should not support conversion to primitive type", valueMap.get("prop1", int.class)); + } + @Test(expected=ClassCastException.class) + public void testPrimitiveTypesArray() { + map.put("prop1", new String[] { "1", "2" }); + Assert.assertArrayEquals("ValueMap should not support conversion to array of primitive type", + new int[0], valueMap.get("prop1", int[].class)); + } + + @Test + public void testEqualsAndHashCodeOfEqualValueMapsWithNonArrayTypes() { + map.put("prop1", "some string"); + ValueMapDecorator valueMap2 = new ValueMapDecorator(map); + Assert.assertTrue("Two ValueMapDecorators based on the same map should be equal", valueMap.equals(valueMap2)); + Assert.assertEquals("Two equal ValueMapDecorators should have the same hash code", valueMap.hashCode(), + valueMap2.hashCode()); + + ValueMapDecorator valueMap3 = new ValueMapDecorator(new HashMap<String, Object>()); + valueMap3.put("prop1", "some string"); + Assert.assertEquals(valueMap, valueMap3); + Assert.assertEquals("Two equal ValueMapDecorators should have the same hash code", valueMap.hashCode(), + valueMap3.hashCode()); + + Assert.assertEquals(map, valueMap); + Assert.assertEquals(valueMap, map); + } + + @Ignore("SLING-4784") + @Test + public void testEqualsAndHashCodeOfEqualValueMapsWithArrayTypes() { + map.put("prop1", new String[] { "1", "2" }); + ValueMapDecorator valueMap2 = new ValueMapDecorator(map); + Assert.assertTrue("Two ValueMapDecorators based on the same map should be equal", valueMap.equals(valueMap2)); + Assert.assertEquals("Two equal ValueMapDecorators should have the same hash code", valueMap.hashCode(), + valueMap2.hashCode()); + + ValueMapDecorator valueMap3 = new ValueMapDecorator(new HashMap<String, Object>()); + valueMap3.put("prop1", new String[] { "1", "2" }); + Assert.assertEquals(valueMap, valueMap3); + Assert.assertEquals("Two equal ValueMapDecorators should have the same hash code", valueMap.hashCode(), + valueMap3.hashCode()); + } + + @Test + public void testEqualsOfInequalValueMapsWithNonArrayTypes() { + valueMap.put("prop", "value"); + ValueMapDecorator valueMap2 = new ValueMapDecorator(new HashMap<String, Object>()); + valueMap2.put("prop", "value2"); + Assert.assertFalse("Two ValueMapDecorators based on maps with different entries should not be equal", + valueMap.equals(valueMap2)); + + } + + @Test + public void testEqualsOfInequalValueMapsWithArrayTypes() { + valueMap.put("prop", new String[] { "1", "2" }); + ValueMapDecorator valueMap2 = new ValueMapDecorator(new HashMap<String, Object>()); + valueMap2.put("prop", new String[] { "3", "4" }); + Assert.assertFalse("Two ValueMapDecorators based on maps with different entries should not be equal", + valueMap.equals(valueMap2)); + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapDecoratorTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java?rev=1786361&view=auto ============================================================================== --- sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java (added) +++ sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java Fri Mar 10 14:58:17 2017 @@ -0,0 +1,55 @@ +/* + * 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.fsprovider.internal.mapper.valuemap; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.sling.api.resource.ValueMap; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +public class ValueMapUtilTest { + + @Test + public void testToValueMap() { + Map<String,Object> content = new HashMap<>(); + content.put("stringProp", "abc"); + content.put("intProp", 123); + content.put("childNode", ImmutableMap.<String,Object>of()); + content.put("stringArray", new String[] { "a", "b", "c" }); + content.put("stringList", ImmutableList.of("ab", "cd")); + content.put("intList", ImmutableList.of(12, 34)); + + ValueMap props = ValueMapUtil.toValueMap(content); + assertEquals("abc", props.get("stringProp", String.class)); + assertEquals((Integer)123, props.get("intProp", 0)); + assertNull(props.get("childNode")); + assertArrayEquals(new String[] { "a", "b", "c" }, props.get("stringArray", String[].class)); + assertArrayEquals(new String[] { "ab", "cd" }, props.get("stringList", String[].class)); + assertArrayEquals(new Integer[] { 12, 34 }, props.get("intList", Integer[].class)); + } + +} Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Fri Mar 10 14:58:17 2017 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/valuemap/ValueMapUtilTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain