You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by tb...@apache.org on 2013/12/06 17:52:46 UTC

[04/50] [abbrv] Poc for ListsDs and Processor

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bebf610/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
index e30e382..cc9cd6c 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/edm/AnnotationHelper.java
@@ -20,61 +20,274 @@ package org.apache.olingo.odata2.core.annotation.edm;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+
 import org.apache.olingo.odata2.api.annotation.edm.EdmComplexEntity;
 import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 /**
  *
  */
 public class AnnotationHelper {
-
-  public Object getValueForField(Object result, Class<? extends Annotation> annotation) {
-    if(result == null) {
+  
+  public static final class ODataAnnotationException extends ODataException {
+    public ODataAnnotationException(String message) {
+      super(message);
+    }
+  }
+  
+  public Class<?> getFieldTypeForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+    if (instance == null) {
       return null;
     }
-    return getValueForField(result, result.getClass(), annotation, true);
+    
+    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+    if(field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName 
+              + "' found at class '" + instance.getClass() + "'.");
+    }
+    return field.getType();
   }
 
-  private Object getValueForField(Object result, Class<?> resultClass, 
-          Class<? extends Annotation> annotation, boolean inherited) {
-    if(result == null) {
+  public Object getValueForProperty(Object instance, String propertyName) throws ODataAnnotationException {
+    if (instance == null) {
       return null;
     }
     
+    Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+    if(field == null) {
+      throw new ODataAnnotationException("No field for property '" + propertyName 
+              + "' found at class '" + instance.getClass() + "'.");
+    }
+    return getFieldValue(instance, field);
+  }
+
+  public void setValueForProperty(Object instance, String propertyName, Object propertyValue) {
+    if (instance != null) {
+      Field field = getFieldForPropertyName(instance, propertyName, instance.getClass(), true);
+      if(field != null) {
+        setFieldValue(instance, field, propertyValue);
+      }
+    }
+  }
+
+//  private Object getValueForPropertyName(Object instance, String propertyName, 
+//      Class<?> resultClass, boolean inherited) {
+//    if (instance == null) {
+//      return null;
+//    }
+//
+//    Field[] fields = resultClass.getDeclaredFields();
+//    for (Field field : fields) {
+//      EdmProperty property = field.getAnnotation(EdmProperty.class);
+//      if (property != null) {
+//        if(property.name().equals(propertyName)) {
+//          return getFieldValue(instance, field);
+//        } else if(field.getName().equals(propertyName)) {
+//          return getFieldValue(instance, field);
+//        }
+//      }
+//    }
+//
+//    Class<?> superClass = resultClass.getSuperclass();
+//    if (inherited && superClass != Object.class) {
+//      return getValueForPropertyName(instance, propertyName, superClass, true);
+//    }
+//
+//    return null;
+//  }
+
+
+  private Field getFieldForPropertyName(Object instance, String propertyName, 
+      Class<?> resultClass, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
     Field[] fields = resultClass.getDeclaredFields();
     for (Field field : fields) {
-      if(field.getAnnotation(annotation) != null) {
-        try {
-          boolean access = field.isAccessible();
-          field.setAccessible(true);
-          Object value = field.get(result);
-          field.setAccessible(access);
-          return value;
-        } catch (IllegalArgumentException ex) { // should never happen
-          throw new ODataRuntimeException(ex);
-        } catch (IllegalAccessException ex) { // should never happen
-          throw new ODataRuntimeException(ex);
+      EdmProperty property = field.getAnnotation(EdmProperty.class);
+      if (property != null) {
+        if(property.name().isEmpty() && getCanonicalName(field).equals(propertyName)) {
+          return field;
+        } else if(property.name().equals(propertyName)) {
+          return field;
         }
       }
     }
 
-    Class<?> superClass = result.getClass().getSuperclass();
-    if(inherited && superClass != Object.class) {
-      return getValueForField(result, superClass, annotation, true);
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      return getFieldForPropertyName(instance, propertyName, superClass, true);
     }
+
+    return null;
+  }
+
+  
+  public Object getValueForField(Object instance, String fieldName, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getValueForField(instance, fieldName, instance.getClass(), annotation, true);
+  }
+
+  public Object getValueForField(Object instance, Class<? extends Annotation> annotation) {
+    if (instance == null) {
+      return null;
+    }
+    return getValueForField(instance, instance.getClass(), annotation, true);
+  }
+
+  private Object getValueForField(Object instance, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    return getValueForField(instance, null, resultClass, annotation, inherited);
+  }
+
+  public Map<String, Object> getValueForAnnotatedFields(Object instance,
+          Class<? extends Annotation> annotation) {
+    return getValueForAnnotatedFields(instance, instance.getClass(), annotation, true);
+  }
     
+  private Map<String, Object> getValueForAnnotatedFields(Object instance, Class<?> resultClass,
+    Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    Map<String, Object> fieldName2Value = new HashMap<String, Object>();
+    
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null) {
+        Object value = getFieldValue(instance, field);
+        fieldName2Value.put(field.getName(), value);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      Map<String, Object> tmp = getValueForAnnotatedFields(instance, superClass, annotation, true);
+      fieldName2Value.putAll(tmp);
+    }
+
+    return fieldName2Value;
+  }
+
+  public void setValuesToAnnotatedFields(Map<String, Object> fieldName2Value, Object instance, 
+          Class<? extends Annotation> annotation) {
+    List<Field> fields = getAnnotatedFields(instance, instance.getClass(), annotation, true);
+    
+    // XXX: refactore
+    for (Field field : fields) {
+      final String canonicalName = getCanonicalName(field);
+      if(fieldName2Value.containsKey(canonicalName)) {
+        Object value = fieldName2Value.get(canonicalName);
+        setFieldValue(instance, field, value);
+      }
+    }
+  }
+          
+  public List<Field> getAnnotatedFields(Object instance, Class<? extends Annotation> annotation) {
+    return getAnnotatedFields(instance, instance.getClass(), annotation, true);
+  } 
+  
+  /**
+   * 
+   * @param instance
+   * @param resultClass
+   * @param annotation
+   * @param inherited
+   * @return 
+   */
+  private List<Field> getAnnotatedFields(Object instance, Class<?> resultClass,
+    Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    List<Field> annotatedFields = new ArrayList<Field>();
+    
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null) {
+        annotatedFields.add(field);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      List<Field> tmp = getAnnotatedFields(instance, superClass, annotation, true);
+      annotatedFields.addAll(tmp);
+    }
+
+    return annotatedFields;
+  }
+
+  private Object getValueForField(Object instance, String fieldName, Class<?> resultClass,
+      Class<? extends Annotation> annotation, boolean inherited) {
+    if (instance == null) {
+      return null;
+    }
+
+    Field[] fields = resultClass.getDeclaredFields();
+    for (Field field : fields) {
+      if (field.getAnnotation(annotation) != null
+          && (fieldName == null || field.getName().equals(fieldName))) {
+        return getFieldValue(instance, field);
+      }
+    }
+
+    Class<?> superClass = resultClass.getSuperclass();
+    if (inherited && superClass != Object.class) {
+      return getValueForField(instance, fieldName, superClass, annotation, true);
+    }
+
     return null;
   }
 
+  private Object getFieldValue(Object instance, Field field) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      Object value = field.get(instance);
+      field.setAccessible(access);
+      return value;
+    } catch (IllegalArgumentException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    } catch (IllegalAccessException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
+  private void setFieldValue(Object instance, Field field, Object propertyValue) {
+    try {
+      boolean access = field.isAccessible();
+      field.setAccessible(true);
+      field.set(instance, propertyValue);
+      field.setAccessible(access);
+    } catch (IllegalArgumentException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    } catch (IllegalAccessException ex) { // should never happen
+      throw new ODataRuntimeException(ex);
+    }
+  }
+
+  
   public boolean isEdmAnnotated(Object object) {
-    if(object == null) {
+    if (object == null) {
       return false;
     }
     return isEdmAnnotated(object.getClass());
   }
-  
+
   public boolean isEdmAnnotated(Class<?> clazz) {
     if (clazz == null) {
       return false;
@@ -84,17 +297,17 @@ public class AnnotationHelper {
       return isEntity || isComplexEntity;
     }
   }
-  
+
   public String getCanonicalName(Field field) {
     return firstCharToUpperCase(field.getName());
   }
-  
+
   public String getCanonicalName(Class<?> clazz) {
     return firstCharToUpperCase(clazz.getSimpleName());
   }
-  
+
   private String firstCharToUpperCase(String content) {
-    if(content == null || content.isEmpty()) {
+    if (content == null || content.isEmpty()) {
       return content;
     }
     return content.substring(0, 1).toUpperCase(Locale.ENGLISH) + content.substring(1);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/3bebf610/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
index d06bd3f..23fc743 100644
--- a/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
+++ b/odata2-edm-annotation/edm-annotation-core/src/main/java/org/apache/olingo/odata2/core/annotation/processor/AnnotationProcessor.java
@@ -21,68 +21,60 @@ package org.apache.olingo.odata2.core.annotation.processor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
 import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
 import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceContent;
 import org.apache.olingo.odata2.api.annotation.edm.EdmMediaResourceMimeType;
 import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
 import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
 import org.apache.olingo.odata2.api.uri.KeyPredicate;
 import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
 import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
 import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityCreate;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDataSource;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityDelete;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntitySetRead;
-import org.apache.olingo.odata2.api.annotation.edm.ds.EntityUpdate;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+import org.apache.olingo.odata2.core.annotation.ds.DataSourceHolder;
 import org.apache.olingo.odata2.core.annotation.edm.AnnotationHelper;
 import org.apache.olingo.odata2.core.annotation.edm.ClassHelper;
 import org.apache.olingo.odata2.core.annotation.processor.json.EdmAnnotationSerializer;
 import org.apache.olingo.odata2.core.annotation.processor.json.JsonConsumer;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
 /**
  *
  */
 public class AnnotationProcessor extends ODataSingleProcessor {
 
-  private static final Object[] EMPTY_ARRAY = new Object[0];
   private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
 
-  private final List<Class<?>> foundClasses;
-
   private final Map<String, DataSourceHolder> dataSources = new HashMap<String, DataSourceHolder>();
   private ODataContext odataContext;
 
   public AnnotationProcessor(ODataContext context, String packageToScan) {
     odataContext = context;
 
-    foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
+    List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
       @Override
       public boolean isClassValid(Class<?> c) {
         return null != c.getAnnotation(EntityDataSource.class);
       }
     });
 
-    init();
+    init(foundClasses);
   }
 
-  private void init() {
+  private void init(List<Class<?>> foundClasses) {
     for (Class<?> clz : foundClasses) {
       DataSourceHolder dhs = new DataSourceHolder(clz);
       dataSources.put(dhs.getEntityName(), dhs);
@@ -196,7 +188,7 @@ public class AnnotationProcessor extends ODataSingleProcessor {
           throws ODataException {
     try {
       Object instance = dataSource.createEntityInstance();
-      Map<String, FieldHolder> propName2Field = extractPropertyFields(dataSource.entityTypeClass);
+      Map<String, FieldHolder> propName2Field = extractPropertyFields(dataSource.getEntityTypeClass());
       Map<String, String> contentAsMap = JsonConsumer.readContent(content);
       Set<Map.Entry<String, String>> contentEntries = contentAsMap.entrySet();
       for (Map.Entry<String, String> entry : contentEntries) {
@@ -314,157 +306,4 @@ public class AnnotationProcessor extends ODataSingleProcessor {
       return "FieldHolder{" + "propertyName=" + propertyName + ", propertyField=" + propertyField + '}';
     }
   }
-
-  /**
-   *
-   */
-  static final class DataSourceHolder {
-
-    private final String name;
-    private final Object dataSourceInstance;
-    private final Class<?> entityTypeClass;
-    private Method readMethod;
-    private Method createMethod;
-    private Method updateMethod;
-    private Method deleteMethod;
-    private Method setReadMethod;
-
-    public DataSourceHolder(Class<?> clz) {
-      EntityDataSource eds = clz.getAnnotation(EntityDataSource.class);
-      entityTypeClass = eds.entityType();
-      EdmEntityType entityType = entityTypeClass.getAnnotation(EdmEntityType.class);
-      if (entityType == null) {
-        throw new IllegalArgumentException("Missing EdmEntityType Annotation at class " + clz);
-      }
-
-      if (entityType.name().isEmpty()) {
-        name = ANNOTATION_HELPER.getCanonicalName(entityTypeClass);
-      } else {
-        name = entityType.name();
-      }
-      dataSourceInstance = createInstance(clz);
-      initMethods(clz);
-    }
-
-    private void initMethods(Class<?> clz) throws IllegalArgumentException, SecurityException {
-      Method[] methods = clz.getDeclaredMethods();
-      for (Method method : methods) {
-        EntityRead ec = method.getAnnotation(EntityRead.class);
-        if (ec != null) {
-          readMethod = method;
-        }
-        EntityCreate ep = method.getAnnotation(EntityCreate.class);
-        if (ep != null) {
-          createMethod = method;
-        }
-        EntityUpdate update = method.getAnnotation(EntityUpdate.class);
-        if (update != null) {
-          updateMethod = method;
-        }
-        EntityDelete delete = method.getAnnotation(EntityDelete.class);
-        if (delete != null) {
-          deleteMethod = method;
-        }
-        EntitySetRead readSet = method.getAnnotation(EntitySetRead.class);
-        if (readSet != null) {
-          setReadMethod = method;
-        }
-      }
-
-      validateMethods(clz);
-    }
-
-    private void validateMethods(Class<?> clz) throws IllegalArgumentException {
-      //
-      if (readMethod == null) {
-        throw new IllegalArgumentException("Missing " + EntityRead.class
-                + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-      }
-      if (updateMethod == null) {
-        throw new IllegalArgumentException("Missing " + EntityUpdate.class
-                + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-      }
-      if (createMethod == null) {
-        throw new IllegalArgumentException("Missing " + EntityCreate.class
-                + " annotation at " + EntityDataSource.class + " annotated class " + clz);
-      }
-    }
-
-    public Object readEntity(List<KeyPredicate> keys) {
-      Object[] parameterKeys = mapParameterKeys(readMethod, keys);
-      return invoke(readMethod, parameterKeys);
-    }
-
-    private Object[] mapParameterKeys(Method method, List<KeyPredicate> keys) throws IllegalStateException {
-      if(method == null) {
-        return EMPTY_ARRAY;
-      }
-      Class<?>[] pTypes = method.getParameterTypes();
-      if (pTypes.length != keys.size()) {
-        throw new IllegalStateException("Wrong amount of key properties. Expected read keys = "
-                + Arrays.toString(pTypes) + " given key predicates = " + keys);
-      }
-      Object[] parameterKeys = new Object[pTypes.length];
-      int i = 0;
-      for (KeyPredicate keyPredicate : keys) {
-        if (matches(pTypes[i], keyPredicate)) {
-          parameterKeys[i] = keyPredicate.getLiteral();
-        }
-        i++;
-      }
-      return parameterKeys;
-    }
-
-    public Object createEntity(Object key) {
-      return invoke(createMethod, new Object[]{key});
-    }
-
-    public Object updateEntity(Object key) {
-      return invoke(updateMethod, new Object[]{key});
-    }
-
-    public Object deleteEntity(List<KeyPredicate> keys) {
-      Object[] parameterKeys = mapParameterKeys(deleteMethod, keys);
-      return invoke(deleteMethod, parameterKeys);
-    }
-
-    public Object readEntitySet() {
-      return invoke(setReadMethod, new Object[0]);
-    }
-
-    private Object invoke(Method m, Object[] objs) {
-      try {
-        return m.invoke(dataSourceInstance, objs);
-      } catch (Exception ex) {
-        return null;
-      }
-    }
-
-    public Object createEntityInstance() {
-      return createInstance(this.entityTypeClass);
-    }
-
-    private static Object createInstance(Class<?> clz) {
-      try {
-        return clz.newInstance();
-      } catch (Exception ex) {
-        return null;
-      }
-    }
-
-    public String getEntityName() {
-      return this.name;
-    }
-
-    @Override
-    public String toString() {
-      return "DataSourceHolder{" + "name=" + name + ", dataSourceInstance=" + dataSourceInstance + 
-              ", entityTypeClass=" + entityTypeClass + ", consumerMethod=" + readMethod + 
-              ", createMethod=" + createMethod + ", updateMethod=" + updateMethod + '}';
-    }
-
-    private boolean matches(Class<?> aClass, KeyPredicate type) {
-      return true;
-    }
-  }
 }