Author: davidb
Date: Wed Jan 10 19:08:23 2018
New Revision: 1820772

URL: http://svn.apache.org/viewvc?rev=1820772&view=rev
Log:
Felix Converter - support for converting to marker annotations.

Modified:
    
felix/trunk/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java

Modified: 
felix/trunk/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java?rev=1820772&r1=1820771&r2=1820772&view=diff
==============================================================================
--- 
felix/trunk/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java
 (original)
+++ 
felix/trunk/converter/converter/src/main/java/org/osgi/util/converter/ConvertingImpl.java
 Wed Jan 10 19:08:23 2018
@@ -712,8 +712,12 @@ class ConvertingImpl extends AbstractSpe
                        ic.sourceAsBean();
                final Map m = ic.to(Map.class);
 
-               return Proxy.newProxyInstance(targetCls.getClassLoader(), new 
Class[] {
-                               targetCls
+               return createProxy(targetCls, m);
+       }
+
+       private Object createProxy(final Class< ? > cls, final Map< ? , ? > 
data) {
+               return Proxy.newProxyInstance(cls.getClassLoader(), new Class[] 
{
+                               cls
                }, new InvocationHandler() {
                        @SuppressWarnings("boxing")
                        @Override
@@ -727,40 +731,40 @@ class ConvertingImpl extends AbstractSpe
                                                case "hashCode" :
                                                        return 
System.identityHashCode(proxy);
                                                case "toString" :
-                                                       return "Proxy for " + 
targetCls;
+                                                       return "Proxy for " + 
cls;
                                                default :
                                                        throw new 
UnsupportedOperationException("Method "
                                                                        + 
method + " not supported on proxy for "
-                                                                       + 
targetCls);
+                                                                       + cls);
                                        }
                                if (mdDecl.equals(Annotation.class)) {
                                        if 
("annotationType".equals(method.getName())
                                                        && 
method.getParameterTypes().length == 0) {
-                                               return targetCls;
+                                               return cls;
                                        }
                                }
 
                                String propName = 
Util.getInterfacePropertyName(method,
-                                               
Util.getSingleElementAnnotationKey(targetCls, proxy),
+                                               
Util.getSingleElementAnnotationKey(cls, proxy),
                                                proxy);
                                if (propName == null)
                                        return null;
 
-                               Object val = m.get(propName);
+                               Object val = data.get(propName);
                                if (val == null && keysIgnoreCase) {
                                        // try in a case-insensitive way
-                                       for (Iterator it = 
m.keySet().iterator(); it.hasNext()
+                                       for (Iterator it = 
data.keySet().iterator(); it.hasNext()
                                                        && val == null;) {
                                                String k = it.next().toString();
                                                if 
(propName.equalsIgnoreCase(k)) {
-                                                       val = m.get(k);
+                                                       val = data.get(k);
                                                }
                                        }
                                }
 
                                // If no value is available take the default if 
specified
                                if (val == null) {
-                                       if (targetCls.isAnnotation()) {
+                                       if (cls.isAnnotation()) {
                                                val = method.getDefaultValue();
                                        }
 
@@ -870,33 +874,51 @@ class ConvertingImpl extends AbstractSpe
                                        }
                                }
                        }
-               } else if (Annotation.class.isAssignableFrom(sourceClass)) {
+               } else if (Annotation.class.isAssignableFrom(sourceClass)
+                               && isMarkerAnnotation(sourceClass)) {
                        // Special treatment for marker annotations
-                       for (Method m : sourceClass.getDeclaredMethods()) {
-                               try {
-                                       if 
(Annotation.class.getMethod(m.getName(),
-                                                       
m.getParameterTypes()).getReturnType().equals(
-                                                                       
m.getReturnType()))
-                                               // this is a base annotation 
method
-                                               continue;
-                               } catch (Exception ex) {
-                                       // Method not found, not a marker 
annotation
-                               }
-                               return null;
-                       }
-
                        Class< ? > ann = Util.getAnnotationType(sourceClass, 
object);
-                       String key = Util.toSingleElementAnnotationKey(
-                                       ann.getSimpleName());
+                       String key = 
Util.toSingleElementAnnotationKey(ann.getSimpleName());
                        return converter
                                        .convert(Collections.singletonMap(key, 
Boolean.TRUE))
                                        .targetAs(targetAsClass)
                                        .to(targetType);
-
+               } else if (Annotation.class.isAssignableFrom(targetAsClass)
+                               && isMarkerAnnotation(targetAsClass)) {
+                       Map<String,Boolean> representation = 
Converters.standardConverter()
+                                       .convert(object)
+                                       .to(new 
TypeReference<Map<String,Boolean>>() {
+                                               /* empty subclass */
+                                       });
+                       if (Boolean.TRUE.equals(
+                                       
representation.get(Util.toSingleElementAnnotationKey(
+                                                       
targetAsClass.getSimpleName())))) {
+                               return createProxy(targetClass, 
Collections.emptyMap());
+                       } else {
+                               throw new ConversionException("Cannot convert " 
+ object
+                                               + " to marker annotation " + 
targetAsClass);
+                       }
                }
                return null;
        }
 
+       private boolean isMarkerAnnotation(Class< ? > annClass) {
+               for (Method m : annClass.getDeclaredMethods()) {
+                       try {
+                               if (Annotation.class
+                                               .getMethod(m.getName(), 
m.getParameterTypes())
+                                               .getReturnType()
+                                               .equals(m.getReturnType()))
+                                       // this is a base annotation method
+                                       continue;
+                       } catch (Exception ex) {
+                               // Method not found, not a marker annotation
+                       }
+                       return false;
+               }
+               return true;
+       }
+
        @SuppressWarnings("unchecked")
        private <T> T tryStandardMethods() {
                try {


Reply via email to