[OLINGO-129] Merge with master branch
diff --git a/.gitignore b/.gitignore
index e000e0d..fced0b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.idea
.pmd
.project
.classpath
@@ -9,3 +10,4 @@
.DS_Store
nb-configuration.xml
context.xml
+glassfish-web.xml
diff --git a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/annotation/processor/api/AnnotationServiceFactory.java b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/annotation/processor/api/AnnotationServiceFactory.java
index 92f47e6..7a65dd1 100644
--- a/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/annotation/processor/api/AnnotationServiceFactory.java
+++ b/odata2-annotation-processor/annotation-processor-api/src/main/java/org/apache/olingo/odata2/annotation/processor/api/AnnotationServiceFactory.java
@@ -81,7 +81,6 @@
* <code>org.apache.olingo.olingo-odata2-api-annotation</code> module
* (see package <code>org.apache.olingo.odata2.api.annotation.edm</code>) to define the model and access the data.
*
- * @param modelPackage classes (which are annotated) which will be used for EDM definition and data access.
* @return service an {@link ODataService} based on on an EDM and Processor which are using annotations
* for model definition and data access.
* @throws ODataException if an error during initialization occurs
@@ -108,7 +107,6 @@
* <code>org.apache.olingo.olingo-odata2-api-annotation</code> module
* (see package <code>org.apache.olingo.odata2.api.annotation.edm</code>) to define the model and access the data.
*
- * @param modelPackage classes (which are annotated) which will be used for EDM definition and data access.
* @return service an {@link ODataService} based on on an EDM and Processor which are using annotations
* for model definition and data access.
* @throws ODataException if an error during initialization occurs
diff --git a/odata2-annotation-processor/annotation-processor-core/pom.xml b/odata2-annotation-processor/annotation-processor-core/pom.xml
index 4804851..795a283 100644
--- a/odata2-annotation-processor/annotation-processor-core/pom.xml
+++ b/odata2-annotation-processor/annotation-processor-core/pom.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
- license agreements. See the NOTICE file distributed with this work for additional
- information regarding copyright ownership. The ASF licenses this file to
- you 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. -->
+license agreements. See the NOTICE file distributed with this work for additional
+information regarding copyright ownership. The ASF licenses this file to
+you 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>olingo-odata2-annotation-processor-core</artifactId>
@@ -93,5 +93,10 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>javax.persistence</artifactId>
+ <version>2.1.0</version>
+ </dependency>
</dependencies>
</project>
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationInMemoryDs.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationDataSource.java
similarity index 90%
rename from odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationInMemoryDs.java
rename to odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationDataSource.java
index 74b8d1e..eb22f81 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationInMemoryDs.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationDataSource.java
@@ -22,12 +22,12 @@
import java.util.List;
import java.util.Map;
-import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStore.DataStoreException;
import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper;
import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper.AnnotatedNavInfo;
import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper.ODataAnnotationException;
import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationRuntimeException;
import org.apache.olingo.odata2.annotation.processor.core.util.ClassHelper;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
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.EdmNavigationProperty;
@@ -40,28 +40,35 @@
import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-public class AnnotationInMemoryDs implements DataSource {
+public class AnnotationDataSource implements DataSource {
private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
- private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
- private final boolean persistInMemory;
+ private static final String DEFAULT_PERSISTENCE = Boolean.TRUE.toString();
- public AnnotationInMemoryDs(final Collection<Class<?>> annotatedClasses) throws ODataException {
- this(annotatedClasses, true);
+ private final Map<String, DataStore<Object>> dataStores = new HashMap<String, DataStore<Object>>();
+ private final DataStoreFactory dataStoreFactory;
+
+ public AnnotationDataSource(final Collection<Class<?>> annotatedClasses) throws ODataException {
+ this(annotatedClasses, new DualDataStoreFactory());
+ dataStoreFactory.setDefaultProperty(DataStoreFactory.KEEP_PERSISTENT, DEFAULT_PERSISTENCE);
}
- public AnnotationInMemoryDs(final Collection<Class<?>> annotatedClasses, final boolean persistInMemory)
+ public AnnotationDataSource(final Collection<Class<?>> annotatedClasses, final DataStoreFactory dataStoreFactory)
throws ODataException {
- this.persistInMemory = persistInMemory;
+ this.dataStoreFactory = dataStoreFactory;
+
init(annotatedClasses);
}
- public AnnotationInMemoryDs(final String packageToScan) throws ODataException {
- this(packageToScan, true);
+ public AnnotationDataSource(final String packageToScan) throws ODataException {
+ this(packageToScan, new DualDataStoreFactory());
+ dataStoreFactory.setDefaultProperty(DataStoreFactory.KEEP_PERSISTENT, DEFAULT_PERSISTENCE);
}
- public AnnotationInMemoryDs(final String packageToScan, final boolean persistInMemory) throws ODataException {
- this.persistInMemory = persistInMemory;
+ public AnnotationDataSource(final String packageToScan, final DataStoreFactory dataStoreFactory)
+ throws ODataException {
+ this.dataStoreFactory = dataStoreFactory;
+
List<Class<?>> foundClasses = ClassHelper.loadClasses(packageToScan, new ClassHelper.ClassValidator() {
@Override
public boolean isClassValid(final Class<?> c) {
@@ -77,15 +84,15 @@
try {
for (Class<?> clz : annotatedClasses) {
String entitySetName = ANNOTATION_HELPER.extractEntitySetName(clz);
- if (entitySetName != null) {
- DataStore<Object> dhs = (DataStore<Object>) DataStore.createInMemory(clz, persistInMemory);
+ if(entitySetName != null) {
+ DataStore<Object> dhs = (DataStore<Object>) dataStoreFactory.createDataStore(clz);
dataStores.put(entitySetName, dhs);
} else if (!ANNOTATION_HELPER.isEdmAnnotated(clz)) {
throw new ODataException("Found not annotated class during DataStore initilization of type: "
+ clz.getName());
}
}
- } catch (DataStore.DataStoreException e) {
+ } catch (DataStoreException e) {
throw new ODataException("Error in DataStore initilization with message: " + e.getMessage(), e);
}
}
@@ -155,7 +162,7 @@
+ "', targetStore='" + targetStore + "').");
}
- List<Object> resultData = readResultData(targetStore, sourceData, sourceField);
+ List<Object> resultData = readResultData(targetStore, sourceData, sourceField, navInfo);
return extractResultData(targetStore, targetKeys, navInfo, resultData);
}
@@ -168,20 +175,24 @@
* @return
* @throws DataStoreException
*/
- private List<Object> readResultData(final DataStore<?> targetStore, final Object sourceData, final Field sourceField)
+ private List<Object> readResultData(final DataStore<?> targetStore, final Object sourceData,
+ final Field sourceField, final AnnotatedNavInfo navInfo)
throws DataStoreException {
Object navigationInstance = getValue(sourceField, sourceData);
if (navigationInstance == null) {
return Collections.emptyList();
}
-
+
List<Object> resultData = new ArrayList<Object>();
for (Object targetInstance : targetStore.read()) {
if (navigationInstance instanceof Collection) {
- for (Object object : (Collection<?>) navigationInstance) {
- if (targetStore.isKeyEqualChecked(targetInstance, object)) {
- resultData.add(targetInstance);
- }
+ Map<String, Object> keyName2Value =
+ ANNOTATION_HELPER.getValueForAnnotatedFields(sourceData, EdmKey.class);
+ Field toField = navInfo.getToField();
+ Object backInstance = ClassHelper.getFieldValue(targetInstance, toField);
+ boolean keyMatch = ANNOTATION_HELPER.keyMatch(backInstance, keyName2Value);
+ if(keyMatch) {
+ resultData.add(targetInstance);
}
} else if (targetStore.isKeyEqualChecked(targetInstance, navigationInstance)) {
resultData.add(targetInstance);
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStore.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStore.java
index c03a557..ff47232 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStore.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStore.java
@@ -1,292 +1,66 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- ******************************************************************************/
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * 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.apache.olingo.odata2.annotation.processor.core.datasource;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper;
-import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationRuntimeException;
-import org.apache.olingo.odata2.annotation.processor.core.util.ClassHelper;
-import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
-import org.apache.olingo.odata2.api.exception.ODataApplicationException;
/**
*
+ * @author michael
*/
-public class DataStore<T> {
+public interface DataStore<T> {
- private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
- private final Map<KeyElement, T> dataStore;
- private final Class<T> dataTypeClass;
- private final KeyAccess keyAccess;
+ T create(final T object) throws DataStoreException;
- private static class InMemoryDataStore {
- private static final Map<Class<?>, DataStore<?>> c2ds = new HashMap<Class<?>, DataStore<?>>();
+ T createInstance();
- @SuppressWarnings("unchecked")
- static synchronized DataStore<?> getInstance(final Class<?> clz, final boolean createNewInstance)
- throws DataStoreException {
- DataStore<?> ds = c2ds.get(clz);
- if (createNewInstance || ds == null) {
- ds = new DataStore<Object>((Class<Object>) clz);
- c2ds.put(clz, ds);
- }
- return ds;
- }
- }
+ T delete(final T object);
- @SuppressWarnings("unchecked")
- public static <T> DataStore<T> createInMemory(final Class<T> clazz) throws DataStoreException {
- return (DataStore<T>) InMemoryDataStore.getInstance(clazz, true);
- }
+ Class<T> getDataTypeClass();
- @SuppressWarnings("unchecked")
- public static <T> DataStore<T> createInMemory(final Class<T> clazz, final boolean keepExisting)
- throws DataStoreException {
- return (DataStore<T>) InMemoryDataStore.getInstance(clazz, !keepExisting);
- }
-
- private DataStore(final Map<KeyElement, T> wrapStore, final Class<T> clz) throws DataStoreException {
- dataStore = Collections.synchronizedMap(wrapStore);
- dataTypeClass = clz;
- keyAccess = new KeyAccess(clz);
- }
-
- private DataStore(final Class<T> clz) throws DataStoreException {
- this(new HashMap<KeyElement, T>(), clz);
- }
-
- public Class<T> getDataTypeClass() {
- return dataTypeClass;
- }
-
- public String getEntityTypeName() {
- return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
- }
-
- public T createInstance() {
- try {
- return dataTypeClass.newInstance();
- } catch (InstantiationException e) {
- throw new AnnotationRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
- } catch (IllegalAccessException e) {
- throw new AnnotationRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
- }
- }
-
- public T read(final T obj) {
- KeyElement objKeys = getKeys(obj);
- return dataStore.get(objKeys);
- }
-
- public Collection<T> read() {
- return Collections.unmodifiableCollection(dataStore.values());
- }
-
- public T create(final T object) throws DataStoreException {
- KeyElement keyElement = getKeys(object);
- return create(object, keyElement);
- }
-
- private T create(final T object, final KeyElement keyElement) throws DataStoreException {
- synchronized (dataStore) {
- if (keyElement.keyValuesMissing() || dataStore.containsKey(keyElement)) {
- KeyElement newKey = createSetAndGetKeys(object);
- return this.create(object, newKey);
- }
- dataStore.put(keyElement, object);
- }
- return object;
- }
-
- public T update(final T object) {
- KeyElement keyElement = getKeys(object);
- synchronized (dataStore) {
- dataStore.remove(keyElement);
- dataStore.put(keyElement, object);
- }
- return object;
- }
-
- public T delete(final T object) {
- KeyElement keyElement = getKeys(object);
- synchronized (dataStore) {
- return dataStore.remove(keyElement);
- }
- }
+ String getEntityTypeName();
/**
* Are the key values equal for both instances.
* If all compared key values are <code>null</code> this also means equal.
- *
+ *
* @param first first instance to check for key equal
* @param second second instance to check for key equal
* @return <code>true</code> if object instance have equal keys set.
*/
- public boolean isKeyEqual(final T first, final T second) {
- KeyElement firstKeys = getKeys(first);
- KeyElement secondKeys = getKeys(second);
-
- return firstKeys.equals(secondKeys);
- }
+// boolean isKeyEqual(final T first, final T second);
/**
* Are the key values equal for both instances.
* If all compared key values are <code>null</code> this also means equal.
* Before object (keys) are compared it is validated that both object instance are NOT null
- * and that both are from the same class as this {@link DataStore} (see {@link #dataTypeClass}).
- * For the equal check on {@link #dataTypeClass} instances without validation see {@link #isKeyEqual(Object, Object)}.
- *
+ * and that both are from the same class as this {@link DataStore} (see {@link #getDataTypeClass()}).
+ * For the equal check on {@link #getDataTypeClass()} instances without validation see
+ * {@link #isKeyEqual(Object, Object)}.
+ *
* @param first first instance to check for key equal
* @param second second instance to check for key equal
* @return <code>true</code> if object instance have equal keys set.
*/
- @SuppressWarnings("unchecked")
- public boolean isKeyEqualChecked(final Object first, final Object second) throws DataStoreException {
- if (first == null || second == null) {
- throw new DataStoreException("Tried to compare null values which is not allowed.");
- } else if (first.getClass() != dataTypeClass) {
- throw new DataStoreException("First value is no instance from required class '" + dataTypeClass + "'.");
- } else if (second.getClass() != dataTypeClass) {
- throw new DataStoreException("Second value is no instance from required class '" + dataTypeClass + "'.");
- }
+ boolean isKeyEqualChecked(Object first, Object second) throws DataStoreException;
- return isKeyEqual((T) first, (T) second);
- }
+ T read(final T obj);
- private class KeyElement {
- private int cachedHashCode = 42;
- private final List<Object> keyValues;
+ Collection<T> read();
- public KeyElement(final int size) {
- keyValues = new ArrayList<Object>(size);
- }
-
- private void addValue(final Object keyValue) {
- keyValues.add(keyValue);
- cachedHashCode = 89 * cachedHashCode + (keyValue != null ? keyValue.hashCode() : 0);
- }
-
- boolean keyValuesMissing() {
- return keyValues.contains(null);
- }
-
- @Override
- public int hashCode() {
- return cachedHashCode;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- @SuppressWarnings("unchecked")
- final KeyElement other = (KeyElement) obj;
- if (this.keyValues != other.keyValues && (this.keyValues == null || !this.keyValues.equals(other.keyValues))) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "KeyElement{" + "cachedHashCode=" + cachedHashCode + ", keyValues=" + keyValues + '}';
- }
- }
-
- private class KeyAccess {
- final List<Field> keyFields;
- final AtomicInteger idCounter = new AtomicInteger(1);
-
- KeyAccess(final Class<?> clazz) throws DataStoreException {
- keyFields = ANNOTATION_HELPER.getAnnotatedFields(clazz, EdmKey.class);
- if (keyFields.isEmpty()) {
- throw new DataStoreException("No EdmKey annotated fields found for class " + clazz);
- }
- }
-
- KeyElement getKeyValues(final T object) {
- KeyElement keyElement = new KeyElement(keyFields.size());
- for (Field field : keyFields) {
- Object keyValue = ClassHelper.getFieldValue(object, field);
- keyElement.addValue(keyValue);
- }
-
- return keyElement;
- }
-
- KeyElement createSetAndGetKeys(final T object) throws DataStoreException {
- KeyElement keyElement = new KeyElement(keyFields.size());
- for (Field field : keyFields) {
- Object key = createKey(field);
- ClassHelper.setFieldValue(object, field, key);
- keyElement.addValue(key);
- }
-
- return keyElement;
- }
-
- private Object createKey(final Field field) {
- Class<?> type = field.getType();
-
- if (type == String.class) {
- return String.valueOf(idCounter.getAndIncrement());
- } else if (type == Integer.class || type == int.class) {
- return Integer.valueOf(idCounter.getAndIncrement());
- } else if (type == Long.class || type == long.class) {
- return Long.valueOf(idCounter.getAndIncrement());
- }
-
- throw new UnsupportedOperationException("Automated key generation for type '" + type
- + "' is not supported (caused on field '" + field + "').");
- }
- }
-
- private KeyElement getKeys(final T object) {
- return keyAccess.getKeyValues(object);
- }
-
- private KeyElement createSetAndGetKeys(final T object) throws DataStoreException {
- return keyAccess.createSetAndGetKeys(object);
- }
-
- public static class DataStoreException extends ODataApplicationException {
- private static final long serialVersionUID = 42L;
-
- public DataStoreException(final String message) {
- this(message, null);
- }
-
- public DataStoreException(final String message, final Throwable cause) {
- super(message, Locale.ENGLISH, cause);
- }
- }
+ T update(final T object);
}
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStoreException.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStoreException.java
new file mode 100644
index 0000000..95299f4
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStoreException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * 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.apache.olingo.odata2.annotation.processor.core.datasource;
+
+import java.util.Locale;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+
+/**
+ *
+ */
+public class DataStoreException extends ODataApplicationException {
+
+ private static final long serialVersionUID = 42L;
+
+ public DataStoreException(final String message) {
+ this(message, null);
+ }
+
+ public DataStoreException(final String message, final Throwable cause) {
+ super(message, Locale.ENGLISH, cause);
+ }
+}
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStoreFactory.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStoreFactory.java
new file mode 100644
index 0000000..9d0b97b
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DataStoreFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * 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.apache.olingo.odata2.annotation.processor.core.datasource;
+
+import java.util.Map;
+
+/**
+ *
+ */
+public interface DataStoreFactory {
+ static final String KEEP_PERSISTENT = "KEEP_PERSISTENT";
+
+ void setDefaultProperty(String name, String value);
+ DataStore<?> createDataStore(Class<?> clz) throws DataStoreException;
+ DataStore<?> createDataStore(Class<?> clz, Map<String, String> properties) throws DataStoreException;
+}
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DualDataStoreFactory.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DualDataStoreFactory.java
new file mode 100644
index 0000000..714b629
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/DualDataStoreFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * 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.apache.olingo.odata2.annotation.processor.core.datasource;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.Entity;
+
+/**
+ *
+ */
+public class DualDataStoreFactory implements DataStoreFactory {
+
+ private final Map<String, String> properties = new HashMap<String, String>();
+
+ @Override
+ public DataStore<?> createDataStore(Class<?> clz) throws DataStoreException {
+ return createDataStore(clz, properties);
+ }
+
+ @Override
+ public DataStore<?> createDataStore(Class<?> clz, Map<String, String> properties) throws DataStoreException {
+ boolean keepPersistent = Boolean.parseBoolean(properties.get(KEEP_PERSISTENT));
+ return createInstance(clz, keepPersistent);
+ }
+
+ @Override
+ public void setDefaultProperty(String name, String value) {
+ properties.put(name, value);
+ }
+
+ public DataStore<?> createInstance(Class<?> clz, boolean keepPersistent) throws DataStoreException {
+ if(isJpaAnnotated(clz)) {
+ String persistenceName = System.getProperty(JpaAnnotationDataStore.PERSISTENCE_NAME);
+ if(persistenceName == null) {
+ return JpaAnnotationDataStore.createInstance(clz);
+ }
+ return JpaAnnotationDataStore.createInstance(clz, persistenceName);
+ }
+ return InMemoryDataStore.createInMemory(clz, keepPersistent);
+ }
+
+ private boolean isJpaAnnotated(Class<?> clz) {
+ return clz.getAnnotation(Entity.class) != null;
+ }
+}
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/InMemoryDataStore.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/InMemoryDataStore.java
new file mode 100644
index 0000000..d85e06b
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/InMemoryDataStore.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.olingo.odata2.annotation.processor.core.datasource;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper;
+import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationRuntimeException;
+import org.apache.olingo.odata2.annotation.processor.core.util.ClassHelper;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+
+/**
+ *
+ */
+public class InMemoryDataStore<T> implements DataStore<T> {
+
+ private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+ private final Map<KeyElement, T> dataStore;
+ private final Class<T> dataTypeClass;
+ private final KeyAccess keyAccess;
+
+ private static class InMemoryDataStoreHolder {
+ private static final Map<Class<?>, InMemoryDataStore<?>> c2ds = new HashMap<Class<?>, InMemoryDataStore<?>>();
+
+ @SuppressWarnings("unchecked")
+ static synchronized InMemoryDataStore<?> getInstance(final Class<?> clz, final boolean createNewInstance)
+ throws DataStoreException {
+ InMemoryDataStore<?> ds = c2ds.get(clz);
+ if (createNewInstance || ds == null) {
+ ds = new InMemoryDataStore<Object>((Class<Object>) clz);
+ c2ds.put(clz, ds);
+ }
+ return ds;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> InMemoryDataStore<T> createInMemory(final Class<T> clazz) throws DataStoreException {
+ return (InMemoryDataStore<T>) InMemoryDataStoreHolder.getInstance(clazz, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> InMemoryDataStore<T> createInMemory(final Class<T> clazz, final boolean keepExisting)
+ throws DataStoreException {
+ return (InMemoryDataStore<T>) InMemoryDataStoreHolder.getInstance(clazz, !keepExisting);
+ }
+
+ private InMemoryDataStore(final Map<KeyElement, T> wrapStore, final Class<T> clz) throws DataStoreException {
+ dataStore = Collections.synchronizedMap(wrapStore);
+ dataTypeClass = clz;
+ keyAccess = new KeyAccess(clz);
+ }
+
+ private InMemoryDataStore(final Class<T> clz) throws DataStoreException {
+ this(new HashMap<KeyElement, T>(), clz);
+ }
+
+ @Override
+ public Class<T> getDataTypeClass() {
+ return dataTypeClass;
+ }
+
+ @Override
+ public String getEntityTypeName() {
+ return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
+ }
+
+ @Override
+ public T createInstance() {
+ try {
+ return dataTypeClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new AnnotationRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+ } catch (IllegalAccessException e) {
+ throw new AnnotationRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+ }
+ }
+
+ @Override
+ public T read(final T obj) {
+ KeyElement objKeys = getKeys(obj);
+ return dataStore.get(objKeys);
+ }
+
+ @Override
+ public Collection<T> read() {
+ return Collections.unmodifiableCollection(dataStore.values());
+ }
+
+ @Override
+ public T create(final T object) throws DataStoreException {
+ KeyElement keyElement = getKeys(object);
+ return create(object, keyElement);
+ }
+
+ private T create(final T object, final KeyElement keyElement) throws DataStoreException {
+ synchronized (dataStore) {
+ if (keyElement.keyValuesMissing() || dataStore.containsKey(keyElement)) {
+ KeyElement newKey = createSetAndGetKeys(object);
+ return this.create(object, newKey);
+ }
+ dataStore.put(keyElement, object);
+ }
+ return object;
+ }
+
+ @Override
+ public T update(final T object) {
+ KeyElement keyElement = getKeys(object);
+ synchronized (dataStore) {
+ dataStore.remove(keyElement);
+ dataStore.put(keyElement, object);
+ }
+ return object;
+ }
+
+ @Override
+ public T delete(final T object) {
+ KeyElement keyElement = getKeys(object);
+ synchronized (dataStore) {
+ return dataStore.remove(keyElement);
+ }
+ }
+
+ /**
+ * Are the key values equal for both instances.
+ * If all compared key values are <code>null</code> this also means equal.
+ *
+ * @param first first instance to check for key equal
+ * @param second second instance to check for key equal
+ * @return <code>true</code> if object instance have equal keys set.
+ */
+ private boolean isKeyEqual(final T first, final T second) {
+ KeyElement firstKeys = getKeys(first);
+ KeyElement secondKeys = getKeys(second);
+
+ return firstKeys.equals(secondKeys);
+ }
+
+ /**
+ * Are the key values equal for both instances.
+ * If all compared key values are <code>null</code> this also means equal.
+ * Before object (keys) are compared it is validated that both object instance are NOT null
+ * and that both are from the same class as this {@link InMemoryDataStore} (see {@link #dataTypeClass}).
+ * For the equal check on {@link #dataTypeClass} instances without validation see
+ * {@link #isKeyEqual(Object, Object)}.
+ *
+ * @param first first instance to check for key equal
+ * @param second second instance to check for key equal
+ * @return <code>true</code> if object instance have equal keys set.
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean isKeyEqualChecked(Object first, Object second) throws DataStoreException {
+ if(first == null || second == null) {
+ throw new DataStoreException("Tried to compare null values which is not allowed.");
+ } else if(first.getClass() != dataTypeClass) {
+ throw new DataStoreException("First value is no instance from required class '" + dataTypeClass + "'.");
+ } else if(second.getClass() != dataTypeClass) {
+ throw new DataStoreException("Second value is no instance from required class '" + dataTypeClass + "'.");
+ }
+
+ return isKeyEqual((T) first, (T) second);
+ }
+
+
+ private class KeyElement {
+ private int cachedHashCode = 42;
+ private final List<Object> keyValues;
+
+ public KeyElement(final int size) {
+ keyValues = new ArrayList<Object>(size);
+ }
+
+ private void addValue(final Object keyValue) {
+ keyValues.add(keyValue);
+ cachedHashCode = 89 * cachedHashCode + (keyValue != null ? keyValue.hashCode() : 0);
+ }
+
+ boolean keyValuesMissing() {
+ return keyValues.contains(null);
+ }
+
+ @Override
+ public int hashCode() {
+ return cachedHashCode;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ final KeyElement other = (KeyElement) obj;
+ if (this.keyValues != other.keyValues && (this.keyValues == null || !this.keyValues.equals(other.keyValues))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "KeyElement{" + "cachedHashCode=" + cachedHashCode + ", keyValues=" + keyValues + '}';
+ }
+ }
+
+ private class KeyAccess {
+ final List<Field> keyFields;
+ final AtomicInteger idCounter = new AtomicInteger(1);
+
+ KeyAccess(final Class<?> clazz) throws DataStoreException {
+ keyFields = ANNOTATION_HELPER.getAnnotatedFields(clazz, EdmKey.class);
+ if (keyFields.isEmpty()) {
+ throw new DataStoreException("No EdmKey annotated fields found for class " + clazz);
+ }
+ }
+
+ KeyElement getKeyValues(final T object) {
+ KeyElement keyElement = new KeyElement(keyFields.size());
+ for (Field field : keyFields) {
+ Object keyValue = ClassHelper.getFieldValue(object, field);
+ keyElement.addValue(keyValue);
+ }
+
+ return keyElement;
+ }
+
+ KeyElement createSetAndGetKeys(final T object) throws DataStoreException {
+ KeyElement keyElement = new KeyElement(keyFields.size());
+ for (Field field : keyFields) {
+ Object key = createKey(field);
+ ClassHelper.setFieldValue(object, field, key);
+ keyElement.addValue(key);
+ }
+
+ return keyElement;
+ }
+
+ private Object createKey(final Field field) {
+ Class<?> type = field.getType();
+
+ if (type == String.class) {
+ return String.valueOf(idCounter.getAndIncrement());
+ } else if (type == Integer.class || type == int.class) {
+ return Integer.valueOf(idCounter.getAndIncrement());
+ } else if (type == Long.class || type == long.class) {
+ return Long.valueOf(idCounter.getAndIncrement());
+ }
+
+ throw new UnsupportedOperationException("Automated key generation for type '" + type
+ + "' is not supported (caused on field '" + field + "').");
+ }
+ }
+
+ private KeyElement getKeys(final T object) {
+ return keyAccess.getKeyValues(object);
+ }
+
+ private KeyElement createSetAndGetKeys(final T object) throws DataStoreException {
+ return keyAccess.createSetAndGetKeys(object);
+ }
+}
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/JpaAnnotationDataStore.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/JpaAnnotationDataStore.java
new file mode 100644
index 0000000..17e7755
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/datasource/JpaAnnotationDataStore.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * 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.apache.olingo.odata2.annotation.processor.core.datasource;
+
+import java.util.Collection;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationHelper;
+import org.apache.olingo.odata2.annotation.processor.core.util.AnnotationRuntimeException;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+
+/**
+ *
+ */
+public class JpaAnnotationDataStore<T> implements DataStore<T> {
+
+ public static final String DEFAULT_PERSISTENCE_NAME = "JpaAnnotationDataStorePersistence";
+ public static final String PERSISTENCE_NAME = "JpaAnnotationDataStorePersistenceNameSystemProperty";
+
+ private static final AnnotationHelper ANNOTATION_HELPER = new AnnotationHelper();
+
+ protected Class<T> dataTypeClass;
+ protected EntityManager entityManager;
+
+ public static DataStore<?> createInstance(Class<?> clz) {
+ return createInstance(clz, DEFAULT_PERSISTENCE_NAME);
+ }
+
+ public static DataStore<?> createInstance(Class<?> clz, String persistenceName) {
+ return new JpaAnnotationDataStore<Object>((Class<Object>) clz, persistenceName);
+ }
+
+ private JpaAnnotationDataStore(final Class<T> clz, String persistenceName) {
+ EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceName);
+ entityManager = emf.createEntityManager();
+ this.dataTypeClass = clz;
+ }
+
+ @Override
+ public Class<T> getDataTypeClass() {
+ return dataTypeClass;
+ }
+
+ @Override
+ public String getEntityTypeName() {
+ return ANNOTATION_HELPER.extractEntityTypeName(dataTypeClass);
+ }
+
+ @Override
+ public T createInstance() {
+ try {
+ return dataTypeClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new AnnotationRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+ } catch (IllegalAccessException e) {
+ throw new AnnotationRuntimeException("Unable to create instance of class '" + dataTypeClass + "'.", e);
+ }
+ }
+
+ @Override
+ public T create(T object) throws DataStoreException {
+ EntityTransaction t = this.entityManager.getTransaction();
+ try {
+ t.begin();
+ this.entityManager.persist(object);
+ this.entityManager.flush();
+ t.commit();
+ } catch(Exception e) {
+ if(t != null && t.isActive()) {
+ t.rollback();
+ }
+ }
+
+ return object;
+ }
+
+ @Override
+ public T delete(T object) {
+ EntityTransaction t = this.entityManager.getTransaction();
+ try {
+ t.begin();
+ object = this.entityManager.merge(object);
+ this.entityManager.remove(object);
+ this.entityManager.flush();
+ t.commit();
+
+ return object;
+ } catch(Exception e) {
+ if(t != null && t.isActive()) {
+ t.rollback();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isKeyEqualChecked(Object first, Object second) throws DataStoreException {
+ return ANNOTATION_HELPER.keyMatch(first, second);
+ }
+
+ @Override
+ public T read(T obj) {
+ Object key = ANNOTATION_HELPER.getValueForField(obj, EdmKey.class);
+ return this.entityManager.find(dataTypeClass, key);
+ }
+
+ @Override
+ public Collection<T> read() {
+ Query query = entityManager.createQuery("SELECT t FROM " + dataTypeClass.getSimpleName() + " t");
+ return query.getResultList();
+ }
+
+ @Override
+ public T update(T object) {
+ EntityTransaction t = this.entityManager.getTransaction();
+ try {
+ t.begin();
+ object = this.entityManager.merge(object);
+ this.entityManager.flush();
+ t.commit();
+
+ return object;
+ } catch(Exception e) {
+ if(t != null && t.isActive()) {
+ t.rollback();
+ }
+ }
+ return null;
+ }
+}
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProvider.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProvider.java
index 81546a7..21df18a 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProvider.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/edm/AnnotationEdmProvider.java
@@ -6,9 +6,9 @@
* to you 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
@@ -73,7 +73,7 @@
/**
* Provider for the entity data model used in the reference scenario
- *
+ *
*/
public class AnnotationEdmProvider extends EdmProvider {
diff --git a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/rt/AnnotationServiceFactoryImpl.java b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/rt/AnnotationServiceFactoryImpl.java
index ed99a4b..733d4d5 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/rt/AnnotationServiceFactoryImpl.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/main/java/org/apache/olingo/odata2/annotation/processor/core/rt/AnnotationServiceFactoryImpl.java
@@ -22,7 +22,7 @@
import org.apache.olingo.odata2.annotation.processor.api.AnnotationServiceFactory.AnnotationServiceFactoryInstance;
import org.apache.olingo.odata2.annotation.processor.core.ListsProcessor;
-import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationInMemoryDs;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationDataSource;
import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationValueAccess;
import org.apache.olingo.odata2.annotation.processor.core.edm.AnnotationEdmProvider;
import org.apache.olingo.odata2.api.ODataService;
@@ -40,7 +40,7 @@
@Override
public ODataService createAnnotationService(final String modelPackage) throws ODataException {
AnnotationEdmProvider edmProvider = new AnnotationEdmProvider(modelPackage);
- AnnotationInMemoryDs dataSource = new AnnotationInMemoryDs(modelPackage);
+ AnnotationDataSource dataSource = new AnnotationDataSource(modelPackage);
AnnotationValueAccess valueAccess = new AnnotationValueAccess();
// Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
@@ -54,7 +54,7 @@
@Override
public ODataService createAnnotationService(final Collection<Class<?>> annotatedClasses) throws ODataException {
AnnotationEdmProvider edmProvider = new AnnotationEdmProvider(annotatedClasses);
- AnnotationInMemoryDs dataSource = new AnnotationInMemoryDs(annotatedClasses);
+ AnnotationDataSource dataSource = new AnnotationDataSource(annotatedClasses);
AnnotationValueAccess valueAccess = new AnnotationValueAccess();
// Edm via Annotations and ListProcessor via AnnotationDS with AnnotationsValueAccess
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/ListsProcessorTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/ListsProcessorTest.java
index 89c83da..cc7cbe6 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/ListsProcessorTest.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/ListsProcessorTest.java
@@ -15,7 +15,7 @@
*/
package org.apache.olingo.odata2.annotation.processor.core;
-import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationInMemoryDs;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationDataSource;
import org.apache.olingo.odata2.annotation.processor.core.datasource.AnnotationValueAccess;
import org.apache.olingo.odata2.annotation.processor.core.datasource.DataSource;
import org.apache.olingo.odata2.annotation.processor.core.datasource.ValueAccess;
@@ -36,7 +36,7 @@
@Test
public void init() throws ODataException {
- DataSource dataSource = new AnnotationInMemoryDs(Building.class.getPackage().getName());
+ DataSource dataSource = new AnnotationDataSource(Building.class.getPackage().getName());
ValueAccess valueAccess = new AnnotationValueAccess();
ListsProcessor lp = new ListsProcessor(dataSource, valueAccess);
diff --git a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsDataSourceTest.java
similarity index 95%
rename from odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java
rename to odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsDataSourceTest.java
index 7b2ee4b..a1fb796 100644
--- a/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsInMemoryDsTest.java
+++ b/odata2-annotation-processor/annotation-processor-core/src/test/java/org/apache/olingo/odata2/annotation/processor/core/datasource/AnnotationsDataSourceTest.java
@@ -57,7 +57,7 @@
/**
*
*/
-public class AnnotationsInMemoryDsTest {
+public class AnnotationsDataSourceTest {
final static Set<Class<?>> ANNOTATED_MODEL_CLASSES = new HashSet<Class<?>>();
final static Set<Class<?>> ANNOTATED_ENTITY_SET_CLASSES = new HashSet<Class<?>>();
@@ -69,49 +69,51 @@
ANNOTATED_ENTITY_SET_CLASSES.add(Photo.class);
ANNOTATED_ENTITY_SET_CLASSES.add(Room.class);
ANNOTATED_ENTITY_SET_CLASSES.add(Team.class);
-
ANNOTATED_MODEL_CLASSES.addAll(ANNOTATED_ENTITY_SET_CLASSES);
ANNOTATED_MODEL_CLASSES.add(Location.class);
ANNOTATED_MODEL_CLASSES.add(City.class);
ANNOTATED_MODEL_CLASSES.add(RefBase.class);
}
- private final AnnotationInMemoryDs datasource;
+ private final AnnotationDataSource datasource;
private final AnnotationEdmProvider edmProvider;
private static final String DEFAULT_CONTAINER = ModelSharedConstants.CONTAINER_1;
+ private final DualDataStoreFactory dataStoreFactory;
- public AnnotationsInMemoryDsTest() throws ODataException {
- datasource = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
+ public AnnotationsDataSourceTest() throws ODataException {
+ dataStoreFactory = new DualDataStoreFactory();
+ dataStoreFactory.setDefaultProperty(DataStoreFactory.KEEP_PERSISTENT, Boolean.FALSE.toString());
+ datasource = new AnnotationDataSource(Building.class.getPackage().getName(), dataStoreFactory);
edmProvider = new AnnotationEdmProvider(Building.class.getPackage().getName());
}
@Test
public void initFromPackage() throws Exception {
- AnnotationInMemoryDs ds = new AnnotationInMemoryDs(Building.class.getPackage().getName(), false);
+ AnnotationDataSource ds = new AnnotationDataSource(Building.class.getPackage().getName());
Assert.assertNotNull(ds);
}
@Test(expected = IllegalArgumentException.class)
public void initFromNotExistingPackage() throws Exception {
- AnnotationInMemoryDs ds = new AnnotationInMemoryDs("does.not.exist", false);
+ AnnotationDataSource ds = new AnnotationDataSource("does.not.exist");
Assert.assertNotNull(ds);
}
@Test
public void initFromPackageWithoutAnnotatedClasses() throws Exception {
- AnnotationInMemoryDs ds = new AnnotationInMemoryDs(this.getClass().getPackage().getName(), false);
+ AnnotationDataSource ds = new AnnotationDataSource(this.getClass().getPackage().getName());
Assert.assertNotNull(ds);
}
@Test
public void initFromClassCollectionEntitySets() throws Exception {
- AnnotationInMemoryDs ds = new AnnotationInMemoryDs(ANNOTATED_ENTITY_SET_CLASSES, false);
+ AnnotationDataSource ds = new AnnotationDataSource(ANNOTATED_ENTITY_SET_CLASSES);
Assert.assertNotNull(ds);
}
@Test
public void initFromClassCollectionModel() throws Exception {
- AnnotationInMemoryDs ds = new AnnotationInMemoryDs(ANNOTATED_MODEL_CLASSES, false);
+ AnnotationDataSource ds = new AnnotationDataSource(ANNOTATED_MODEL_CLASSES);
Assert.assertNotNull(ds);
}
@@ -120,7 +122,7 @@
Set<Class<?>> annotatedClassesAndMore = new HashSet<Class<?>>(ANNOTATED_ENTITY_SET_CLASSES);
annotatedClassesAndMore.add(String.class);
annotatedClassesAndMore.add(Object.class);
- AnnotationInMemoryDs ds = new AnnotationInMemoryDs(annotatedClassesAndMore, false);
+ AnnotationDataSource ds = new AnnotationDataSource(annotatedClassesAndMore);
Assert.assertNotNull(ds);
}
@@ -165,7 +167,7 @@
public void multiThreadedSyncCreateReadTest() throws Exception {
Collection<Class<?>> ac = new ArrayList<Class<?>>();
ac.add(SimpleEntity.class);
- final AnnotationInMemoryDs localDs = new AnnotationInMemoryDs(SimpleEntity.class.getPackage().getName(), true);
+ final AnnotationDataSource localDs = new AnnotationDataSource(SimpleEntity.class.getPackage().getName());
final AnnotationEdmProvider localProvider = new AnnotationEdmProvider(ac);
final EdmEntitySet edmEntitySet = createMockedEdmEntitySet(localProvider, "SimpleEntitySet");
final CountDownLatch latch;
@@ -745,8 +747,8 @@
@Test
public void writeRelations() throws Exception {
- DataStore<Building> buildingStore = DataStore.createInMemory(Building.class, true);
- DataStore<Room> roomStore = DataStore.createInMemory(Room.class, true);
+ DataStore<Building> buildingStore = InMemoryDataStore.createInMemory(Building.class, true);
+ DataStore<Room> roomStore = InMemoryDataStore.createInMemory(Room.class, true);
EdmEntitySet buildingsEntitySet = createMockedEdmEntitySet("Buildings");
EdmEntitySet roomsEntitySet = createMockedEdmEntitySet("Rooms");
diff --git a/odata2-annotation-processor/annotation-processor-ref/pom.xml b/odata2-annotation-processor/annotation-processor-ref/pom.xml
index 7e04d76..b052ae6 100644
--- a/odata2-annotation-processor/annotation-processor-ref/pom.xml
+++ b/odata2-annotation-processor/annotation-processor-ref/pom.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
- license agreements. See the NOTICE file distributed with this work for additional
- information regarding copyright ownership. The ASF licenses this file to
- you 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. -->
+license agreements. See the NOTICE file distributed with this work for additional
+information regarding copyright ownership. The ASF licenses this file to
+you 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. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>olingo-odata2-annotation-processor-ref</artifactId>
@@ -68,6 +68,30 @@
<dependencies>
<dependency>
+ <!-- required because of auto detection of web facet 2.5 -->
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>javax.persistence</artifactId>
+ <version>2.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>1.8.0.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>eclipselink</artifactId>
+ <version>2.5.1</version>
+ </dependency>
+
+ <dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>olingo-odata2-api</artifactId>
<version>${project.version}</version>
diff --git a/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java b/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
index 9130a19..65f5585 100644
--- a/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
+++ b/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
@@ -15,18 +15,23 @@
package org.apache.olingo.odata2.annotation.processor.ref;
import java.util.Calendar;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.olingo.odata2.annotation.processor.api.AnnotationServiceFactory;
-import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStore;
-import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStore.DataStoreException;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.InMemoryDataStore;
+import org.apache.olingo.odata2.annotation.processor.core.datasource.DataStoreException;
import org.apache.olingo.odata2.annotation.processor.ref.model.Building;
+import org.apache.olingo.odata2.annotation.processor.ref.model.City;
import org.apache.olingo.odata2.annotation.processor.ref.model.Employee;
import org.apache.olingo.odata2.annotation.processor.ref.model.Location;
import org.apache.olingo.odata2.annotation.processor.ref.model.Manager;
import org.apache.olingo.odata2.annotation.processor.ref.model.Photo;
+import org.apache.olingo.odata2.annotation.processor.ref.model.RefBase;
import org.apache.olingo.odata2.annotation.processor.ref.model.ResourceHelper;
import org.apache.olingo.odata2.annotation.processor.ref.model.Room;
import org.apache.olingo.odata2.annotation.processor.ref.model.Team;
+import org.apache.olingo.odata2.annotation.processor.ref.model.jpa.Animal;
import org.apache.olingo.odata2.api.ODataCallback;
import org.apache.olingo.odata2.api.ODataDebugCallback;
import org.apache.olingo.odata2.api.ODataService;
@@ -54,12 +59,26 @@
*/
private static class AnnotationInstances {
final static String MODEL_PACKAGE = "org.apache.olingo.odata2.annotation.processor.ref.model";
-
+ final static Set<Class<?>> ANNOTATED_MODEL_CLASSES = new HashSet<Class<?>>();
+ static {
+ ANNOTATED_MODEL_CLASSES.add(Building.class);
+ ANNOTATED_MODEL_CLASSES.add(City.class);
+ ANNOTATED_MODEL_CLASSES.add(Employee.class);
+ ANNOTATED_MODEL_CLASSES.add(Location.class);
+ ANNOTATED_MODEL_CLASSES.add(Manager.class);
+ ANNOTATED_MODEL_CLASSES.add(Photo.class);
+ ANNOTATED_MODEL_CLASSES.add(RefBase.class);
+ ANNOTATED_MODEL_CLASSES.add(Room.class);
+ ANNOTATED_MODEL_CLASSES.add(Team.class);
+ // JPA
+ ANNOTATED_MODEL_CLASSES.add(Animal.class);
+ }
final static ODataService ANNOTATION_ODATA_SERVICE;
static {
try {
- ANNOTATION_ODATA_SERVICE = AnnotationServiceFactory.createAnnotationService(MODEL_PACKAGE);
+// ANNOTATION_ODATA_SERVICE = AnnotationServiceFactory.createAnnotationService(MODEL_PACKAGE);
+ ANNOTATION_ODATA_SERVICE = AnnotationServiceFactory.createAnnotationService(ANNOTATED_MODEL_CLASSES);
initializeSampleData();
} catch (ODataApplicationException ex) {
throw new RuntimeException("Exception during sample data generation.", ex);
@@ -116,12 +135,12 @@
}
- private static <T> DataStore<T> getDataStore(final Class<T> clz) throws DataStoreException {
- return DataStore.createInMemory(clz, true);
+ private static <T> InMemoryDataStore<T> getDataStore(Class<T> clz) throws DataStoreException {
+ return InMemoryDataStore.createInMemory(clz, true);
}
private static void initializeSampleData() throws ODataApplicationException {
- DataStore<Team> teamDs = getDataStore(Team.class);
+ InMemoryDataStore<Team> teamDs = getDataStore(Team.class);
teamDs.create(createTeam("Team Alpha", true));
teamDs.create(createTeam("Team Beta", false));
teamDs.create(createTeam("Team Gamma", false));
@@ -130,7 +149,7 @@
teamDs.create(subTeam);
teamDs.create(createTeam("Team Zeta", true, subTeam));
- DataStore<Building> buildingsDs = getDataStore(Building.class);
+ InMemoryDataStore<Building> buildingsDs = getDataStore(Building.class);
Building redBuilding = createBuilding("Red Building");
buildingsDs.create(redBuilding);
Building greenBuilding = createBuilding("Green Building");
@@ -140,13 +159,13 @@
Building yellowBuilding = createBuilding("Yellow Building");
buildingsDs.create(yellowBuilding);
- DataStore<Photo> photoDs = getDataStore(Photo.class);
+ InMemoryDataStore<Photo> photoDs = getDataStore(Photo.class);
photoDs.create(createPhoto("Small picture", ResourceHelper.Format.GIF));
photoDs.create(createPhoto("Medium picture", ResourceHelper.Format.PNG));
photoDs.create(createPhoto("Big picture", ResourceHelper.Format.JPEG));
photoDs.create(createPhoto("Huge picture", ResourceHelper.Format.BMP));
- DataStore<Room> roomDs = getDataStore(Room.class);
+ InMemoryDataStore<Room> roomDs = getDataStore(Room.class);
roomDs.create(createRoom("Tiny red room", 5, 1, redBuilding));
roomDs.create(createRoom("Small red room", 20, 1, redBuilding));
roomDs.create(createRoom("Small green room", 20, 1, greenBuilding));
@@ -154,7 +173,7 @@
roomDs.create(createRoom("Huge blue room", 120, 1, blueBuilding));
roomDs.create(createRoom("Huge yellow room", 120, 1, yellowBuilding));
- DataStore<Employee> employeeDataStore = getDataStore(Employee.class);
+ InMemoryDataStore<Employee> employeeDataStore = getDataStore(Employee.class);
employeeDataStore.create(createEmployee("first Employee",
new Location("Norge", "8392", "Ä"), 42, null,
photoDs.read().iterator().next().getImage(), photoDs.read().iterator().next().getImageType(),
diff --git a/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/jpa/Animal.java b/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/jpa/Animal.java
new file mode 100644
index 0000000..8418343
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/model/jpa/Animal.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * 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.apache.olingo.odata2.annotation.processor.ref.model.jpa;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.annotation.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.annotation.edm.EdmKey;
+import org.apache.olingo.odata2.api.annotation.edm.EdmProperty;
+
+@EdmEntitySet
+@EdmEntityType
+@Entity
+public class Animal implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @EdmKey
+ @EdmProperty
+ private String id;
+ @EdmProperty
+ private String name;
+ @EdmProperty
+ private Integer age;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+}
diff --git a/odata2-annotation-processor/annotation-processor-ref/src/main/resources/META-INF/persistence.xml b/odata2-annotation-processor/annotation-processor-ref/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..c434fdf
--- /dev/null
+++ b/odata2-annotation-processor/annotation-processor-ref/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+ <persistence-unit name="JpaAnnotationDataStorePersistence" transaction-type="RESOURCE_LOCAL">
+ <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+ <class>org.apache.olingo.odata2.annotation.processor.ref.model.jpa.Animal</class>
+ <properties>
+ <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
+ <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:org.apache.olingo.annotation.jpa.sample"/>
+<!-- <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:/tmp/db/olingo;shutdown=true"/>-->
+ <property name="javax.persistence.jdbc.user" value="sa"/>
+ <property name="javax.persistence.jdbc.password" value=""/>
+ <property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.HSQLPlatform"/>
+ <property name="eclipselink.logging.level" value="ALL"/>
+ <property name="eclipselink.orm.throw.exceptions" value="true"/>
+ <property name="eclipselink.ddl-generation" value="create-tables"/>
+ <property name="eclipselink.ddl-generation.output-mode" value="database"/>
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git a/odata2-annotation-processor/annotation-processor-web/src/main/webapp/WEB-INF/web.xml b/odata2-annotation-processor/annotation-processor-web/src/main/webapp/WEB-INF/web.xml
index 2e4635e..df856bb 100644
--- a/odata2-annotation-processor/annotation-processor-web/src/main/webapp/WEB-INF/web.xml
+++ b/odata2-annotation-processor/annotation-processor-web/src/main/webapp/WEB-INF/web.xml
@@ -36,7 +36,7 @@
<init-param>
<param-name>org.apache.olingo.odata2.service.factory</param-name>
<param-value>org.apache.olingo.odata2.annotation.processor.ref.AnnotationRefServiceFactory</param-value>
- </init-param>
+ </init-param>
<load-on-startup>1</load-on-startup>
</servlet>
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/SalesOrderHeaderProcessor.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/SalesOrderHeaderProcessor.java
index dd72595..945d909 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/SalesOrderHeaderProcessor.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/extension/SalesOrderHeaderProcessor.java
@@ -6,9 +6,9 @@
* to you 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
diff --git a/odata2-jpa-processor/jpa-web/src/main/webapp/SalesOrderProcessingMappingModel.xml b/odata2-jpa-processor/jpa-web/src/main/webapp/SalesOrderProcessingMappingModel.xml
index 50afd7e..e690d0a 100644
--- a/odata2-jpa-processor/jpa-web/src/main/webapp/SalesOrderProcessingMappingModel.xml
+++ b/odata2-jpa-processor/jpa-web/src/main/webapp/SalesOrderProcessingMappingModel.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
- license agreements. See the NOTICE file distributed with this work for additional
- information regarding copyright ownership. The ASF licenses this file to
- you 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
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
+ license agreements. See the NOTICE file distributed with this work for additional
+ information regarding copyright ownership. The ASF licenses this file to
+ you 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. -->
<JPAEDMMappingModel
xmlns="http://www.apache.org/olingo/odata2/jpa/processor/api/model/mapping">
@@ -59,4 +59,4 @@
</JPAEmbeddableType>
</JPAEmbeddableTypes>
</PersistenceUnit>
-</JPAEDMMappingModel>
\ No newline at end of file
+</JPAEDMMappingModel>