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;
- }
- }
}