Author: davidb Date: Wed Jun 29 18:39:20 2016 New Revision: 1750687 URL: http://svn.apache.org/viewvc?rev=1750687&view=rev Log: Felix Converter Service: implement some special cases as adapters and introduce a function with exception.
Added: felix/trunk/converter/src/main/java/org/osgi/service/converter/FunctionThrowsException.java Modified: felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterService.java felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/json/JsonCodecTest.java Modified: felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java?rev=1750687&r1=1750686&r2=1750687&view=diff ============================================================================== --- felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java (original) +++ felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java Wed Jun 29 18:39:20 2016 @@ -20,18 +20,18 @@ import java.lang.reflect.Type; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; import org.osgi.service.converter.Adapter; import org.osgi.service.converter.ConversionException; import org.osgi.service.converter.Converter; import org.osgi.service.converter.Converting; +import org.osgi.service.converter.FunctionThrowsException; import org.osgi.service.converter.Rule; import org.osgi.service.converter.TypeReference; public class AdapterImpl implements Adapter { private final Converter delegate; - private final Map<TypePair, Function<Object, Object>> classRules = + private final Map<TypePair, FunctionThrowsException<Object, Object>> classRules = new ConcurrentHashMap<>(); public AdapterImpl(Converter converter) { @@ -52,23 +52,25 @@ public class AdapterImpl implements Adap @SuppressWarnings("unchecked") @Override public <F, T> Adapter rule(Class<F> fromCls, Class<T> toCls, - Function<F, T> toFun, Function<T, F> fromFun) { + FunctionThrowsException<F, T> toFun, FunctionThrowsException<T, F> fromFun) { if (fromCls.equals(toCls)) throw new IllegalArgumentException(); - classRules.put(new TypePair(fromCls, toCls), (Function<Object, Object>) toFun); - classRules.put(new TypePair(toCls, fromCls), (Function<Object, Object>) fromFun); + classRules.put(new TypePair(fromCls, toCls), (FunctionThrowsException<Object, Object>) toFun); + classRules.put(new TypePair(toCls, fromCls), (FunctionThrowsException<Object, Object>) fromFun); return this; } @Override - public <F, T> Adapter rule(TypeReference<F> fromRef, TypeReference<T> toRef, Function<F, T> toFun, Function<T, F> fromFun) { + public <F, T> Adapter rule(TypeReference<F> fromRef, TypeReference<T> toRef, + FunctionThrowsException<F, T> toFun, FunctionThrowsException<T, F> fromFun) { // TODO Auto-generated method stub return null; } @Override - public <F, T> Adapter rule(Type fromType, Type toType, Function<F, T> toFun, Function<T, F> fromFun) { + public <F, T> Adapter rule(Type fromType, Type toType, + FunctionThrowsException<F, T> toFun, FunctionThrowsException<T, F> fromFun) { // TODO Auto-generated method stub return null; } @@ -114,7 +116,7 @@ public class AdapterImpl implements Adap @Override public Object to(Type type) { if (object != null) { - Function<Object, Object> f = classRules.get( + FunctionThrowsException<Object, Object> f = classRules.get( new TypePair(object.getClass(), Util.primitiveToBoxed(type))); if (f != null) { try { Modified: felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterService.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterService.java?rev=1750687&r1=1750686&r2=1750687&view=diff ============================================================================== --- felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterService.java (original) +++ felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConverterService.java Wed Jun 29 18:39:20 2016 @@ -34,15 +34,21 @@ public class ConverterService implements public ConverterService() { Adapter a = new ConverterImpl().getAdapter(); - a.rule(UUID.class, String.class, UUID::toString, UUID::fromString); - a.rule(Pattern.class, String.class, Pattern::toString, Pattern::compile); + a.rule(Character.class, Boolean.class, v -> v.charValue() != 0, + v -> v.booleanValue() ? (char) 1 : (char) 0); + a.rule(Character.class, String.class, v -> v.toString(), + v -> v.length() > 0 ? v.charAt(0) : 0); + a.rule(Class.class, String.class, Class::toString, + v -> getClass().getClassLoader().loadClass(v)); + a.rule(Integer.class, String.class, v -> v.toString(), Integer::parseInt); a.rule(LocalDateTime.class, String.class, LocalDateTime::toString, LocalDateTime::parse); a.rule(LocalDate.class, String.class, LocalDate::toString, LocalDate::parse); a.rule(LocalTime.class, String.class, LocalTime::toString, LocalTime::parse); a.rule(OffsetDateTime.class, String.class, OffsetDateTime::toString, OffsetDateTime::parse); a.rule(OffsetTime.class, String.class, OffsetTime::toString, OffsetTime::parse); + a.rule(Pattern.class, String.class, Pattern::toString, Pattern::compile); + a.rule(UUID.class, String.class, UUID::toString, UUID::fromString); a.rule(ZonedDateTime.class, String.class, ZonedDateTime::toString, ZonedDateTime::parse); - a.rule(Integer.class, String.class, v -> v.toString(), Integer::parseInt); adapter = a; } Modified: felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java?rev=1750687&r1=1750686&r2=1750687&view=diff ============================================================================== --- felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java (original) +++ felix/trunk/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java Wed Jun 29 18:39:20 2016 @@ -67,11 +67,7 @@ public class ConvertingImpl implements C @Override public Converting defaultValue(Object defVal) { - if (object == null) - object = defVal; // TODO do we need this??? - else - defaultValue = defVal; - + defaultValue = defVal; hasDefault = true; return this; @@ -298,6 +294,9 @@ public class ConvertingImpl implements C } private Object handleNull(Class<?> cls) { + if (hasDefault) + return converter.convert(defaultValue).to(cls); + Class<?> boxed = Util.primitiveToBoxed(cls); if (boxed.equals(cls)) { // This is not a primitive, just return null @@ -324,38 +323,23 @@ public class ConvertingImpl implements C // TODO some of these can probably be implemented as an adapter if (Boolean.class.equals(targetCls)) { - if (object instanceof Character) { - return ((Character) object).charValue() != (char) 0; - } else if (object instanceof Number) { + if (object instanceof Number) { return ((Number) object).longValue() != 0; } else if (object instanceof Collection && ((Collection<?>) object).size() == 0) { + // TODO What about arrays? return Boolean.FALSE; } } else if (Character.class.equals(targetCls)) { - if (object instanceof Boolean) { - return ((Boolean) object).booleanValue() ? Character.valueOf((char) 1) : Character.valueOf((char) 0); - } else if (object instanceof Number) { + if (object instanceof Number) { return Character.valueOf((char) ((Number) object).intValue()); - } else { - String v = converter.convert(object).toString(); - if (v == null) - return 0; - else - return v.length() > 0 ? v.charAt(0) : 0; } - } else if (Integer.class.equals(targetCls)) { + } else if (Number.class.isAssignableFrom(targetCls)) { if (object instanceof Boolean) { - return ((Boolean) object).booleanValue() ? Integer.valueOf(1) : Integer.valueOf(0); + return ((Boolean) object).booleanValue() ? 1 : 0; } } else if (Class.class.equals(targetCls)) { if (object instanceof Collection && ((Collection<?>) object).size() == 0) { return null; - } else { - try { - return getClass().getClassLoader().loadClass(converter.convert(object).toString()); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } } } else if (Enum.class.isAssignableFrom(targetCls)) { if (object instanceof Boolean) { Modified: felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java?rev=1750687&r1=1750686&r2=1750687&view=diff ============================================================================== --- felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java (original) +++ felix/trunk/converter/src/main/java/org/osgi/service/converter/Adapter.java Wed Jun 29 18:39:20 2016 @@ -16,7 +16,6 @@ package org.osgi.service.converter; import java.lang.reflect.Type; -import java.util.function.Function; /** * An {@link Adapter} is used to modify the behaviour of the Converter service, @@ -54,11 +53,11 @@ public interface Adapter extends Convert * @return The current adapter, can be used to chain invocations. */ <F, T> Adapter rule(Class<F> fromCls, Class<T> toCls, - Function<F, T> toFun, Function<T, F> fromFun); + FunctionThrowsException<F, T> toFun, FunctionThrowsException<T, F> fromFun); <F, T> Adapter rule(TypeReference<F> fromRef, TypeReference<T> toRef, - Function<F, T> toFun, Function<T, F> fromFun); + FunctionThrowsException<F, T> toFun, FunctionThrowsException<T, F> fromFun); <F, T> Adapter rule(Type fromType, Type toType, - Function<F, T> toFun, Function<T, F> fromFun); + FunctionThrowsException<F, T> toFun, FunctionThrowsException<T, F> fromFun); } Added: felix/trunk/converter/src/main/java/org/osgi/service/converter/FunctionThrowsException.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/main/java/org/osgi/service/converter/FunctionThrowsException.java?rev=1750687&view=auto ============================================================================== --- felix/trunk/converter/src/main/java/org/osgi/service/converter/FunctionThrowsException.java (added) +++ felix/trunk/converter/src/main/java/org/osgi/service/converter/FunctionThrowsException.java Wed Jun 29 18:39:20 2016 @@ -0,0 +1,33 @@ +/* + * Copyright (c) OSGi Alliance (2016). All Rights Reserved. + * + * Licensed 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.osgi.service.converter; + +/** + * A function that can throw an exception. + * + * @param <T> The type of the input to the function. + * @param <R> The type of the result of the function. + */ +@FunctionalInterface +public interface FunctionThrowsException<T, R> { + /** + * Applies this function to the argument. + * @param t The function argument + * @return The function result + * @throws Exception An exception can be thrown by the function. + */ + R apply(T t) throws Exception; +} Modified: felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/json/JsonCodecTest.java URL: http://svn.apache.org/viewvc/felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/json/JsonCodecTest.java?rev=1750687&r1=1750686&r2=1750687&view=diff ============================================================================== --- felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/json/JsonCodecTest.java (original) +++ felix/trunk/converter/src/test/java/org/apache/felix/converter/impl/json/JsonCodecTest.java Wed Jun 29 18:39:20 2016 @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.Map; import org.apache.felix.converter.impl.ConverterImpl; -import org.apache.felix.converter.impl.json.JsonCodecImpl; import org.apache.sling.commons.json.JSONException; import org.apache.sling.commons.json.JSONObject; import org.junit.After;