You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by da...@apache.org on 2016/09/06 18:32:50 UTC

svn commit: r1759480 - in /felix/trunk/converter/converter/src: main/java/org/apache/felix/converter/impl/ main/java/org/osgi/service/converter/ test/java/org/apache/felix/converter/impl/

Author: davidb
Date: Tue Sep  6 18:32:50 2016
New Revision: 1759480

URL: http://svn.apache.org/viewvc?rev=1759480&view=rev
Log:
Felix Converter Service - Add Convert Result data class.

Added:
    felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertResult.java
Modified:
    felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
    felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertFunction.java
    felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/SimpleConvertFunction.java
    felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/AdapterTest.java

Modified: felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java?rev=1759480&r1=1759479&r2=1759480&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java (original)
+++ felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java Tue Sep  6 18:32:50 2016
@@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentHa
 import org.osgi.service.converter.Adapter;
 import org.osgi.service.converter.ConversionException;
 import org.osgi.service.converter.ConvertFunction;
+import org.osgi.service.converter.ConvertResult;
 import org.osgi.service.converter.Converter;
 import org.osgi.service.converter.Converting;
 import org.osgi.service.converter.Rule;
@@ -167,9 +168,9 @@ public class AdapterImpl implements Adap
                         continue;
 
                     try {
-                        Object res = func.convert(object, type);
-                        if (res != ConvertFunction.CANNOT_CONVERT)
-                            return res;
+                        ConvertResult<?> res = func.convert(object, type);
+                        if (res.getStatus() == ConvertResult.Status.CONVERTED)
+                            return res.getResult();
                     } catch (Exception ex) {
                         if (hasDefault)
                             return defaultValue;

Modified: felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertFunction.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertFunction.java?rev=1759480&r1=1759479&r2=1759480&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertFunction.java (original)
+++ felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertFunction.java Tue Sep  6 18:32:50 2016
@@ -20,7 +20,7 @@ import java.lang.reflect.Type;
 /**
  * An functional interface with a single convert method that is passed the
  * original object and the target type.
- * 
+ *
  * @param <F> Type parameter for the source object.
  * @param <T> Type parameter for the converted object.
  * @author $Id$
@@ -28,18 +28,13 @@ import java.lang.reflect.Type;
 @FunctionalInterface
 public interface ConvertFunction<F, T> {
 	/**
-	 * Used to indicate that the default converter should be used for this
-	 * value.
-	 */
-	public static final Object CANNOT_CONVERT = new Object();
-
-	/**
 	 * Convert the object into the target type.
-	 * 
+	 *
 	 * @param obj The object to be converted.
 	 * @param targetType The target type.
-	 * @return The converted object or {@link #CANNOT_CONVERT} to indicate that
-	 *         this converter cannot handle the conversion.
+	 * @return The conversion result. A {@link ConvertResult} may indicate that conversion
+	 * was not successful. In this case the next matching rule or adapter will be given a
+	 * opportunity to convert.
 	 */
-	T convert(F obj, Type targetType) throws Exception;
+	ConvertResult<T> convert(F obj, Type targetType) throws Exception;
 }

