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;


Reply via email to