You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:50 UTC
[45/51] [partial] initial commit
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java
new file mode 100644
index 0000000..271455d
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPAEdmNameBuilder.java
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.access.model;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+
+import javax.persistence.Column;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.PluralAttribute;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.Mapping;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAEdmMappingModelAccess;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationEndView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationSetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmAssociationView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmBaseView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmComplexPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityContainerView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntitySetView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmEntityTypeView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmMapping;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmNavigationPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmPropertyView;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmSchemaView;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmComplexType;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmMappingImpl;
+
+public class JPAEdmNameBuilder {
+ private static final String ENTITY_CONTAINER_SUFFIX = "Container";
+ private static final String ENTITY_SET_SUFFIX = "s";
+ private static final String ASSOCIATIONSET_SUFFIX = "Set";
+ private static final String NAVIGATION_NAME = "Details";
+ private static final String UNDERSCORE = "_";
+
+ public static FullQualifiedName build(final JPAEdmBaseView view, final String name) {
+ FullQualifiedName fqName = new FullQualifiedName(buildNamespace(view),
+ name);
+ return fqName;
+ }
+
+ /*
+ * ************************************************************************
+ * EDM EntityType Name - RULES
+ * ************************************************************************
+ * EDM Entity Type Name = JPA Entity Name EDM Entity Type Internal Name =
+ * JPA Entity Name
+ * ************************************************************************
+ * EDM Entity Type Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmEntityTypeView view) {
+
+ EntityType edmEntityType = view.getEdmEntityType();
+ String jpaEntityName = view.getJPAEntityType().getName();
+ JPAEdmMappingModelAccess mappingModelAccess = view
+ .getJPAEdmMappingModelAccess();
+ String edmEntityTypeName = null;
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ edmEntityTypeName = mappingModelAccess
+ .mapJPAEntityType(jpaEntityName);
+ }
+
+ JPAEdmMapping mapping = new JPAEdmMappingImpl();
+ mapping.setJPAType(view.getJPAEntityType().getJavaType());
+
+ if (edmEntityTypeName == null) {
+ edmEntityTypeName = jpaEntityName;
+ }
+ //Setting the mapping object
+ edmEntityType.setMapping(((Mapping) mapping)
+ .setInternalName(jpaEntityName));
+
+ edmEntityType.setName(edmEntityTypeName);
+
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Schema Name - RULES
+ * ************************************************************************
+ * Java Persistence Unit name is set as Schema's Namespace
+ * ************************************************************************
+ * EDM Schema Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmSchemaView view)
+ throws ODataJPAModelException {
+ view.getEdmSchema().setNamespace(buildNamespace(view));
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Property Name - RULES
+ * ************************************************************************
+ * OData Property Names are represented in Camel Case. The first character
+ * of JPA Attribute Name is converted to an UpperCase Character and set as
+ * OData Property Name. JPA Attribute Name is set as Internal Name for OData
+ * Property. The Column name (annotated as @Column(name="x")) is set as
+ * column name in the mapping object.
+ * ************************************************************************
+ * EDM Property Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmPropertyView view, final boolean isComplexMode) {
+ Attribute<?, ?> jpaAttribute = view.getJPAAttribute();
+ String jpaAttributeName = jpaAttribute.getName();
+ String propertyName = null;
+
+ JPAEdmMappingModelAccess mappingModelAccess = view
+ .getJPAEdmMappingModelAccess();
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ if (isComplexMode) {
+ propertyName = mappingModelAccess
+ .mapJPAEmbeddableTypeAttribute(view
+ .getJPAEdmComplexTypeView()
+ .getJPAEmbeddableType().getJavaType()
+ .getSimpleName(), jpaAttributeName);
+ } else {
+ propertyName = mappingModelAccess.mapJPAAttribute(
+ view.getJPAEdmEntityTypeView().getJPAEntityType()
+ .getName(), jpaAttributeName);
+ }
+ }
+ if (propertyName == null) {
+ propertyName = Character.toUpperCase(jpaAttributeName.charAt(0))
+ + jpaAttributeName.substring(1);
+ }
+
+ view.getEdmSimpleProperty().setName(propertyName);
+
+ JPAEdmMapping mapping = new JPAEdmMappingImpl();
+ ((Mapping) mapping).setInternalName(jpaAttributeName);
+
+ AnnotatedElement annotatedElement = (AnnotatedElement) jpaAttribute
+ .getJavaMember();
+ if (annotatedElement != null) {
+ Column column = annotatedElement.getAnnotation(Column.class);
+ if (column != null) {
+ mapping.setJPAColumnName(column.name());
+ }
+ } else {
+ ManagedType<?> managedType = jpaAttribute.getDeclaringType();
+ if (managedType != null) {
+ Class<?> clazz = managedType.getJavaType();
+ try {
+ Field field = clazz.getDeclaredField(jpaAttributeName);
+ Column column = field.getAnnotation(Column.class);
+ if (column != null) {
+ mapping.setJPAColumnName(column.name());
+ }
+ } catch (SecurityException e) {
+
+ } catch (NoSuchFieldException e) {
+
+ }
+ }
+
+ }
+ view.getEdmSimpleProperty().setMapping((Mapping) mapping);
+ }
+
+ /*
+ * ************************************************************************
+ * EDM EntityContainer Name - RULES
+ * ************************************************************************
+ * Entity Container Name = EDM Namespace + Literal "Container"
+ * ************************************************************************
+ * EDM EntityContainer Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmEntityContainerView view) {
+ view.getEdmEntityContainer().setName(
+ buildNamespace(view) + ENTITY_CONTAINER_SUFFIX);
+ }
+
+ /*
+ * ************************************************************************
+ * EDM EntitySet Name - RULES
+ * ************************************************************************
+ * Entity Set Name = JPA Entity Type Name + Literal "s"
+ * ************************************************************************
+ * EDM EntitySet Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmEntitySetView view,
+ final JPAEdmEntityTypeView entityTypeView) {
+ FullQualifiedName fQname = view.getEdmEntitySet().getEntityType();
+ JPAEdmMappingModelAccess mappingModelAccess = view
+ .getJPAEdmMappingModelAccess();
+ String entitySetName = null;
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ Mapping mapping = entityTypeView.getEdmEntityType().getMapping();
+ if (mapping != null) {
+ entitySetName = mappingModelAccess.mapJPAEntitySet(mapping
+ .getInternalName());
+ }
+ }
+
+ if (entitySetName == null) {
+ entitySetName = fQname.getName() + ENTITY_SET_SUFFIX;
+ }
+
+ view.getEdmEntitySet().setName(entitySetName);
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Complex Type Name - RULES
+ * ************************************************************************
+ * Complex Type Name = JPA Embeddable Type Simple Name.
+ * ************************************************************************
+ * EDM Complex Type Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmComplexType view) {
+
+ JPAEdmMappingModelAccess mappingModelAccess = view
+ .getJPAEdmMappingModelAccess();
+ String jpaEmbeddableTypeName = view.getJPAEmbeddableType()
+ .getJavaType().getSimpleName();
+ String edmComplexTypeName = null;
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ edmComplexTypeName = mappingModelAccess
+ .mapJPAEmbeddableType(jpaEmbeddableTypeName);
+ }
+
+ if (edmComplexTypeName == null) {
+ edmComplexTypeName = jpaEmbeddableTypeName;
+ }
+
+ view.getEdmComplexType().setName(edmComplexTypeName);
+
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Complex Property Name - RULES
+ * ************************************************************************
+ * The first character of JPA complex attribute name is converted to
+ * uppercase. The modified JPA complex attribute name is assigned as EDM
+ * complex property name. The unmodified JPA complex attribute name is
+ * assigned as internal name.
+ * ************************************************************************
+ * EDM Complex Property Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmComplexPropertyView complexView,
+ final JPAEdmPropertyView propertyView) {
+
+ ComplexProperty complexProperty = complexView.getEdmComplexProperty();
+
+ String jpaAttributeName = propertyView.getJPAAttribute().getName();
+ String jpaEntityTypeName = propertyView.getJPAEdmEntityTypeView()
+ .getJPAEntityType().getName();
+
+ JPAEdmMappingModelAccess mappingModelAccess = complexView
+ .getJPAEdmMappingModelAccess();
+ String propertyName = null;
+
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ propertyName = mappingModelAccess.mapJPAAttribute(
+ jpaEntityTypeName, jpaAttributeName);
+ }
+
+ if (propertyName == null) {
+ propertyName = Character.toUpperCase(jpaAttributeName.charAt(0))
+ + jpaAttributeName.substring(1);
+ }
+ // change for navigation property issue
+ JPAEdmMapping mapping = new JPAEdmMappingImpl();
+ ((Mapping) mapping).setInternalName(jpaAttributeName);
+ mapping.setJPAType(propertyView.getJPAAttribute().getJavaType());
+ complexProperty.setMapping((Mapping) mapping);
+
+ complexProperty.setName(propertyName);
+
+ }
+
+ public static void build(final JPAEdmComplexPropertyView complexView, final String parentComplexTypeName)
+ {
+ ComplexProperty complexProperty = complexView.getEdmComplexProperty();
+
+ JPAEdmMappingModelAccess mappingModelAccess = complexView.getJPAEdmMappingModelAccess();
+ JPAEdmPropertyView propertyView = ((JPAEdmPropertyView) complexView);
+ String jpaAttributeName = propertyView.getJPAAttribute().getName();
+ String propertyName = null;
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ propertyName = mappingModelAccess.mapJPAEmbeddableTypeAttribute(
+ parentComplexTypeName, jpaAttributeName);
+ }
+ if (propertyName == null) {
+ propertyName = Character.toUpperCase(jpaAttributeName.charAt(0))
+ + jpaAttributeName.substring(1);
+ }
+ JPAEdmMapping mapping = new JPAEdmMappingImpl();
+ ((Mapping) mapping).setInternalName(jpaAttributeName);
+ mapping.setJPAType(propertyView.getJPAAttribute().getJavaType());
+ complexProperty.setMapping((Mapping) mapping);
+ complexProperty.setName(propertyName);
+
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Association End Name - RULES
+ * ************************************************************************
+ * Association End name = Namespace + Entity Type Name
+ * ************************************************************************
+ * EDM Association End Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmAssociationEndView assocaitionEndView,
+ final JPAEdmEntityTypeView entityTypeView, final JPAEdmPropertyView propertyView) {
+
+ String namespace = buildNamespace(assocaitionEndView);
+
+ String name = entityTypeView.getEdmEntityType().getName();
+ FullQualifiedName fQName = new FullQualifiedName(namespace, name);
+ assocaitionEndView.getEdmAssociationEnd1().setType(fQName);
+
+ name = null;
+ String jpaEntityTypeName = null;
+ try {
+
+ PluralAttribute<?, ?, ?> jpattr = (PluralAttribute<?, ?, ?>) propertyView
+ .getJPAAttribute();
+
+ jpaEntityTypeName = jpattr.getElementType().getJavaType()
+ .getSimpleName();
+
+ } catch (Exception e) {
+ jpaEntityTypeName = propertyView.getJPAAttribute().getJavaType()
+ .getSimpleName();
+ }
+
+ JPAEdmMappingModelAccess mappingModelAccess = assocaitionEndView
+ .getJPAEdmMappingModelAccess();
+
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ name = mappingModelAccess.mapJPAEntityType(jpaEntityTypeName);
+ }
+
+ if (name == null) {
+ name = jpaEntityTypeName;
+ }
+
+ fQName = new FullQualifiedName(namespace, name);
+ assocaitionEndView.getEdmAssociationEnd2().setType(fQName);
+
+ }
+
+ private static String buildNamespace(final JPAEdmBaseView view) {
+ JPAEdmMappingModelAccess mappingModelAccess = view
+ .getJPAEdmMappingModelAccess();
+ String namespace = null;
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ namespace = mappingModelAccess.mapJPAPersistenceUnit(view
+ .getpUnitName());
+ }
+ if (namespace == null) {
+ namespace = view.getpUnitName();
+ }
+
+ return namespace;
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Association Name - RULES
+ * ************************************************************************
+ * Association name = Association + End1 Name + End2 Name
+ * ************************************************************************
+ * EDM Association Name - RULES
+ * ************************************************************************
+ */
+
+ public static void build(final JPAEdmAssociationView view, final int count) {
+ Association association = view.getEdmAssociation();
+ String associationName = null;
+ String end1Name = association.getEnd1().getType().getName();
+ String end2Name = association.getEnd2().getType().getName();
+
+ if (end1Name.compareToIgnoreCase(end2Name) > 0) {
+ associationName = end2Name + UNDERSCORE + end1Name;
+ } else {
+ associationName = end1Name + UNDERSCORE + end2Name;
+ }
+ if (count > 1) {
+ associationName = associationName + Integer.toString(count - 1);
+ }
+ association.setName(associationName);
+
+ }
+
+ /*
+ * ************************************************************************
+ * EDM Association Set Name - RULES
+ * ************************************************************************
+ * Association Set name = Association Name + "Set"
+ * ************************************************************************
+ * EDM Association Set Name - RULES
+ * ************************************************************************
+ */
+ public static void build(final JPAEdmAssociationSetView view) {
+ AssociationSet associationSet = view.getEdmAssociationSet();
+
+ String name = view.getEdmAssociation().getName();
+ associationSet.setName(name + ASSOCIATIONSET_SUFFIX);
+
+ }
+
+ public static void build(final JPAEdmAssociationView associationView,
+ final JPAEdmPropertyView propertyView,
+ final JPAEdmNavigationPropertyView navPropertyView, final int count) {
+
+ String toName = null;
+ String fromName = null;
+ String navPropName = null;
+ NavigationProperty navProp = navPropertyView.getEdmNavigationProperty();
+ String namespace = buildNamespace(associationView);
+
+ Association association = associationView.getEdmAssociation();
+ navProp.setRelationship(new FullQualifiedName(namespace, association
+ .getName()));
+
+ FullQualifiedName associationEndTypeOne = association.getEnd1()
+ .getType();
+ FullQualifiedName associationEndTypeTwo = association.getEnd2()
+ .getType();
+
+ Attribute<?, ?> jpaAttribute = propertyView.getJPAAttribute();
+ navProp.setMapping(new Mapping().setInternalName(jpaAttribute.getName()));
+
+ String jpaEntityTypeName = propertyView.getJPAEdmEntityTypeView()
+ .getJPAEntityType().getName();
+ JPAEdmMappingModelAccess mappingModelAccess = navPropertyView
+ .getJPAEdmMappingModelAccess();
+
+ try {
+ PluralAttribute<?, ?, ?> jpattr = (PluralAttribute<?, ?, ?>) propertyView
+ .getJPAAttribute();
+
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ toName = mappingModelAccess.mapJPAEntityType(jpattr
+ .getElementType().getJavaType().getSimpleName());
+ fromName = mappingModelAccess
+ .mapJPAEntityType(jpaEntityTypeName);
+ navPropName = mappingModelAccess.mapJPARelationship(
+ jpaEntityTypeName, jpattr.getName());
+ }
+ if (toName == null) {
+ toName = jpattr.getElementType().getJavaType().getSimpleName();
+ }
+ if (fromName == null) {
+ fromName = jpaEntityTypeName;
+ }
+
+ if (navPropName == null) {
+ navPropName = toName.concat(NAVIGATION_NAME);
+ }
+ if (count > 1) {
+ navPropName = navPropName + Integer.toString(count - 1);
+ }
+ navProp.setName(navPropName);
+
+ if (toName.equals(associationEndTypeOne.getName())) {
+ navProp.setFromRole(association.getEnd2().getRole());
+ navProp.setToRole(association.getEnd1().getRole());
+ } else if (toName.equals(associationEndTypeTwo.getName())) {
+ navProp.setToRole(association.getEnd2().getRole());
+ navProp.setFromRole(association.getEnd1().getRole());
+ }
+
+ } catch (Exception e) {
+ if (mappingModelAccess != null
+ && mappingModelAccess.isMappingModelExists()) {
+ navPropName = mappingModelAccess.mapJPARelationship(
+ jpaEntityTypeName, jpaAttribute.getName());
+ toName = mappingModelAccess.mapJPAEntityType(jpaAttribute
+ .getJavaType().getSimpleName());
+ fromName = mappingModelAccess
+ .mapJPAEntityType(jpaEntityTypeName);
+ }
+ if (toName == null) {
+ toName = jpaAttribute.getJavaType().getSimpleName();
+ }
+ if (fromName == null) {
+ fromName = jpaEntityTypeName;
+ }
+
+ if (navPropName == null) {
+ navPropName = toName.concat(NAVIGATION_NAME);
+ }
+ if (count > 1) {
+ navPropName = navPropName + Integer.toString(count - 1);
+ }
+ navProp.setName(navPropName);
+
+ if (toName.equals(associationEndTypeOne.getName())) {
+ navProp.setFromRole(association.getEnd2().getRole());
+ navProp.setToRole(association.getEnd1().getRole());
+ } else if (toName.equals(associationEndTypeTwo.getName())) {
+
+ navProp.setToRole(association.getEnd2().getRole());
+ navProp.setFromRole(association.getEnd1().getRole());
+ }
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java
new file mode 100644
index 0000000..ae9eabc
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/access/model/JPATypeConvertor.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.access.model;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.metamodel.Attribute;
+
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+/**
+ * This class holds utility methods for Type conversions between JPA and OData Types.
+ *
+ * @author SAP AG
+ *
+ */
+public class JPATypeConvertor {
+
+ /**
+ * This utility method converts a given jpa Type to equivalent
+ * EdmSimpleTypeKind for maintaining compatibility between Java and OData
+ * Types.
+ *
+ * @param jpaType
+ * The JPA Type input.
+ * @return The corresponding EdmSimpleTypeKind.
+ * @throws ODataJPAModelException
+ * @throws ODataJPARuntimeException
+ *
+ * @see EdmSimpleTypeKind
+ */
+ public static EdmSimpleTypeKind convertToEdmSimpleType(final Class<?> jpaType, final Attribute<?, ?> currentAttribute) throws ODataJPAModelException {
+ if (jpaType.equals(String.class)) {
+ return EdmSimpleTypeKind.String;
+ }
+ else if (jpaType.equals(Long.class) || jpaType.equals(long.class)) {
+ return EdmSimpleTypeKind.Int64;
+ }
+ else if (jpaType.equals(Short.class) || jpaType.equals(short.class)) {
+ return EdmSimpleTypeKind.Int16;
+ }
+ else if (jpaType.equals(Integer.class) || jpaType.equals(int.class)) {
+ return EdmSimpleTypeKind.Int32;
+ }
+ else if (jpaType.equals(Double.class) || jpaType.equals(double.class)) {
+ return EdmSimpleTypeKind.Double;
+ }
+ else if (jpaType.equals(Float.class) || jpaType.equals(float.class)) {
+ return EdmSimpleTypeKind.Single;
+ }
+ else if (jpaType.equals(BigDecimal.class)) {
+ return EdmSimpleTypeKind.Decimal;
+ }
+ else if (jpaType.equals(byte[].class)) {
+ return EdmSimpleTypeKind.Binary;
+ }
+ else if (jpaType.equals(Byte.class) || jpaType.equals(byte.class)) {
+ return EdmSimpleTypeKind.Byte;
+ }
+ else if (jpaType.equals(Byte[].class)) {
+ return EdmSimpleTypeKind.Binary;
+ }
+ else if (jpaType.equals(Boolean.class) || jpaType.equals(boolean.class)) {
+ return EdmSimpleTypeKind.Boolean;
+ }
+ else if ((jpaType.equals(Date.class)) || (jpaType.equals(Calendar.class))) {
+ try {
+ if ((currentAttribute != null) && (currentAttribute.getDeclaringType().getJavaType().getDeclaredField(currentAttribute.getName()).getAnnotation(Temporal.class).value() == TemporalType.TIME)) {
+ return EdmSimpleTypeKind.Time;
+ } else {
+ return EdmSimpleTypeKind.DateTime;
+ }
+ } catch (NoSuchFieldException e) {
+ throw ODataJPAModelException
+ .throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+ } catch (SecurityException e) {
+ throw ODataJPAModelException
+ .throwException(ODataJPAModelException.GENERAL.addContent(e.getMessage()), e);
+ }
+ }
+ else if (jpaType.equals(UUID.class)) {
+ return EdmSimpleTypeKind.Guid;
+ }
+ throw ODataJPAModelException.throwException(ODataJPAModelException.TYPE_NOT_SUPPORTED.addContent(jpaType.toString()), null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java
new file mode 100644
index 0000000..6297f67
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPACreateRequest.java
@@ -0,0 +1,477 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+public class JPACreateRequest extends JPAWriteRequest {
+
+ private Metamodel metamodel;
+
+ public JPACreateRequest() {
+ super();
+ jpaEmbeddableKeyMap = new HashMap<String, HashMap<String, String>>();
+ jpaEmbeddableKeyObjectMap = new HashMap<String, Class<?>>();
+ }
+
+ public JPACreateRequest(final Metamodel metamodel) {
+ this();
+ this.metamodel = metamodel;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> List<T> process(final PostUriInfo postUriInfo, final InputStream content, final String requestContentType) throws ODataJPARuntimeException {
+ final EdmEntitySet entitySet = postUriInfo.getTargetEntitySet();
+ EdmEntityType entityType = null;
+ try {
+ entityType = entitySet.getEntityType();
+ } catch (EdmException e3) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e3.getMessage()), e3);
+ }
+ String entityName = null;
+ try {
+ if (entityType.getMapping() != null && entityType.getMapping().getInternalName() != null)
+ {
+ entityName = entityType.getMapping().getInternalName();
+ } else {
+ entityName = entityType.getName();
+ }
+ } catch (EdmException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ }
+ Object jpaEntity = null;
+ Set<EntityType<?>> entityTypeSet = metamodel.getEntities();
+ String currentEntityName = null;
+ for (EntityType<?> entityTypeTemp : entityTypeSet) {
+ if (entityTypeTemp.getJavaType().getName().endsWith("." + entityName)) {
+ currentEntityName = entityTypeTemp.getName();
+ try {
+ jpaEntity = entityTypeTemp.getJavaType().newInstance();
+ break;
+ } catch (InstantiationException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ }
+
+ ODataEntry entryValues = null;
+ try {
+ entryValues = parseEntry(entitySet, content, requestContentType, true);
+ } catch (ODataBadRequestException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ }
+
+ Map<String, Object> propertyValueMap = entryValues.getProperties();
+ parse2JPAEntityValueMap(jpaEntity, entityType, propertyValueMap, currentEntityName);
+
+ Map<EdmNavigationProperty, EdmEntitySet> navPropEntitySetMap = null;
+ try {
+ navPropEntitySetMap = createInlinedEntities(jpaEntity, entitySet, entryValues, currentEntityName);
+ } catch (ODataException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ List<T> objectList = new ArrayList<T>();
+ objectList.add((T) jpaEntity);
+ objectList.add((T) navPropEntitySetMap);
+ return objectList;
+ }
+
+ @SuppressWarnings("unchecked")
+ public final Object parse2JPAEntityValueMap(
+ final Object jpaEntity, final EdmStructuralType edmEntityType, final Map<String, Object> propertyValueMap, final String entityName)
+ throws ODataJPARuntimeException {
+
+ if (jpaEntity == null || edmEntityType == null || propertyValueMap == null || propertyValueMap.size() == 0) {
+ return null;
+ }
+
+ String jpaEntityAccessKey = jpaEntity.getClass().getName();
+
+ if (!jpaEntityAccessMap.containsKey(jpaEntityAccessKey)) {
+ jpaEntityAccessMap.put(jpaEntityAccessKey,
+ getSetters(jpaEntity, edmEntityType, true));
+ }
+
+ HashMap<String, Method> setters = jpaEntityAccessMap
+ .get(jpaEntityAccessKey);
+ HashMap<String, String> embeddableKeys = jpaEmbeddableKeyMap
+ .get(jpaEntityAccessKey);
+ String propertyName = null;
+ try {
+ for (String key : setters.keySet()) {
+
+ EdmProperty property = (EdmProperty) edmEntityType
+ .getProperty(key);
+ if (property.getMapping() != null && property.getMapping().getInternalName() != null) {
+ propertyName = property.getMapping().getInternalName();
+ } else {
+ propertyName = property.getName();
+ }
+ Method method = setters.get(key);
+ Object propertyValue = propertyValueMap.get(key);
+ if (propertyValue == null) {
+ continue;
+ }
+ if (propertyValue instanceof java.util.GregorianCalendar) {
+ propertyValue = ((java.util.GregorianCalendar) propertyValue).getTime();
+ }
+
+ if (method != null) {
+ if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+ Object complexObject = jpaComplexObjectMap.get(propertyName);
+ parse2JPAEntityValueMap(complexObject, ((EdmComplexType) property.getType()),
+ (Map<String, Object>) propertyValue, propertyName);
+ setters.get(key).invoke(jpaEntity, complexObject);
+ } else {
+ setters.get(key).invoke(jpaEntity, propertyValue);
+ }
+ }
+ }
+
+ if (embeddableKeys != null) {
+ Object embeddableKeyObj = null;
+ Method method = null;
+ for (String embeddableKey : embeddableKeys.keySet()) {
+ String name = embeddableKeys.get(embeddableKey);
+ String[] nameParts = name.split("\\.");//$NON-NLS-1$
+ Object propertyValue = jpaEntity;
+ Class<?> propertyClass = null;
+
+ try {
+ for (EntityType<?> entity : metamodel.getEntities())
+ {
+ if (entity.getName().equals(entityName))
+ {
+ Attribute<?, ?> attribute = entity.getAttribute(nameParts[0].substring(3, 4).toLowerCase() + nameParts[0].substring(4));
+ propertyClass = attribute.getJavaType();
+ if (embeddableKeyObj == null) {
+ try {
+ embeddableKeyObj = propertyClass.newInstance();
+ } catch (InstantiationException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ break;
+ }
+ }
+
+ method = propertyValue.getClass().getMethod(
+ nameParts[0], propertyClass);
+ populateEmbeddableKey(embeddableKeyObj, embeddableKey, nameParts[1], propertyValueMap);
+ } catch (NoSuchMethodException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ propertyName = "Embeddable Key";//$NON-NLS-1$
+ method.invoke(jpaEntity, embeddableKeyObj);
+ }
+ } catch (SecurityException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.ERROR_JPQL_PARAM_VALUE
+ .addContent(propertyName), e);
+ } catch (InvocationTargetException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ return jpaEntity;
+ }
+
+ private void populateEmbeddableKey(final Object embeddableKeyObject, final String key, final String setterName, final Map<String, Object> propertyValueMap) throws ODataJPARuntimeException {
+ Class<?> propertyClass = jpaEmbeddableKeyObjectMap.get(key);
+ Method method = null;
+ try {
+ method = embeddableKeyObject.getClass().getMethod(setterName, propertyClass);
+ } catch (NoSuchMethodException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ } catch (SecurityException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ }
+ try {
+ method.invoke(embeddableKeyObject, propertyValueMap.get(key));
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.ERROR_JPQL_KEY_VALUE
+ .addContent(key), e);
+ } catch (InvocationTargetException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+
+ private <T> Map<EdmNavigationProperty, EdmEntitySet> createInlinedEntities(final T jpaEntity, final EdmEntitySet entitySet, final ODataEntry entryValues, final String jpaEntityName) throws ODataException {
+ if (jpaEntity == null) {
+ return null;
+ }
+ Map<String, Object> relatedPropertyValueMap = new HashMap<String, Object>();
+ Map<String, Class<?>> relatedClassMap = new HashMap<String, Class<?>>();
+ Map<EdmNavigationProperty, EdmEntitySet> navPropEntitySetMap = new HashMap<EdmNavigationProperty, EdmEntitySet>();
+ final EdmEntityType entityType = entitySet.getEntityType();
+ for (final String navigationPropertyName : entityType.getNavigationPropertyNames()) {
+ final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) entityType.getProperty(navigationPropertyName);
+ List<ODataEntry> relatedValueList = null;
+ if (entryValues.getProperties().get(navigationPropertyName) != null) {
+ relatedValueList = ((ODataFeed) entryValues.getProperties().get(navigationPropertyName)).getEntries();
+ }
+ List<Object> relatedDataList = null;
+ if (relatedValueList != null) {
+ relatedDataList = new ArrayList<Object>();
+ final EdmEntitySet relatedEntitySet = entitySet.getRelatedEntitySet(navigationProperty);
+
+ for (final ODataEntry relatedValues : relatedValueList) {
+
+ String entityName = null;
+ EdmEntityType relatedEntityType = relatedEntitySet.getEntityType();
+ try {
+ if (relatedEntityType.getMapping() != null && relatedEntityType.getMapping().getInternalName() != null)
+ {
+ entityName = relatedEntityType.getMapping().getInternalName();
+ } else {
+ entityName = relatedEntityType.getName();
+ }
+ } catch (EdmException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ }
+
+ Object relatedData = null;
+ Set<EntityType<?>> entityTypeSet = metamodel.getEntities();
+ String currentEntityName = null;
+ for (EntityType<?> entityTypeTemp : entityTypeSet) {
+ if (entityTypeTemp.getJavaType().getName().endsWith("." + entityName)) {
+ currentEntityName = entityTypeTemp.getName();
+ try {
+ relatedClassMap.put(navigationProperty.getMapping().getInternalName(), entityTypeTemp.getJavaType());
+ relatedData = entityTypeTemp.getJavaType().newInstance();
+ break;
+ } catch (InstantiationException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ }
+ if (relatedValues != null && relatedEntitySet != null) {
+ relatedDataList.add(relatedData);
+ if (navPropEntitySetMap.get(navigationProperty) == null) {
+ navPropEntitySetMap.put(navigationProperty, relatedEntitySet);
+ }
+ parse2JPAEntityValueMap(relatedData, relatedEntitySet.getEntityType(), relatedValues.getProperties(), currentEntityName);
+ } else {
+ continue;
+ }
+ createInlinedEntities(relatedData, relatedEntitySet, relatedValues, currentEntityName);
+ }
+ }
+ relatedPropertyValueMap.put(navigationProperty.getMapping().getInternalName(), relatedDataList);
+ }
+ setNavigationProperties(jpaEntity, entitySet, relatedPropertyValueMap, jpaEntityName, relatedClassMap);
+ return navPropEntitySetMap;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void setNavigationProperties(
+ final Object jpaEntity, final EdmEntitySet entitySet, final Map<String, Object> propertyValueMap, final String entityName, final Map<String, Class<?>> relatedClassMap) throws ODataJPARuntimeException {
+ if (jpaEntity == null || entitySet == null || propertyValueMap == null || propertyValueMap.size() == 0) {
+ return;
+ }
+ List<HashMap<?, ?>> mapList = getSettersForNavigationProperties(jpaEntity, entitySet, relatedClassMap);
+ HashMap<String, Method> setters = (HashMap<String, Method>) mapList.get(0);
+ HashMap<String, EdmMultiplicity> multiplicityMap = (HashMap<String, EdmMultiplicity>) mapList.get(1);
+ for (String key : setters.keySet()) {
+ Method method = setters.get(key);
+ List<Object> propertyValue = (List<Object>) propertyValueMap.get(key);
+ if (propertyValue == null || propertyValue.size() == 0) {
+ continue;
+ }
+ try {
+ if (multiplicityMap.get(key) == EdmMultiplicity.MANY) {
+ method.invoke(jpaEntity, propertyValue);
+ } else {
+ method.invoke(jpaEntity, propertyValue.get(0));
+ }
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (InvocationTargetException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+
+ }
+
+ private List<HashMap<?, ?>> getSettersForNavigationProperties(final Object jpaEntity, final EdmEntitySet edmEntitySet, final Map<String, Class<?>> relatedClassMap) throws ODataJPARuntimeException {
+ List<HashMap<?, ?>> mapList = new ArrayList<HashMap<?, ?>>();
+ HashMap<String, Method> setters = new HashMap<String, Method>();
+ HashMap<String, EdmMultiplicity> multiplicityMap = new HashMap<String, EdmMultiplicity>();
+ EdmEntityType edmEntityType = null;
+ try {
+ edmEntityType = edmEntitySet.getEntityType();
+ } catch (EdmException e2) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e2.getMessage()), e2);
+ }
+
+ try {
+ for (final String navigationPropertyName : edmEntityType.getNavigationPropertyNames()) {
+ final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) edmEntityType.getProperty(navigationPropertyName);
+ String entityName = null;
+ try {
+ if (navigationProperty.getMapping() != null && navigationProperty.getMapping().getInternalName() != null)
+ {
+ entityName = navigationProperty.getMapping().getInternalName();
+ } else {
+ entityName = navigationProperty.getName();
+ }
+ } catch (EdmException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ }
+ String name = getSetterName(entityName);
+
+ Class<?> propertyClass = null;
+ if (navigationProperty.getMultiplicity() == EdmMultiplicity.MANY) {
+ propertyClass = List.class;
+ multiplicityMap.put(entityName, EdmMultiplicity.MANY);
+ } else {
+ propertyClass = relatedClassMap.get(entityName);
+ if (propertyClass == null) {
+ continue;
+ }
+ multiplicityMap.put(entityName, EdmMultiplicity.ONE);
+ }
+ try {
+ setters.put(
+ entityName,
+ jpaEntity.getClass().getDeclaredMethod(name, propertyClass));
+ } catch (NoSuchMethodException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (SecurityException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ mapList.add(0, setters);
+ mapList.add(1, multiplicityMap);
+ return mapList;
+ }
+
+ private String getSetterName(final String navigationPropertyName)
+ throws ODataJPARuntimeException {
+ StringBuilder builder = new StringBuilder();
+ char c = Character.toUpperCase(navigationPropertyName.charAt(0));
+
+ builder.append("set").append(c).append(navigationPropertyName.substring(1)) //$NON-NLS-1$
+ .toString();
+ if (builder.length() > 0) {
+ return builder.toString();
+ } else {
+ return null;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java
new file mode 100644
index 0000000..c1a3e8c
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPALink.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.uri.UriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.access.JPAProcessor;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAFactory;
+import org.apache.olingo.odata2.processor.core.jpa.ODataEntityParser;
+import org.apache.olingo.odata2.processor.core.jpa.access.data.JPAEntityParser;
+
+public class JPALink {
+
+ private ODataJPAContext context;
+ private JPAProcessor jpaProcessor;
+ private ODataEntityParser parser;
+ private Object targetJPAEntity;
+ private Object sourceJPAEntity;
+
+ public JPALink(final ODataJPAContext context) {
+ this.context = context;
+ jpaProcessor = ODataJPAFactory.createFactory().getJPAAccessFactory()
+ .getJPAProcessor(this.context);
+ parser = new ODataEntityParser(this.context);
+ }
+
+ public void setSourceJPAEntity(final Object jpaEntity) {
+ sourceJPAEntity = jpaEntity;
+ }
+
+ public void create(final PostUriInfo uriInfo, final InputStream content, final String requestContentType, final String contentType)
+ throws ODataJPARuntimeException, ODataJPAModelException {
+
+ EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+ String targerEntitySetName;
+ EdmNavigationProperty navigationProperty = null;
+ try {
+ targerEntitySetName = targetEntitySet.getName();
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+
+ List<UriInfo> uriInfoList = new ArrayList<UriInfo>();
+
+ if (((UriInfo) uriInfo).isLinks()) {
+ UriInfo getUriInfo = parser.parseLink(targetEntitySet, content, requestContentType);
+ uriInfoList = new ArrayList<UriInfo>();
+ uriInfoList.add(getUriInfo);
+ navigationProperty = uriInfo.getNavigationSegments().get(0).getNavigationProperty();
+ }
+ else
+ {
+ uriInfoList = parser.parseLinks(targetEntitySet, content, contentType);
+ }
+
+ if (uriInfoList == null) {
+ return;
+ }
+ try {
+ for (UriInfo getUriInfo : uriInfoList) {
+
+ if (!getUriInfo.getTargetEntitySet().getName().equals(targerEntitySetName))
+ {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.RELATIONSHIP_INVALID, null);
+ }
+ if (!((UriInfo) uriInfo).isLinks()) {
+ navigationProperty = getUriInfo.getNavigationSegments().get(0).getNavigationProperty();
+ }
+
+ targetJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+ if (targetJPAEntity != null && ((UriInfo) uriInfo).isLinks()) {
+ getUriInfo = parser.parseLinkURI();
+ sourceJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+ if (sourceJPAEntity == null) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.RESOURCE_X_NOT_FOUND.
+ addContent(getUriInfo.getTargetEntitySet().getName()), null);
+ }
+ }
+
+ JPAEntityParser entityParser = JPAEntityParser.create();
+ Method setMethod = entityParser.getAccessModifier(sourceJPAEntity,
+ navigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
+
+ Method getMethod = entityParser.getAccessModifier(sourceJPAEntity,
+ navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
+
+ if (getMethod.getReturnType().getTypeParameters() != null) {
+ @SuppressWarnings("unchecked")
+ List<Object> relatedEntities = (List<Object>) getMethod.invoke(sourceJPAEntity);
+ relatedEntities.add(targetJPAEntity);
+ setMethod.invoke(sourceJPAEntity, relatedEntities);
+ } else {
+ setMethod.invoke(sourceJPAEntity, targetJPAEntity);
+ }
+ }
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (InvocationTargetException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+
+ public void delete() {}
+
+ public void save() {
+ EntityManager em = context.getEntityManager();
+ EntityTransaction tx = em.getTransaction();
+
+ if (!tx.isActive()) {
+ em.getTransaction().begin();
+ em.persist(sourceJPAEntity);
+ em.getTransaction().commit();
+ }
+
+ }
+
+ public void update(final PutMergePatchUriInfo putUriInfo, final InputStream content,
+ final String requestContentType, final String contentType) throws ODataJPARuntimeException, ODataJPAModelException {
+ UriInfo uriInfo = (UriInfo) putUriInfo;
+
+ EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+ String targerEntitySetName;
+ EdmNavigationProperty navigationProperty = null;
+ try {
+ targerEntitySetName = targetEntitySet.getName();
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+
+ List<UriInfo> uriInfoList = new ArrayList<UriInfo>();
+
+ if (((UriInfo) uriInfo).isLinks()) {
+ UriInfo getUriInfo = parser.parseLink(targetEntitySet, content, requestContentType);
+ uriInfoList = new ArrayList<UriInfo>();
+ uriInfoList.add(getUriInfo);
+ navigationProperty = uriInfo.getNavigationSegments().get(0).getNavigationProperty();
+ }
+ else
+ {
+ uriInfoList = parser.parseLinks(targetEntitySet, content, contentType);
+ }
+
+ if (uriInfoList == null) {
+ return;
+ }
+ try {
+ for (UriInfo getUriInfo : uriInfoList) {
+
+ if (!getUriInfo.getTargetEntitySet().getName().equals(targerEntitySetName))
+ {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.RELATIONSHIP_INVALID, null);
+ }
+ if (!((UriInfo) uriInfo).isLinks()) {
+ navigationProperty = getUriInfo.getNavigationSegments().get(0).getNavigationProperty();
+ }
+
+ targetJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+ if (targetJPAEntity != null && ((UriInfo) uriInfo).isLinks()) {
+ getUriInfo = parser.parseLinkURI();
+ sourceJPAEntity = jpaProcessor.process((GetEntityUriInfo) getUriInfo);
+ if (sourceJPAEntity == null) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.RESOURCE_X_NOT_FOUND.
+ addContent(getUriInfo.getTargetEntitySet().getName()), null);
+ }
+ }
+
+ JPAEntityParser entityParser = JPAEntityParser.create();
+ Method setMethod = entityParser.getAccessModifier(sourceJPAEntity,
+ navigationProperty, JPAEntityParser.ACCESS_MODIFIER_SET);
+
+ Method getMethod = entityParser.getAccessModifier(sourceJPAEntity,
+ navigationProperty, JPAEntityParser.ACCESS_MODIFIER_GET);
+
+ if (getMethod.getReturnType().getTypeParameters() != null && getMethod.getReturnType().getTypeParameters().length != 0) {
+ @SuppressWarnings("unchecked")
+ List<Object> relatedEntities = (List<Object>) getMethod.invoke(sourceJPAEntity);
+ relatedEntities.add(targetJPAEntity);
+ setMethod.invoke(sourceJPAEntity, relatedEntities);
+ } else {
+ setMethod.invoke(sourceJPAEntity, targetJPAEntity);
+ }
+ }
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (InvocationTargetException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java
new file mode 100644
index 0000000..b8ae487
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAUpdateRequest.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+
+public class JPAUpdateRequest extends JPAWriteRequest {
+
+ public JPAUpdateRequest() {
+ super();
+ }
+
+ public void process(final Object jpaEntity, final PutMergePatchUriInfo putUriInfo, final InputStream content, final String requestContentType) throws ODataJPARuntimeException {
+
+ final EdmEntitySet entitySet = putUriInfo.getTargetEntitySet();
+ EdmEntityType entityType = null;
+ try {
+ entityType = entitySet.getEntityType();
+ } catch (EdmException e3) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e3.getMessage()), e3);
+ }
+
+ ODataEntry entryValues = null;
+ try {
+ entryValues = parseEntry(entitySet, content, requestContentType, false);
+ } catch (ODataBadRequestException e1) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e1.getMessage()), e1);
+ }
+ try {
+ Map<String, Object> propertValueMap = entryValues.getProperties();
+ parse2JPAEntityValueMap(jpaEntity, entityType, propertValueMap);
+ } catch (ODataJPARuntimeException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public final Object parse2JPAEntityValueMap(
+ final Object jpaEntity, final EdmStructuralType edmEntityType, final Map<String, Object> propertyValueMap)
+ throws ODataJPARuntimeException {
+
+ if (jpaEntity == null || edmEntityType == null || propertyValueMap == null) {
+ return null;
+ }
+
+ String jpaEntityAccessKey = jpaEntity.getClass().getName();
+
+ if (!jpaEntityAccessMap.containsKey(jpaEntityAccessKey)) {
+ jpaEntityAccessMap.put(jpaEntityAccessKey,
+ getSetters(jpaEntity, edmEntityType, false));
+ }
+
+ HashMap<String, Method> setters = jpaEntityAccessMap
+ .get(jpaEntityAccessKey);
+ List<EdmProperty> keyProperties = null;
+ if (edmEntityType instanceof EdmEntityType) {
+ try {
+ keyProperties = ((EdmEntityType) edmEntityType).getKeyProperties();
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ boolean isKeyProperty = false;
+ String propertyName = null;
+ try {
+ for (String key : setters.keySet()) {
+ isKeyProperty = false;
+ if (keyProperties != null) {
+ for (EdmProperty keyProperty : keyProperties) {
+ if (keyProperty.getName().equalsIgnoreCase(key)) {
+ isKeyProperty = true;
+ break;
+ }
+ }
+ if (isKeyProperty) {
+ continue;
+ }
+ }
+ EdmProperty property = (EdmProperty) edmEntityType
+ .getProperty(key);
+ if (property.getMapping() != null && property.getMapping().getInternalName() != null) {
+ propertyName = property.getMapping().getInternalName();
+ } else {
+ propertyName = property.getName();
+ }
+ Method method = setters.get(key);
+ Object propertyValue = propertyValueMap.get(key);
+ if (propertyValue == null) {
+ continue;
+ }
+ if (propertyValue != null) {
+ if (propertyValue instanceof java.util.GregorianCalendar) {
+ propertyValue = ((java.util.GregorianCalendar) propertyValue).getTime();
+ }
+
+ if (method != null) {
+ if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+ Object complexObject = jpaComplexObjectMap.get(propertyName);
+ parse2JPAEntityValueMap(complexObject, ((EdmComplexType) property.getType()),
+ (Map<String, Object>) propertyValue);
+ setters.get(key).invoke(jpaEntity, complexObject);
+ } else {
+ setters.get(key).invoke(jpaEntity, propertyValue);
+ }
+ }
+ }
+
+ }
+ } catch (SecurityException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalArgumentException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.ERROR_JPQL_PARAM_VALUE
+ .addContent(propertyName), e);
+ } catch (InvocationTargetException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ return jpaEntity;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java
new file mode 100644
index 0000000..d8fd6d4
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/cud/JPAWriteRequest.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.cud;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmStructuralType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPARuntimeException;
+import org.apache.olingo.odata2.processor.core.jpa.access.model.EdmTypeConvertor;
+import org.apache.olingo.odata2.processor.core.jpa.model.JPAEdmMappingImpl;
+
+public class JPAWriteRequest {
+ protected HashMap<String, HashMap<String, Method>> jpaEntityAccessMap = null;
+ protected HashMap<String, Object> jpaComplexObjectMap = null;
+ protected HashMap<String, HashMap<String, String>> jpaEmbeddableKeyMap = null;
+ protected HashMap<String, Class<?>> jpaEmbeddableKeyObjectMap = null;
+
+ public JPAWriteRequest() {
+ jpaEntityAccessMap = new HashMap<String, HashMap<String, Method>>();
+ jpaComplexObjectMap = new HashMap<String, Object>();
+ }
+
+ protected HashMap<String, Method> getSetters(final Object jpaEntity,
+ final EdmStructuralType structuralType, final boolean isCreate) throws ODataJPARuntimeException {
+
+ HashMap<String, Method> setters = new HashMap<String, Method>();
+ HashMap<String, String> embeddableKey = new HashMap<String, String>();
+ try {
+ for (String propertyName : structuralType.getPropertyNames()) {
+
+ EdmProperty property = (EdmProperty) structuralType
+ .getProperty(propertyName);
+ Class<?> propertyClass = null;
+ try {
+ if (property.getMapping() != null && ((JPAEdmMappingImpl) property.getMapping()).getJPAType() != null) {
+ propertyClass = ((JPAEdmMappingImpl) property.getMapping()).getJPAType();
+ if (property.getType().getKind().equals(EdmTypeKind.COMPLEX)) {
+ try {
+ if (((JPAEdmMappingImpl) property.getMapping()).getInternalName() != null) {
+ jpaComplexObjectMap.put(((JPAEdmMappingImpl) property.getMapping()).getInternalName(), propertyClass.newInstance());
+ } else {
+ jpaComplexObjectMap.put(propertyName, propertyClass.newInstance());
+ }
+ } catch (InstantiationException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (IllegalAccessException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ }
+ } else {
+ propertyClass = EdmTypeConvertor.convertToJavaType(property.getType());
+ }
+ } catch (ODataJPAModelException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+ String name = getSetterName(property);
+ String[] nameParts = name.split("\\.");
+ if (nameParts.length > 1) {
+ if (isCreate) {
+ jpaEmbeddableKeyObjectMap.put(propertyName, propertyClass);
+ embeddableKey.put(propertyName, name);
+ }
+ } else {
+ setters.put(
+ propertyName,
+ jpaEntity.getClass().getMethod(name, propertyClass));
+ }
+ }
+ } catch (NoSuchMethodException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (SecurityException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+
+ if (isCreate && !embeddableKey.isEmpty()) {
+ jpaEmbeddableKeyMap.put(jpaEntity.getClass().getName(),
+ embeddableKey);
+ }
+ return setters;
+ }
+
+ private String getSetterName(final EdmProperty property)
+ throws ODataJPARuntimeException {
+ EdmMapping mapping = null;
+ String name = null;
+ try {
+ mapping = property.getMapping();
+ if (mapping == null || mapping.getInternalName() == null) {
+ name = property.getName();
+ } else {
+ name = mapping.getInternalName();
+ }
+
+ } catch (EdmException e) {
+ throw ODataJPARuntimeException
+ .throwException(ODataJPARuntimeException.GENERAL
+ .addContent(e.getMessage()), e);
+ }
+
+ String[] nameParts = name.split("\\."); //$NON-NLS-1$
+ StringBuilder builder = new StringBuilder();
+
+ if (nameParts.length == 1) {
+ if (name != null) {
+ char c = Character.toUpperCase(name.charAt(0));
+
+ builder.append("set").append(c).append(name.substring(1)) //$NON-NLS-1$
+ .toString();
+ }
+ } else if (nameParts.length > 1) {
+
+ for (int i = 0; i < nameParts.length; i++) {
+ name = nameParts[i];
+ char c = Character.toUpperCase(name.charAt(0));
+ if (i == 0) {
+ builder.append("set").append(c).append(name.substring(1)); //$NON-NLS-1$
+ } else {
+ builder.append(".").append("set").append(c) //$NON-NLS-1$ //$NON-NLS-2$
+ .append(name.substring(1));
+ }
+ }
+ } else {
+ return null;
+ }
+
+ if (builder.length() > 0) {
+ return builder.toString();
+ } else {
+ return null;
+ }
+
+ }
+
+ protected ODataEntry parseEntry(final EdmEntitySet entitySet, final InputStream content, final String requestContentType, final boolean merge) throws ODataBadRequestException {
+ ODataEntry entryValues;
+ try {
+ EntityProviderReadProperties entityProviderProperties = EntityProviderReadProperties.init().mergeSemantic(merge).build();
+ entryValues = EntityProvider.readEntry(requestContentType, entitySet, content, entityProviderProperties);
+ } catch (EntityProviderException e) {
+ throw new ODataBadRequestException(ODataBadRequestException.BODY, e);
+ }
+ return entryValues;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java
----------------------------------------------------------------------
diff --git a/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java
new file mode 100644
index 0000000..edc3da9
--- /dev/null
+++ b/jpa-core/src/main/java/org/apache/olingo/odata2/processor/core/jpa/edm/ODataJPAEdmProvider.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * 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.processor.core.jpa.edm;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.processor.api.jpa.ODataJPAContext;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAException;
+import org.apache.olingo.odata2.processor.api.jpa.exception.ODataJPAModelException;
+import org.apache.olingo.odata2.processor.api.jpa.factory.ODataJPAFactory;
+import org.apache.olingo.odata2.processor.api.jpa.model.JPAEdmModelView;
+
+public class ODataJPAEdmProvider extends EdmProvider {
+
+ private ODataJPAContext oDataJPAContext;
+ private JPAEdmModelView jpaEdmModel;
+
+ private List<Schema> schemas;
+ private HashMap<String, EntityType> entityTypes;
+ private HashMap<String, EntityContainerInfo> entityContainerInfos;
+ private HashMap<String, ComplexType> complexTypes;
+ private HashMap<String, Association> associations;
+ private HashMap<String, FunctionImport> functionImports;
+
+ public ODataJPAEdmProvider() {
+ entityTypes = new HashMap<String, EntityType>();
+ entityContainerInfos = new HashMap<String, EntityContainerInfo>();
+ complexTypes = new HashMap<String, ComplexType>();
+ associations = new HashMap<String, Association>();
+ functionImports = new HashMap<String, FunctionImport>();
+ }
+
+ public ODataJPAEdmProvider(final ODataJPAContext oDataJPAContext) {
+ if (oDataJPAContext == null) {
+ throw new IllegalArgumentException(
+ ODataJPAException.ODATA_JPACTX_NULL);
+ }
+ entityTypes = new HashMap<String, EntityType>();
+ entityContainerInfos = new HashMap<String, EntityContainerInfo>();
+ complexTypes = new HashMap<String, ComplexType>();
+ associations = new HashMap<String, Association>();
+ functionImports = new HashMap<String, FunctionImport>();
+ jpaEdmModel = ODataJPAFactory.createFactory().getJPAAccessFactory()
+ .getJPAEdmModelView(oDataJPAContext);
+ }
+
+ public ODataJPAContext getODataJPAContext() {
+ return oDataJPAContext;
+ }
+
+ public void setODataJPAContext(final ODataJPAContext jpaContext) {
+ oDataJPAContext = jpaContext;
+ }
+
+ @Override
+ public EntityContainerInfo getEntityContainerInfo(final String name)
+ throws ODataException {
+
+ if (entityContainerInfos.containsKey(name)) {
+ return entityContainerInfos.get(name);
+ } else {
+
+ if (schemas == null) {
+ getSchemas();
+ }
+ List<EntityContainer> containerList = schemas.get(0).getEntityContainers();
+ if (containerList == null) return null;
+ for (EntityContainer container : containerList) {
+ if (name == null && container.isDefaultEntityContainer()) {
+ entityContainerInfos.put(name, container);
+ return container;
+ } else if (name != null && name.equals(container.getName())) {
+ return container;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public EntityType getEntityType(final FullQualifiedName edmFQName)
+ throws ODataException {
+
+ String strEdmFQName = edmFQName.toString();
+
+ if (edmFQName != null) {
+ if (entityTypes.containsKey(strEdmFQName)) {
+ return entityTypes.get(strEdmFQName);
+ } else if (schemas == null) {
+ getSchemas();
+ }
+
+ String entityTypeNamespace = edmFQName.getNamespace();
+ String entityTypeName = edmFQName.getName();
+
+ for (Schema schema : schemas) {
+ String schemaNamespace = schema.getNamespace();
+ if (schemaNamespace.equals(entityTypeNamespace)) {
+ if (schema.getEntityTypes() == null) return null;
+ for (EntityType et : schema.getEntityTypes()) {
+ if (et.getName().equals(entityTypeName)) {
+ entityTypes.put(strEdmFQName, et);
+ return et;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public ComplexType getComplexType(final FullQualifiedName edmFQName)
+ throws ODataException {
+
+ if (edmFQName != null) {
+ if (complexTypes.containsKey(edmFQName.toString())) {
+ return complexTypes.get(edmFQName.toString());
+ } else if (schemas == null) {
+ getSchemas();
+ }
+
+ for (Schema schema : schemas) {
+ if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+ if (schema.getComplexTypes() == null) return null;
+ for (ComplexType ct : schema.getComplexTypes()) {
+ if (ct.getName().equals(edmFQName.getName())) {
+ complexTypes.put(edmFQName.toString(), ct);
+ return ct;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Association getAssociation(final FullQualifiedName edmFQName)
+ throws ODataException {
+ if (edmFQName != null) {
+ if (associations.containsKey(edmFQName.toString())) {
+ return associations.get(edmFQName.toString());
+ } else if (schemas == null) {
+ getSchemas();
+ }
+
+ for (Schema schema : schemas) {
+ if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+ if (schema.getAssociations() == null) return null;
+ for (Association association : schema.getAssociations()) {
+ if (association.getName().equals(
+ edmFQName.getName())) {
+ associations.put(edmFQName.toString(),
+ association);
+ return association;
+ }
+ }
+ }
+ }
+
+ }
+ return null;
+ }
+
+ @Override
+ public EntitySet getEntitySet(final String entityContainer, final String name)
+ throws ODataException {
+
+ EntitySet returnedSet = null;
+ EntityContainer container = null;
+ if (!entityContainerInfos.containsKey(entityContainer)) {
+ container = (EntityContainer) getEntityContainerInfo(entityContainer);
+ } else {
+ container = (EntityContainer) entityContainerInfos
+ .get(entityContainer);
+ }
+
+ if (container != null && name != null) {
+ for (EntitySet es : container.getEntitySets()) {
+ if (name.equals(es.getName())) {
+ returnedSet = es;
+ break;
+ }
+ }
+ }
+
+ return returnedSet;
+ }
+
+ @Override
+ public AssociationSet getAssociationSet(final String entityContainer,
+ final FullQualifiedName association, final String sourceEntitySetName,
+ final String sourceEntitySetRole) throws ODataException {
+
+ EntityContainer container = null;
+ if (!entityContainerInfos.containsKey(entityContainer)) {
+ container = (EntityContainer) getEntityContainerInfo(entityContainer);
+ } else {
+ container = (EntityContainer) entityContainerInfos
+ .get(entityContainer);
+ }
+
+ if (container != null && association != null && container.getAssociationSets() != null) {
+ for (AssociationSet as : container.getAssociationSets()) {
+ if (association.equals(as.getAssociation())) {
+ AssociationSetEnd end = as.getEnd1();
+ if (sourceEntitySetName.equals(end.getEntitySet())
+ && sourceEntitySetRole.equals(end.getRole())) {
+ return as;
+ } else {
+ end = as.getEnd2();
+ if (sourceEntitySetName.equals(end.getEntitySet())
+ && sourceEntitySetRole.equals(end.getRole())) {
+ return as;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public FunctionImport getFunctionImport(final String entityContainer, final String name)
+ throws ODataException {
+
+ if (functionImports.containsKey(name)) {
+ return functionImports.get(name);
+ }
+
+ EntityContainer container = null;
+ if (!entityContainerInfos.containsKey(entityContainer)) {
+ container = (EntityContainer) getEntityContainerInfo(entityContainer);
+ } else {
+ container = (EntityContainer) entityContainerInfos
+ .get(entityContainer);
+ }
+
+ if (container != null && name != null) {
+ if (container.getFunctionImports() == null) return null;
+ for (FunctionImport fi : container.getFunctionImports()) {
+ if (name.equals(fi.getName())) {
+ functionImports.put(name, fi);
+ return fi;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<Schema> getSchemas() throws ODataException {
+ if (schemas == null && jpaEdmModel != null) {
+ jpaEdmModel.getBuilder().build();
+ schemas = new ArrayList<Schema>();
+ schemas.add(jpaEdmModel.getEdmSchemaView().getEdmSchema());
+ }
+ if (jpaEdmModel == null) {
+
+ throw ODataJPAModelException.throwException(
+ ODataJPAModelException.BUILDER_NULL, null);
+ }
+
+ return schemas;
+
+ }
+
+}