Added: felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertResult.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertResult.java?rev=1759480&view=auto
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertResult.java (added)
+++ felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/ConvertResult.java Tue Sep  6 18:32:50 2016
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+/**
+ * The result of a conversion, which may indicate that the conversion was not
+ * possible and that the next handler in the chain should try to process it.
+ * @param <T> The target of the conversion.
+ */
+public class ConvertResult<T> {
+    /**
+     * The status of the conversion result.
+     */
+    public enum Status { CONVERTED, CANNOT_CONVERT };
+
+    private final Status status;
+    private final T result;
+
+    /**
+     * Return a instance that indicates that conversion cannot be done.
+     * @return A convert result with status {@link ConvertResult.Status#CANNOT_CONVERT}.
+     */
+    public static <T> ConvertResult<T> cannotConvert() {
+        return new ConvertResult<T>(null, Status.CANNOT_CONVERT);
+    }
+
+    /**
+     * Create a conversion result for a successfully converted object.
+     * @param res The conversion result.
+     */
+    public ConvertResult(T res) {
+        this(res, Status.CONVERTED);
+    }
+
+    /**
+     * Create a conversion result with a specific status.
+     * @param res The conversion result.
+     * @param s The status.
+     */
+    public ConvertResult(T res, Status s) {
+        status = s;
+        result = res;
+    }
+
+    public T getResult() {
+        return result;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+}

Modified: felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/SimpleConvertFunction.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/SimpleConvertFunction.java?rev=1759480&r1=1759479&r2=1759480&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/SimpleConvertFunction.java (original)
+++ felix/trunk/converter/converter/src/main/java/org/osgi/service/converter/SimpleConvertFunction.java Tue Sep  6 18:32:50 2016
@@ -23,7 +23,7 @@ import java.lang.reflect.Type;
  * interface via a default method and can be used in cases where the target type
  * does not need to be passed to the {@link #convert} method, for example in
  * Lambda expressions.
- * 
+ *
  * @param <F> Type parameter for the source object.
  * @param <T> Type parameter for the converted object.
  * @author $Id$
@@ -31,16 +31,15 @@ import java.lang.reflect.Type;
 @FunctionalInterface
 public interface SimpleConvertFunction<F, T> extends ConvertFunction<F,T> {
 	@Override
-	default T convert(F obj, Type type) throws Exception {
-		return convert(obj);
+	default ConvertResult<T> convert(F obj, Type type) throws Exception {
+		return new ConvertResult<T>(convert(obj));
 	}
 
 	/**
 	 * Convert the object into the target type.
-	 * 
+	 *
 	 * @param obj The object to be converted.
-	 * @return The converted object or {@link #CANNOT_CONVERT} to indicate that
-	 *         this converter cannot handle the conversion.
+	 * @return The converted object.
 	 */
 	T convert(F obj) throws Exception;
 }

Modified: felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/AdapterTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/AdapterTest.java?rev=1759480&r1=1759479&r2=1759480&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/AdapterTest.java (original)
+++ felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/AdapterTest.java Tue Sep  6 18:32:50 2016
@@ -32,6 +32,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.osgi.service.converter.Adapter;
 import org.osgi.service.converter.ConvertFunction;
+import org.osgi.service.converter.ConvertResult;
 import org.osgi.service.converter.Converter;
 import org.osgi.service.converter.Rule;
 
@@ -82,11 +83,11 @@ public class AdapterTest {
         ca.rule(char[].class, String.class, AdapterTest::convertToString, null);
         ca.rule(new Rule<String, Number>(String.class, Number.class, new ConvertFunction<String, Number>() {
             @Override
-            public Number convert(String obj, Type targetType) throws Exception {
+            public ConvertResult<Number> convert(String obj, Type targetType) throws Exception {
                 if (Integer.class.equals(targetType))
-                    return Integer.valueOf(-1);
+                    return new ConvertResult<Number>(Integer.valueOf(-1));
                 else if (Long.class.equals(targetType))
-                    return Long.valueOf(-1);
+                    return new ConvertResult<Number>(Long.valueOf(-1));
                 return null;
             }
         }));
@@ -102,22 +103,41 @@ public class AdapterTest {
         assertEquals(Long.valueOf(-1), ca2.convert("Hello").to(Long.class));
     }
 
+    @Test
+    public void testCannotHandleSpecific() {
+        Adapter ca = converter.newAdapter();
+
+        ca.rule(new Rule<Integer, Long>(Integer.class, Long.class, new ConvertFunction<Integer,Long>() {
+            @Override
+            public ConvertResult<Long> convert(Integer obj, Type targetType) throws Exception {
+                if (obj.intValue() != 1)
+                    return new ConvertResult<Long>(new Long(-obj.intValue()));
+                return ConvertResult.cannotConvert();
+            }
+        }));
+
+        assertEquals(Long.valueOf(-2), ca.convert(Integer.valueOf(2)).to(Long.class));
+
+        // This is the exception that the rule cannot handle
+        assertEquals(Long.valueOf(1), ca.convert(Integer.valueOf(1)).to(Long.class));
+    }
+
     @Test @SuppressWarnings("rawtypes")
     public void testWildcardAdapter() {
         ConvertFunction<List, Object> foo = new ConvertFunction<List, Object>() {
             @Override
-            public Object convert(List t, Type type) throws Exception {
+            public ConvertResult<Object> convert(List t, Type type) throws Exception {
                 if (type instanceof Class) {
                     if (Number.class.isAssignableFrom((Class<?>) type))
-                        return converter.convert(t.size()).to(type);
+                        return new ConvertResult<Object>(converter.convert(t.size()).to(type));
                 }
-                return ConvertFunction.CANNOT_CONVERT;
+                return ConvertResult.cannotConvert();
             }
         };
 
         Rule<List, Object> r = new Rule<>(List.class, Object.class, foo);
         Rule<Object, Object> allCatch = new Rule<>(Object.class, Object.class,
-                (v,t) -> v.toString());
+                (v,t) -> new ConvertResult<Object>(v.toString()));
 
         Adapter ca = converter.newAdapter();
         ca.rule(r);
@@ -132,13 +152,13 @@ public class AdapterTest {
     public void testWildcardAdapter2() {
         Map<Object, Object> snooped = new HashMap<>();
         Rule<Object, ArrayList> r = new Rule<>(Object.class, ArrayList.class,
-                (v,t) -> null,
-                (v,t) -> "arraylist");
+                (v,t) -> new ConvertResult<ArrayList>(null),
+                (v,t) -> new ConvertResult<Object>("arraylist"));
         Rule<Object, List> r2 = new Rule<>(Object.class, List.class,
-                (v,t) -> null,
-                (v,t) -> "list");
+                (v,t) -> new ConvertResult<List>(null),
+                (v,t) -> new ConvertResult<Object>("list"));
         Rule<Object, Object> allCatch = new Rule<>(Object.class, Object.class,
-                (v,t) -> {snooped.put(v,t); return ConvertFunction.CANNOT_CONVERT;}, null);
+                (v,t) -> {snooped.put(v,t); return ConvertResult.cannotConvert();}, null);
 
         Adapter ca = converter.newAdapter();
         ca.rule(r);