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:25 UTC
[20/51] [partial] initial commit
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParser.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParser.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParser.java
new file mode 100644
index 0000000..8e3e3dd
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParser.java
@@ -0,0 +1,965 @@
+/*******************************************************************************
+ * 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.core.edm.parser;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmAction;
+import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
+import org.apache.olingo.odata2.api.edm.EdmContentKind;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+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.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.CustomizableFeedMappings;
+import org.apache.olingo.odata2.api.edm.provider.DataServices;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+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.Facets;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImportParameter;
+import org.apache.olingo.odata2.api.edm.provider.Key;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.OnDelete;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
+import org.apache.olingo.odata2.api.edm.provider.ReferentialConstraint;
+import org.apache.olingo.odata2.api.edm.provider.ReferentialConstraintRole;
+import org.apache.olingo.odata2.api.edm.provider.ReturnType;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.api.edm.provider.Using;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import java.util.HashSet;
+import java.util.Set;
+
+public class EdmParser {
+
+ private Map<String, Set<String>> inscopeMap = new HashMap<String, Set<String>>();
+ private Map<String, String> aliasNamespaceMap = new HashMap<String, String>();
+ private Map<String, String> xmlNamespaceMap;
+ private Map<String, String> mandatoryNamespaces;
+ private Map<FullQualifiedName, EntityType> entityTypesMap = new HashMap<FullQualifiedName, EntityType>();
+ private Map<FullQualifiedName, ComplexType> complexTypesMap = new HashMap<FullQualifiedName, ComplexType>();
+ private Map<FullQualifiedName, Association> associationsMap = new HashMap<FullQualifiedName, Association>();
+ private Map<FullQualifiedName, EntityContainer> containerMap = new HashMap<FullQualifiedName, EntityContainer>();
+ private List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
+ private String currentHandledStartTagName;
+ private String currentNamespace;
+ private final String DEFAULT_NAMESPACE = "";
+
+ public DataServices readMetadata(final XMLStreamReader reader, final boolean validate)
+ throws EntityProviderException {
+ try {
+ initialize();
+ DataServices dataServices = new DataServices();
+ List<Schema> schemas = new ArrayList<Schema>();
+
+ while (reader.hasNext()
+ && !(reader.isEndElement() && Edm.NAMESPACE_EDMX_2007_06.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_DATA_SERVICES.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ if (EdmParserConstants.EDM_SCHEMA.equals(reader.getLocalName())) {
+ schemas.add(readSchema(reader));
+ } else if (EdmParserConstants.EDM_DATA_SERVICES.equals(reader
+ .getLocalName())) {
+ dataServices.setDataServiceVersion(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, "DataServiceVersion"));
+ }
+ }
+ }
+ if (validate) {
+ validate();
+ }
+ dataServices.setSchemas(schemas);
+ reader.close();
+ return dataServices;
+ } catch (XMLStreamException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass().getSimpleName()), e);
+ }
+
+ }
+
+ private Schema readSchema(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_SCHEMA);
+
+ Schema schema = new Schema();
+ List<Using> usings = new ArrayList<Using>();
+ List<ComplexType> complexTypes = new ArrayList<ComplexType>();
+ List<EntityType> entityTypes = new ArrayList<EntityType>();
+ List<Association> associations = new ArrayList<Association>();
+ List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+ schema.setNamespace(reader.getAttributeValue(null, EdmParserConstants.EDM_SCHEMA_NAMESPACE));
+ this.inscopeMap.put(schema.getNamespace(), new HashSet<String>());
+ schema.setAlias(reader.getAttributeValue(null, EdmParserConstants.EDM_SCHEMA_ALIAS));
+ schema.setAnnotationAttributes(readAnnotationAttribute(reader));
+ currentNamespace = schema.getNamespace();
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_SCHEMA.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_USING.equals(currentHandledStartTagName)) {
+ usings.add(readUsing(reader, schema.getNamespace()));
+ } else if (EdmParserConstants.EDM_ENTITY_TYPE.equals(currentHandledStartTagName)) {
+ entityTypes.add(readEntityType(reader));
+ } else if (EdmParserConstants.EDM_COMPLEX_TYPE.equals(currentHandledStartTagName)) {
+ complexTypes.add(readComplexType(reader));
+ } else if (EdmParserConstants.EDM_ASSOCIATION.equals(currentHandledStartTagName)) {
+ associations.add(readAssociation(reader));
+ } else if (EdmParserConstants.EDM_ENTITY_CONTAINER.equals(currentHandledStartTagName)) {
+ entityContainers.add(readEntityContainer(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (schema.getAlias() != null) {
+ aliasNamespaceMap.put(schema.getAlias(), schema.getNamespace());
+ }
+ schema.setUsings(usings).setEntityTypes(entityTypes).setComplexTypes(complexTypes).setAssociations(associations).setEntityContainers(entityContainers).setAnnotationElements(annotationElements);
+ return schema;
+ }
+
+ private Using readUsing(final XMLStreamReader reader, final String schemaNamespace)
+ throws XMLStreamException, EntityProviderException {
+
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_USING);
+
+ Using using = new Using();
+ using.setNamespace(reader.getAttributeValue(null, EdmParserConstants.EDM_SCHEMA_NAMESPACE));
+ this.inscopeMap.get(schemaNamespace).add(using.getNamespace());
+ using.setAlias(reader.getAttributeValue(null, EdmParserConstants.EDM_SCHEMA_ALIAS));
+ using.setAnnotationAttributes(readAnnotationAttribute(reader));
+
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI())
+ && EdmParserConstants.EDM_USING.equals(reader.getLocalName()))) {
+
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ using.setAnnotationElements(annotationElements);
+
+ if (using.getAlias() != null) {
+ aliasNamespaceMap.put(using.getAlias(), using.getNamespace());
+ }
+
+ return using;
+ }
+
+ private EntityContainer readEntityContainer(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ENTITY_CONTAINER);
+ EntityContainer container = new EntityContainer();
+ List<EntitySet> entitySets = new ArrayList<EntitySet>();
+ List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
+ List<FunctionImport> functionImports = new ArrayList<FunctionImport>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+ container.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ if (reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, "IsDefaultEntityContainer") != null) {
+ container.setDefaultEntityContainer("true".equalsIgnoreCase(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, "IsDefaultEntityContainer")));
+ }
+ container.setExtendz(reader.getAttributeValue(null, EdmParserConstants.EDM_CONTAINER_EXTENDZ));
+ container.setAnnotationAttributes(readAnnotationAttribute(reader));
+
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ENTITY_CONTAINER.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_ENTITY_SET.equals(currentHandledStartTagName)) {
+ entitySets.add(readEntitySet(reader));
+ } else if (EdmParserConstants.EDM_ASSOCIATION_SET.equals(currentHandledStartTagName)) {
+ associationSets.add(readAssociationSet(reader));
+ } else if (EdmParserConstants.EDM_FUNCTION_IMPORT.equals(currentHandledStartTagName)) {
+ functionImports.add(readFunctionImport(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ container.setEntitySets(entitySets).setAssociationSets(associationSets).setFunctionImports(functionImports).setAnnotationElements(annotationElements);
+
+ containerMap.put(new FullQualifiedName(currentNamespace, container.getName()), container);
+ return container;
+ }
+
+ private FunctionImport readFunctionImport(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_FUNCTION_IMPORT);
+ FunctionImport function = new FunctionImport();
+ List<FunctionImportParameter> functionParameters = new ArrayList<FunctionImportParameter>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+ function.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ function.setHttpMethod(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.EDM_FUNCTION_IMPORT_HTTP_METHOD));
+ function.setEntitySet(reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_SET));
+ ReturnType returnType = new ReturnType();
+ String returnTypeString = reader.getAttributeValue(null, EdmParserConstants.EDM_FUNCTION_IMPORT_RETURN);
+ if (returnTypeString != null) {
+ if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) {
+ returnType.setMultiplicity(EdmMultiplicity.MANY);
+ returnTypeString = returnTypeString.substring(returnTypeString.indexOf("(") + 1, returnTypeString.length() - 1);
+ if (function.getEntitySet() == null) {
+ // throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("EntitySet");
+ }
+ }
+ FullQualifiedName fqName = extractFQName(returnTypeString);
+ returnType.setTypeName(fqName);
+ function.setReturnType(returnType);
+ }
+ function.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_FUNCTION_IMPORT.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_FUNCTION_PARAMETER.equals(currentHandledStartTagName)) {
+ functionParameters.add(readFunctionImportParameter(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ function.setParameters(functionParameters).setAnnotationElements(annotationElements);
+ return function;
+ }
+
+ private FunctionImportParameter readFunctionImportParameter(final XMLStreamReader reader) throws EntityProviderException, XMLStreamException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_FUNCTION_PARAMETER);
+ FunctionImportParameter functionParameter = new FunctionImportParameter();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+ functionParameter.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ String type = reader.getAttributeValue(null, EdmParserConstants.EDM_TYPE);
+ if (type == null) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+ .addContent(EdmParserConstants.EDM_TYPE).addContent(EdmParserConstants.EDM_FUNCTION_PARAMETER));
+ }
+ functionParameter.setType(EdmSimpleTypeKind.valueOf(extractFQName(type).getName()));
+ functionParameter.setFacets(readFacets(reader));
+ functionParameter.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_FUNCTION_IMPORT.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ functionParameter.setAnnotationElements(annotationElements);
+ return functionParameter;
+ }
+
+ private AssociationSet readAssociationSet(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ASSOCIATION_SET);
+ AssociationSet associationSet = new AssociationSet();
+ List<AssociationSetEnd> ends = new ArrayList<AssociationSetEnd>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+
+ associationSet.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ String association = reader.getAttributeValue(null, EdmParserConstants.EDM_ASSOCIATION);
+ if (association != null) {
+ associationSet.setAssociation(extractFQName(association));
+ } else {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+ .addContent(EdmParserConstants.EDM_ASSOCIATION).addContent(EdmParserConstants.EDM_ASSOCIATION_SET));
+ }
+ associationSet.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ASSOCIATION_SET.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_ASSOCIATION_END.equals(currentHandledStartTagName)) {
+ AssociationSetEnd associationSetEnd = new AssociationSetEnd();
+ associationSetEnd.setEntitySet(reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_SET));
+ associationSetEnd.setRole(reader.getAttributeValue(null, EdmParserConstants.EDM_ROLE));
+ ends.add(associationSetEnd);
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (ends.size() != 2) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Count of AssociationSet ends should be 2"));
+ } else {
+ associationSet.setEnd1(ends.get(0)).setEnd2(ends.get(1));
+ }
+ associationSet.setAnnotationElements(annotationElements);
+ return associationSet;
+ }
+
+ private EntitySet readEntitySet(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ENTITY_SET);
+ EntitySet entitySet = new EntitySet();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ entitySet.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ String entityType = reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_TYPE);
+ if (entityType != null) {
+ FullQualifiedName fqName = extractFQName(entityType);
+ entitySet.setEntityType(fqName);
+ } else {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+ .addContent(EdmParserConstants.EDM_ENTITY_TYPE).addContent(EdmParserConstants.EDM_ENTITY_SET));
+ }
+ entitySet.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ENTITY_SET.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ entitySet.setAnnotationElements(annotationElements);
+ return entitySet;
+ }
+
+ private Association readAssociation(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ASSOCIATION);
+
+ Association association = new Association();
+ association.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ List<AssociationEnd> associationEnds = new ArrayList<AssociationEnd>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ association.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ASSOCIATION.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_ASSOCIATION_END.equals(currentHandledStartTagName)) {
+ associationEnds.add(readAssociationEnd(reader));
+ } else if (EdmParserConstants.EDM_ASSOCIATION_CONSTRAINT.equals(currentHandledStartTagName)) {
+ association.setReferentialConstraint(readReferentialConstraint(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (associationEnds.size() < 2 && associationEnds.size() > 2) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Count of association ends should be 2"));
+ }
+
+ association.setEnd1(associationEnds.get(0)).setEnd2(associationEnds.get(1)).setAnnotationElements(annotationElements);
+ associationsMap.put(new FullQualifiedName(currentNamespace, association.getName()), association);
+ return association;
+ }
+
+ private ReferentialConstraint readReferentialConstraint(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ASSOCIATION_CONSTRAINT);
+ ReferentialConstraint refConstraint = new ReferentialConstraint();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ refConstraint.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ASSOCIATION_CONSTRAINT.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_ASSOCIATION_PRINCIPAL.equals(currentHandledStartTagName)) {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ASSOCIATION_PRINCIPAL);
+ refConstraint.setPrincipal(readReferentialConstraintRole(reader));
+ } else if (EdmParserConstants.EDM_ASSOCIATION_DEPENDENT.equals(currentHandledStartTagName)) {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ASSOCIATION_DEPENDENT);
+ refConstraint.setDependent(readReferentialConstraintRole(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ refConstraint.setAnnotationElements(annotationElements);
+ return refConstraint;
+ }
+
+ private ReferentialConstraintRole readReferentialConstraintRole(final XMLStreamReader reader) throws EntityProviderException, XMLStreamException {
+ ReferentialConstraintRole rcRole = new ReferentialConstraintRole();
+ rcRole.setRole(reader.getAttributeValue(null, EdmParserConstants.EDM_ROLE));
+ List<PropertyRef> propertyRefs = new ArrayList<PropertyRef>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ rcRole.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI())
+ && (EdmParserConstants.EDM_ASSOCIATION_PRINCIPAL.equals(reader.getLocalName()) || EdmParserConstants.EDM_ASSOCIATION_DEPENDENT.equals(reader.getLocalName())))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_PROPERTY_REF.equals(currentHandledStartTagName)) {
+ propertyRefs.add(readPropertyRef(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ rcRole.setPropertyRefs(propertyRefs).setAnnotationElements(annotationElements);
+ return rcRole;
+ }
+
+ private ComplexType readComplexType(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_COMPLEX_TYPE);
+
+ ComplexType complexType = new ComplexType();
+ List<Property> properties = new ArrayList<Property>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ complexType.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ String baseType = reader.getAttributeValue(null, EdmParserConstants.EDM_BASE_TYPE);
+ if (baseType != null) {
+ complexType.setBaseType(extractFQName(baseType));
+ }
+ if (reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_TYPE_ABSTRACT) != null) {
+ complexType.setAbstract("true".equalsIgnoreCase(reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_TYPE_ABSTRACT)));
+ }
+ complexType.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_COMPLEX_TYPE.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_PROPERTY.equals(currentHandledStartTagName)) {
+ properties.add(readProperty(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ complexType.setProperties(properties).setAnnotationElements(annotationElements);
+ if (complexType.getName() != null) {
+ FullQualifiedName fqName = new FullQualifiedName(currentNamespace, complexType.getName());
+ complexTypesMap.put(fqName, complexType);
+ } else {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("Name"));
+ }
+ return complexType;
+
+ }
+
+ private EntityType readEntityType(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ENTITY_TYPE);
+ EntityType entityType = new EntityType();
+ List<Property> properties = new ArrayList<Property>();
+ List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ Key key = null;
+
+ entityType.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ String hasStream = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_ENTITY_TYPE_HAS_STREAM);
+ if (hasStream != null) {
+ entityType.setHasStream("true".equalsIgnoreCase(hasStream));
+ }
+
+ if (reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_TYPE_ABSTRACT) != null) {
+ entityType.setAbstract("true".equalsIgnoreCase(reader.getAttributeValue(null, EdmParserConstants.EDM_ENTITY_TYPE_ABSTRACT)));
+ }
+ String baseType = reader.getAttributeValue(null, EdmParserConstants.EDM_BASE_TYPE);
+ if (baseType != null) {
+ entityType.setBaseType(extractFQName(baseType));
+ }
+ entityType.setCustomizableFeedMappings(readCustomizableFeedMappings(reader));
+ entityType.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ENTITY_TYPE.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_ENTITY_TYPE_KEY.equals(currentHandledStartTagName)) {
+ key = readEntityTypeKey(reader);
+ } else if (EdmParserConstants.EDM_PROPERTY.equals(currentHandledStartTagName)) {
+ properties.add(readProperty(reader));
+ } else if (EdmParserConstants.EDM_NAVIGATION_PROPERTY.equals(currentHandledStartTagName)) {
+ navProperties.add(readNavigationProperty(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ extractNamespaces(reader);
+ }
+ }
+ entityType.setKey(key).setProperties(properties).setNavigationProperties(navProperties).setAnnotationElements(annotationElements);
+ if (entityType.getName() != null) {
+ FullQualifiedName fqName = new FullQualifiedName(currentNamespace, entityType.getName());
+ entityTypesMap.put(fqName, entityType);
+ } else {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("Name"));
+ }
+ return entityType;
+ }
+
+ private Key readEntityTypeKey(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ENTITY_TYPE_KEY);
+ List<PropertyRef> keys = new ArrayList<PropertyRef>();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ List<AnnotationAttribute> annotationAttributes = readAnnotationAttribute(reader);
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ENTITY_TYPE_KEY.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_PROPERTY_REF.equals(currentHandledStartTagName)) {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_PROPERTY_REF);
+ keys.add(readPropertyRef(reader));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ return new Key().setKeys(keys).setAnnotationElements(annotationElements).setAnnotationAttributes(annotationAttributes);
+ }
+
+ private PropertyRef readPropertyRef(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_PROPERTY_REF);
+ PropertyRef propertyRef = new PropertyRef();
+ propertyRef.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ propertyRef.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_PROPERTY_REF.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ return propertyRef.setAnnotationElements(annotationElements);
+ }
+
+ private NavigationProperty readNavigationProperty(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_NAVIGATION_PROPERTY);
+
+ NavigationProperty navProperty = new NavigationProperty();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ navProperty.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ String relationship = reader.getAttributeValue(null, EdmParserConstants.EDM_NAVIGATION_RELATIONSHIP);
+ if (relationship != null) {
+ FullQualifiedName fqName = extractFQName(relationship);
+ navProperty.setRelationship(fqName);
+
+ } else {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+ .addContent(EdmParserConstants.EDM_NAVIGATION_RELATIONSHIP).addContent(EdmParserConstants.EDM_NAVIGATION_PROPERTY));
+ }
+
+ navProperty.setFromRole(reader.getAttributeValue(null, EdmParserConstants.EDM_NAVIGATION_FROM_ROLE));
+ navProperty.setToRole(reader.getAttributeValue(null, EdmParserConstants.EDM_NAVIGATION_TO_ROLE));
+ navProperty.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_NAVIGATION_PROPERTY.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ navProperty.setAnnotationElements(annotationElements);
+ navProperties.add(navProperty);
+ return navProperty;
+ }
+
+ private Property readProperty(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_PROPERTY);
+ Property property;
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ String type = reader.getAttributeValue(null, EdmParserConstants.EDM_TYPE);
+ if (type == null) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+ .addContent(EdmParserConstants.EDM_TYPE).addContent(EdmParserConstants.EDM_PROPERTY));
+ }
+ FullQualifiedName fqName = extractFQName(type);
+
+ if (EdmSimpleType.EDM_NAMESPACE.equals(fqName.getNamespace())) {
+ property = readSimpleProperty(reader, fqName);
+ } else {
+ property = readComplexProperty(reader, fqName);
+ }
+ property.setFacets(readFacets(reader));
+ property.setCustomizableFeedMappings(readCustomizableFeedMappings(reader));
+ property.setMimeType(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_MIMETYPE));
+ property.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_PROPERTY.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ property.setAnnotationElements(annotationElements);
+ return property;
+ }
+
+ private Property readComplexProperty(final XMLStreamReader reader, final FullQualifiedName fqName) throws XMLStreamException {
+ ComplexProperty property = new ComplexProperty();
+ property.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ property.setType(fqName);
+ return property;
+ }
+
+ private Property readSimpleProperty(final XMLStreamReader reader, final FullQualifiedName fqName) throws XMLStreamException {
+ SimpleProperty property = new SimpleProperty();
+ property.setName(reader.getAttributeValue(null, EdmParserConstants.EDM_NAME));
+ property.setType(EdmSimpleTypeKind.valueOf(fqName.getName()));
+ return property;
+ }
+
+ private Facets readFacets(final XMLStreamReader reader) throws XMLStreamException {
+ String isNullable = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_NULLABLE);
+ String maxLength = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_MAX_LENGTH);
+ String precision = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_PRECISION);
+ String scale = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_SCALE);
+ String isFixedLength = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_FIXED_LENGTH);
+ String isUnicode = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_UNICODE);
+ String concurrencyMode = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_CONCURRENCY_MODE);
+ String defaultValue = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_DEFAULT_VALUE);
+ String collation = reader.getAttributeValue(null, EdmParserConstants.EDM_PROPERTY_COLLATION);
+ if (isNullable != null || maxLength != null || precision != null || scale != null || isFixedLength != null || isUnicode != null
+ || concurrencyMode != null || defaultValue != null || collation != null) {
+ Facets facets = new Facets();
+ if (isNullable != null) {
+ facets.setNullable("true".equalsIgnoreCase(isNullable));
+ }
+ if (maxLength != null) {
+ if (EdmParserConstants.EDM_PROPERTY_MAX_LENGTH_MAX_VALUE.equals(maxLength)) {
+ facets.setMaxLength(Integer.MAX_VALUE);
+ } else {
+ facets.setMaxLength(Integer.parseInt(maxLength));
+ }
+ }
+ if (precision != null) {
+ facets.setPrecision(Integer.parseInt(precision));
+ }
+ if (scale != null) {
+ facets.setScale(Integer.parseInt(scale));
+ }
+ if (isFixedLength != null) {
+ facets.setFixedLength("true".equalsIgnoreCase(isFixedLength));
+ }
+ if (isUnicode != null) {
+ facets.setUnicode("true".equalsIgnoreCase(isUnicode));
+ }
+ for (int i = 0; i < EdmConcurrencyMode.values().length; i++) {
+ if (EdmConcurrencyMode.values()[i].name().equalsIgnoreCase(concurrencyMode)) {
+ facets.setConcurrencyMode(EdmConcurrencyMode.values()[i]);
+ }
+ }
+ facets.setDefaultValue(defaultValue);
+ facets.setCollation(collation);
+ return facets;
+ } else {
+ return null;
+ }
+ }
+
+ private CustomizableFeedMappings readCustomizableFeedMappings(final XMLStreamReader reader) {
+ String targetPath = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_FC_TARGET_PATH);
+ String sourcePath = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_FC_SOURCE_PATH);
+ String nsUri = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_FC_NS_URI);
+ String nsPrefix = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_FC_PREFIX);
+ String keepInContent = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_FC_KEEP_IN_CONTENT);
+ String contentKind = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, EdmParserConstants.M_FC_CONTENT_KIND);
+
+ if (targetPath != null || sourcePath != null || nsUri != null || nsPrefix != null || keepInContent != null || contentKind != null) {
+ CustomizableFeedMappings feedMapping = new CustomizableFeedMappings();
+ if (keepInContent != null) {
+ feedMapping.setFcKeepInContent("true".equals(keepInContent));
+ }
+ for (int i = 0; i < EdmContentKind.values().length; i++) {
+ if (EdmContentKind.values()[i].name().equalsIgnoreCase(contentKind)) {
+ feedMapping.setFcContentKind(EdmContentKind.values()[i]);
+ }
+ }
+ feedMapping.setFcTargetPath(targetPath).setFcSourcePath(sourcePath).setFcNsUri(nsUri).setFcNsPrefix(nsPrefix);
+ return feedMapping;
+ } else {
+ return null;
+ }
+
+ }
+
+ private AssociationEnd readAssociationEnd(final XMLStreamReader reader) throws EntityProviderException, XMLStreamException {
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_EDM_2008_09, EdmParserConstants.EDM_ASSOCIATION_END);
+
+ AssociationEnd associationEnd = new AssociationEnd();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ associationEnd.setRole(reader.getAttributeValue(null, EdmParserConstants.EDM_ROLE));
+ associationEnd.setMultiplicity(EdmMultiplicity.fromLiteral(reader.getAttributeValue(null, EdmParserConstants.EDM_ASSOCIATION_MULTIPLICITY)));
+ String type = reader.getAttributeValue(null, EdmParserConstants.EDM_TYPE);
+ if (type == null) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+ .addContent(EdmParserConstants.EDM_TYPE).addContent(EdmParserConstants.EDM_ASSOCIATION_END));
+ }
+ associationEnd.setType(extractFQName(type));
+ associationEnd.setAnnotationAttributes(readAnnotationAttribute(reader));
+ while (reader.hasNext() && !(reader.isEndElement() && Edm.NAMESPACE_EDM_2008_09.equals(reader.getNamespaceURI()) && EdmParserConstants.EDM_ASSOCIATION_END.equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ extractNamespaces(reader);
+ currentHandledStartTagName = reader.getLocalName();
+ if (EdmParserConstants.EDM_ASSOCIATION_ONDELETE.equals(currentHandledStartTagName)) {
+ OnDelete onDelete = new OnDelete();
+ for (int i = 0; i < EdmAction.values().length; i++) {
+ if (EdmAction.values()[i].name().equalsIgnoreCase(reader.getAttributeValue(null, EdmParserConstants.EDM_ONDELETE_ACTION))) {
+ onDelete.setAction(EdmAction.values()[i]);
+ }
+ }
+ associationEnd.setOnDelete(onDelete);
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ associationEnd.setAnnotationElements(annotationElements);
+ return associationEnd;
+ }
+
+ private AnnotationElement readAnnotationElement(final XMLStreamReader reader) throws XMLStreamException {
+ AnnotationElement aElement = new AnnotationElement();
+ List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>();
+ List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
+ aElement.setName(reader.getLocalName());
+ String elementNamespace = reader.getNamespaceURI();
+ if (!Edm.NAMESPACE_EDM_2008_09.equals(elementNamespace)) {
+ aElement.setPrefix(reader.getPrefix());
+ aElement.setNamespace(elementNamespace);
+ }
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ AnnotationAttribute annotationAttribute = new AnnotationAttribute();
+ annotationAttribute.setText(reader.getAttributeValue(i));
+ annotationAttribute.setName(reader.getAttributeLocalName(i));
+ annotationAttribute.setPrefix(reader.getAttributePrefix(i));
+ String namespace = reader.getAttributeNamespace(i);
+ if (!DEFAULT_NAMESPACE.equals(namespace)) {
+ annotationAttribute.setNamespace(namespace);
+ }
+ annotationAttributes.add(annotationAttribute);
+ }
+ aElement.setAttributes(annotationAttributes);
+ while (reader.hasNext() && !(reader.isEndElement() && aElement.getName() != null && aElement.getName().equals(reader.getLocalName()))) {
+ reader.next();
+ if (reader.isStartElement()) {
+ annotationElements.add(readAnnotationElement(reader));
+ } else if (reader.isCharacters()) {
+ aElement.setText(reader.getText());
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ aElement.setChildElements(annotationElements);
+ }
+ return aElement;
+ }
+
+ private List<AnnotationAttribute> readAnnotationAttribute(final XMLStreamReader reader) {
+ List<AnnotationAttribute> annotationAttributes = new ArrayList<AnnotationAttribute>();
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ if (!mandatoryNamespaces.containsValue(reader.getAttributeNamespace(i)) && !DEFAULT_NAMESPACE.equals(reader.getAttributeNamespace(i))) {
+ annotationAttributes.add(new AnnotationAttribute().setName(reader.getAttributeLocalName(i)).
+ setPrefix(reader.getAttributePrefix(i)).setNamespace(reader.getAttributeNamespace(i)).setText(reader.getAttributeValue(i)));
+ }
+ }
+ if (annotationAttributes.isEmpty()) {
+ return null;
+ }
+ return annotationAttributes;
+ }
+
+ private void checkAllMandatoryNamespacesAvailable() throws EntityProviderException {
+ if (!xmlNamespaceMap.containsValue(Edm.NAMESPACE_EDMX_2007_06)) {
+ throw new EntityProviderException(EntityProviderException.INVALID_NAMESPACE.addContent(Edm.NAMESPACE_EDMX_2007_06));
+ } else if (!xmlNamespaceMap.containsValue(Edm.NAMESPACE_M_2007_08)) {
+ throw new EntityProviderException(EntityProviderException.INVALID_NAMESPACE.addContent(Edm.NAMESPACE_EDMX_2007_06));
+ } else if (!xmlNamespaceMap.containsValue(Edm.NAMESPACE_EDM_2008_09)) {
+ throw new EntityProviderException(EntityProviderException.INVALID_NAMESPACE.addContent(Edm.NAMESPACE_EDMX_2007_06));
+ }
+ }
+
+ private void extractNamespaces(final XMLStreamReader reader) throws EntityProviderException {
+ int namespaceCount = reader.getNamespaceCount();
+ for (int i = 0; i < namespaceCount; i++) {
+ String namespacePrefix = reader.getNamespacePrefix(i);
+ String namespaceUri = reader.getNamespaceURI(i);
+ if (namespacePrefix == null || DEFAULT_NAMESPACE.equals(namespacePrefix)) {
+ namespacePrefix = Edm.PREFIX_EDM;
+ }
+ xmlNamespaceMap.put(namespacePrefix, namespaceUri);
+ }
+ }
+
+ private FullQualifiedName extractFQName(final String name)
+ throws EntityProviderException {
+ // Looking for the last dot
+ String[] names = name.split("\\" + Edm.DELIMITER + "(?=[^\\" + Edm.DELIMITER + "]+$)");
+ if (names.length != 2) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Attribute should specify a namespace qualified name or an alias qualified name"));
+ } else {
+ return new FullQualifiedName(names[0], names[1]);
+ }
+ }
+
+ private FullQualifiedName validateEntityTypeWithAlias(final FullQualifiedName aliasName) throws EntityProviderException {
+ String namespace = aliasNamespaceMap.get(aliasName.getNamespace());
+ FullQualifiedName fqName = new FullQualifiedName(namespace, aliasName.getName());
+ if (!entityTypesMap.containsKey(fqName)) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid Type"));
+ }
+ return fqName;
+ }
+
+ private void validateEntityTypes() throws EntityProviderException {
+ for (Map.Entry<FullQualifiedName, EntityType> entityTypes : entityTypesMap.entrySet()) {
+ if (entityTypes.getValue() != null && entityTypes.getKey() != null) {
+ EntityType entityType = entityTypes.getValue();
+ if (entityType.getBaseType() != null) {
+ FullQualifiedName baseTypeFQName = entityType.getBaseType();
+ EntityType baseEntityType;
+ if (!entityTypesMap.containsKey(baseTypeFQName)) {
+ FullQualifiedName fqName = validateEntityTypeWithAlias(baseTypeFQName);
+ baseEntityType = entityTypesMap.get(fqName);
+ } else {
+ baseEntityType = entityTypesMap.get(baseTypeFQName);
+ }
+ if (baseEntityType.getKey() == null) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Missing key for EntityType " + baseEntityType.getName()));
+ }
+ } else if (entityType.getKey() == null) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Missing key for EntityType " + entityType.getName()));
+ }
+ }
+ }
+ }
+
+ private FullQualifiedName validateComplexTypeWithAlias(final FullQualifiedName aliasName) throws EntityProviderException {
+ String namespace = aliasNamespaceMap.get(aliasName.getNamespace());
+ FullQualifiedName fqName = new FullQualifiedName(namespace, aliasName.getName());
+ if (!complexTypesMap.containsKey(fqName)) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid BaseType").addContent(fqName));
+ }
+ return fqName;
+ }
+
+ private void validateComplexTypes() throws EntityProviderException {
+ for (Map.Entry<FullQualifiedName, ComplexType> complexTypes : complexTypesMap.entrySet()) {
+ if (complexTypes.getValue() != null && complexTypes.getKey() != null) {
+ ComplexType complexType = complexTypes.getValue();
+ if (complexType.getBaseType() != null) {
+ FullQualifiedName baseTypeFQName = complexType.getBaseType();
+ if (!complexTypesMap.containsKey(baseTypeFQName)) {
+ validateComplexTypeWithAlias(baseTypeFQName);
+ }
+ }
+ }
+ }
+ }
+
+ private void validateRelationship() throws EntityProviderException {
+ for (NavigationProperty navProperty : navProperties) {
+ if (associationsMap.containsKey(navProperty.getRelationship())) {
+ Association assoc = associationsMap.get(navProperty.getRelationship());
+ if (!(assoc.getEnd1().getRole().equals(navProperty.getFromRole()) ^ assoc.getEnd1().getRole().equals(navProperty.getToRole())
+ && (assoc.getEnd2().getRole().equals(navProperty.getFromRole()) ^ assoc.getEnd2().getRole().equals(navProperty.getToRole())))) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid end of association"));
+ }
+ if (!entityTypesMap.containsKey(assoc.getEnd1().getType())) {
+ validateEntityTypeWithAlias(assoc.getEnd1().getType());
+ }
+ if (!entityTypesMap.containsKey(assoc.getEnd2().getType())) {
+ validateEntityTypeWithAlias(assoc.getEnd2().getType());
+ }
+ } else {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid Relationship"));
+ }
+ }
+
+ }
+
+ private void validateAssociation() throws EntityProviderException {
+ for (Map.Entry<FullQualifiedName, EntityContainer> container : containerMap.entrySet()) {
+ for (AssociationSet associationSet : container.getValue().getAssociationSets()) {
+ FullQualifiedName association = associationSet.getAssociation();
+ if (associationsMap.containsKey(association)) {
+ validateAssociationEnd(associationSet.getEnd1(), associationsMap.get(association));
+ validateAssociationEnd(associationSet.getEnd2(), associationsMap.get(association));
+ boolean end1 = false;
+ boolean end2 = false;
+ for (EntitySet entitySet : container.getValue().getEntitySets()) {
+ if (entitySet.getName().equals(associationSet.getEnd1().getEntitySet())) {
+ end1 = true;
+ }
+ if (entitySet.getName().equals(associationSet.getEnd2().getEntitySet())) {
+ end2 = true;
+ }
+ }
+ if (!(end1 && end2)) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid AssociationSet"));
+ }
+ } else {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid AssociationSet"));
+ }
+ }
+ }
+
+ }
+
+ private void validateAssociationEnd(final AssociationSetEnd end, final Association association) throws EntityProviderException {
+ if (!(association.getEnd1().getRole().equals(end.getRole()) ^ association.getEnd2().getRole().equals(end.getRole()))) {
+ throw new EntityProviderException(EntityProviderException.COMMON.addContent("Invalid Association"));
+ }
+ }
+
+ private void validateEntitySet() throws EntityProviderException {
+ for (Map.Entry<FullQualifiedName, EntityContainer> container : containerMap.entrySet()) {
+ for (EntitySet entitySet : container.getValue().getEntitySets()) {
+ FullQualifiedName entityType = entitySet.getEntityType();
+ if (!(entityTypesMap.containsKey(entityType))) {
+ validateEntityTypeWithAlias(entityType);
+ }
+ }
+ }
+ }
+
+ private void validate() throws EntityProviderException {
+ checkAllMandatoryNamespacesAvailable();
+ validateEntityTypes();
+ validateComplexTypes();
+ validateRelationship();
+ validateEntitySet();
+ validateAssociation();
+ }
+
+ private void initialize() {
+ xmlNamespaceMap = new HashMap<String, String>();
+ mandatoryNamespaces = new HashMap<String, String>();
+ mandatoryNamespaces.put(Edm.PREFIX_EDMX, Edm.NAMESPACE_EDMX_2007_06);
+ mandatoryNamespaces.put(Edm.PREFIX_EDM, Edm.NAMESPACE_EDM_2008_09);
+ mandatoryNamespaces.put(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParserConstants.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParserConstants.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParserConstants.java
new file mode 100644
index 0000000..c2a3ae8
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmParserConstants.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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.core.edm.parser;
+
+public class EdmParserConstants {
+
+ public static final String EDM_DATA_SERVICES = "DataServices";
+ public static final String EDM_SCHEMA = "Schema";
+ public static final String EDM_SCHEMA_NAMESPACE = "Namespace";
+ public static final String EDM_SCHEMA_ALIAS = "Alias";
+ public static final String EDM_ENTITY_TYPE = "EntityType";
+ public static final String EDM_COMPLEX_TYPE = "ComplexType";
+ public static final String EDM_ASSOCIATION = "Association";
+ public static final String EDM_USING = "Using";
+
+ public static final String EDM_NAME = "Name";
+ public static final String EDM_TYPE = "Type";
+ public static final String EDM_ENTITY_TYPE_KEY = "Key";
+ public static final String EDM_ENTITY_TYPE_ABSTRACT = "Abstract";
+ public static final String EDM_BASE_TYPE = "BaseType";
+ public static final String EDM_PROPERTY_REF = "PropertyRef";
+
+ public static final String EDM_PROPERTY = "Property";
+ public static final String EDM_PROPERTY_NULLABLE = "Nullable";
+ public static final String EDM_PROPERTY_MAX_LENGTH = "MaxLength";
+ public static final String EDM_PROPERTY_MAX_LENGTH_MAX_VALUE = "Max";
+ public static final String EDM_PROPERTY_DEFAULT_VALUE = "DefaultValue";
+ public static final String EDM_PROPERTY_FIXED_LENGTH = "FixedLength";
+ public static final String EDM_PROPERTY_UNICODE = "Unicode";
+ public static final String EDM_PROPERTY_COLLATION = "Collation";
+ public static final String EDM_PROPERTY_PRECISION = "Precision";
+ public static final String EDM_PROPERTY_SCALE = "Scale";
+ public static final String EDM_PROPERTY_CONCURRENCY_MODE = "ConcurrencyMode";
+
+ public static final String EDM_NAVIGATION_PROPERTY = "NavigationProperty";
+ public static final String EDM_NAVIGATION_FROM_ROLE = "FromRole";
+ public static final String EDM_NAVIGATION_TO_ROLE = "ToRole";
+ public static final String EDM_NAVIGATION_RELATIONSHIP = "Relationship";
+
+ public static final String EDM_ASSOCIATION_CONSTRAINT = "ReferentialConstraint";
+ public static final String EDM_ASSOCIATION_END = "End";
+
+ public static final String EDM_ASSOCIATION_MULTIPLICITY = "Multiplicity";
+ public static final String EDM_ASSOCIATION_ONDELETE = "OnDelete";
+ public static final String EDM_ONDELETE_ACTION = "Action";
+
+ public static final String EDM_ENTITY_CONTAINER = "EntityContainer";
+ public static final String EDM_ENTITY_SET = "EntitySet";
+ public static final String EDM_ASSOCIATION_SET = "AssociationSet";
+ public static final String EDM_FUNCTION_IMPORT = "FunctionImport";
+ public static final String EDM_CONTAINER_EXTENDZ = "Extendz";
+
+ public static final String EDM_FUNCTION_IMPORT_HTTP_METHOD = "HttpMethod";
+ public static final String EDM_FUNCTION_IMPORT_RETURN = "ReturnType";
+ public static final String EDM_FUNCTION_PARAMETER = "Parameter";
+
+ public static final String M_ENTITY_TYPE_HAS_STREAM = "HasStream";
+ public static final String M_MIMETYPE = "MimeType";
+ public static final String M_FC_TARGET_PATH = "FC_TargetPath";
+ public static final String M_FC_SOURCE_PATH = "FC_SourcePath";
+ public static final String M_FC_NS_URI = "FC_NsUri";
+ public static final String M_FC_PREFIX = "FC_NsPrefix";
+ public static final String M_FC_KEEP_IN_CONTENT = "FC_KeepInContent";
+ public static final String M_FC_CONTENT_KIND = "FC_ContentKind";
+ public static final String EDM_ASSOCIATION_PRINCIPAL = "Principal";
+ public static final String EDM_ASSOCIATION_DEPENDENT = "Dependent";
+
+ public static final String EDM_ROLE = "Role";
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmxProvider.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmxProvider.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmxProvider.java
new file mode 100644
index 0000000..2cb7ce8
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/parser/EdmxProvider.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.core.edm.parser;
+
+import java.io.InputStream;
+import java.util.List;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+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.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.DataServices;
+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.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+
+public class EdmxProvider extends EdmProvider {
+ private DataServices dataServices;
+
+ public EdmxProvider parse(final InputStream in, final boolean validate) throws EntityProviderException {
+ EdmParser parser = new EdmParser();
+ XMLStreamReader streamReader = createStreamReader(in);
+ dataServices = parser.readMetadata(streamReader, validate);
+ return this;
+ }
+
+ @Override
+ public EntityContainerInfo getEntityContainerInfo(final String name) throws ODataException {
+ if (name != null) {
+ for (Schema schema : dataServices.getSchemas()) {
+ for (EntityContainer container : schema.getEntityContainers()) {
+ if (container.getName().equals(name)) {
+ return container;
+ }
+ }
+ }
+ } else {
+ for (Schema schema : dataServices.getSchemas()) {
+ for (EntityContainer container : schema.getEntityContainers()) {
+ if (container.isDefaultEntityContainer()) {
+ return container;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public EntityType getEntityType(final FullQualifiedName edmFQName) throws ODataException {
+ for (Schema schema : dataServices.getSchemas()) {
+ if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+ for (EntityType entityType : schema.getEntityTypes()) {
+ if (entityType.getName().equals(edmFQName.getName())) {
+ return entityType;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ComplexType getComplexType(final FullQualifiedName edmFQName) throws ODataException {
+ for (Schema schema : dataServices.getSchemas()) {
+ if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+ for (ComplexType complexType : schema.getComplexTypes()) {
+ if (complexType.getName().equals(edmFQName.getName())) {
+ return complexType;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Association getAssociation(final FullQualifiedName edmFQName) throws ODataException {
+ for (Schema schema : dataServices.getSchemas()) {
+ if (schema.getNamespace().equals(edmFQName.getNamespace())) {
+ for (Association association : schema.getAssociations()) {
+ if (association.getName().equals(edmFQName.getName())) {
+ return association;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public EntitySet getEntitySet(final String entityContainer, final String name) throws ODataException {
+ for (Schema schema : dataServices.getSchemas()) {
+ for (EntityContainer container : schema.getEntityContainers()) {
+ if (container.getName().equals(entityContainer)) {
+ for (EntitySet entitySet : container.getEntitySets()) {
+ if (entitySet.getName().equals(name)) {
+ return entitySet;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public AssociationSet getAssociationSet(final String entityContainer, final FullQualifiedName association, final String sourceEntitySetName, final String sourceEntitySetRole) throws ODataException {
+ for (Schema schema : dataServices.getSchemas()) {
+ for (EntityContainer container : schema.getEntityContainers()) {
+ if (container.getName().equals(entityContainer)) {
+ for (AssociationSet associationSet : container.getAssociationSets()) {
+ if (associationSet.getAssociation().equals(association)
+ && ((associationSet.getEnd1().getEntitySet().equals(sourceEntitySetName) && associationSet.getEnd1().getRole().equals(sourceEntitySetRole))
+ || (associationSet.getEnd2().getEntitySet().equals(sourceEntitySetName) && associationSet.getEnd2().getRole().equals(sourceEntitySetRole)))) {
+ return associationSet;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public FunctionImport getFunctionImport(final String entityContainer, final String name) throws ODataException {
+ for (Schema schema : dataServices.getSchemas()) {
+ for (EntityContainer container : schema.getEntityContainers()) {
+ if (container.getName().equals(entityContainer)) {
+ for (FunctionImport function : container.getFunctionImports()) {
+ if (function.getName().equals(name)) {
+ return function;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<Schema> getSchemas() throws ODataException {
+ return dataServices.getSchemas();
+ }
+
+ private XMLStreamReader createStreamReader(final InputStream in) throws EntityProviderException {
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ factory.setProperty(XMLInputFactory.IS_VALIDATING, false);
+ factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
+
+ XMLStreamReader streamReader;
+ try {
+ streamReader = factory.createXMLStreamReader(in);
+ } catch (XMLStreamException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass().getSimpleName()), e);
+ }
+
+ return streamReader;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAnnotationsImplProv.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAnnotationsImplProv.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAnnotationsImplProv.java
new file mode 100644
index 0000000..9c22cfd
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAnnotationsImplProv.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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.core.edm.provider;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmAnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.EdmAnnotationElement;
+import org.apache.olingo.odata2.api.edm.EdmAnnotations;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+
+public class EdmAnnotationsImplProv implements EdmAnnotations {
+
+ private List<AnnotationAttribute> annotationAttributes;
+ private List<? extends EdmAnnotationElement> annotationElements;
+
+ public EdmAnnotationsImplProv(final List<AnnotationAttribute> annotationAttributes, final List<AnnotationElement> annotationElements) {
+ this.annotationAttributes = annotationAttributes;
+ this.annotationElements = annotationElements;
+ }
+
+ @Override
+ public List<? extends EdmAnnotationElement> getAnnotationElements() {
+ return annotationElements;
+ }
+
+ @Override
+ public EdmAnnotationElement getAnnotationElement(final String name, final String namespace) {
+ if (annotationElements != null) {
+ Iterator<? extends EdmAnnotationElement> annotationElementIterator = annotationElements.iterator();
+
+ while (annotationElementIterator.hasNext()) {
+ EdmAnnotationElement annotationElement = annotationElementIterator.next();
+ if (annotationElement.getName().equals(name) && annotationElement.getNamespace().equals(namespace)) {
+ return annotationElement;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<? extends EdmAnnotationAttribute> getAnnotationAttributes() {
+ return annotationAttributes;
+ }
+
+ @Override
+ public EdmAnnotationAttribute getAnnotationAttribute(final String name, final String namespace) {
+ if (annotationElements != null) {
+ Iterator<? extends EdmAnnotationAttribute> annotationAttributesIterator = annotationAttributes.iterator();
+
+ while (annotationAttributesIterator.hasNext()) {
+ EdmAnnotationAttribute annotationAttribute = annotationAttributesIterator.next();
+ if (annotationAttribute.getName().equals(name) && annotationAttribute.getNamespace().equals(namespace)) {
+ return annotationAttribute;
+ }
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationEndImplProv.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationEndImplProv.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationEndImplProv.java
new file mode 100644
index 0000000..6030fa1
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationEndImplProv.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.core.edm.provider;
+
+import org.apache.olingo.odata2.api.edm.EdmAnnotatable;
+import org.apache.olingo.odata2.api.edm.EdmAnnotations;
+import org.apache.olingo.odata2.api.edm.EdmAssociationEnd;
+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.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+
+public class EdmAssociationEndImplProv implements EdmAssociationEnd, EdmAnnotatable {
+
+ private EdmImplProv edm;
+ private AssociationEnd associationEnd;
+
+ public EdmAssociationEndImplProv(final EdmImplProv edm, final AssociationEnd associationEnd) throws EdmException {
+ this.edm = edm;
+ this.associationEnd = associationEnd;
+ }
+
+ @Override
+ public String getRole() {
+ return associationEnd.getRole();
+ }
+
+ @Override
+ public EdmEntityType getEntityType() throws EdmException {
+ final FullQualifiedName type = associationEnd.getType();
+ EdmEntityType entityType = edm.getEntityType(type.getNamespace(), type.getName());
+ if (entityType == null) {
+ throw new EdmException(EdmException.COMMON);
+ }
+ return entityType;
+ }
+
+ @Override
+ public EdmMultiplicity getMultiplicity() {
+ return associationEnd.getMultiplicity();
+ }
+
+ @Override
+ public EdmAnnotations getAnnotations() throws EdmException {
+ return new EdmAnnotationsImplProv(associationEnd.getAnnotationAttributes(), associationEnd.getAnnotationElements());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationImplProv.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationImplProv.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationImplProv.java
new file mode 100644
index 0000000..3c102ca
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationImplProv.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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.core.edm.provider;
+
+import org.apache.olingo.odata2.api.edm.EdmAnnotatable;
+import org.apache.olingo.odata2.api.edm.EdmAnnotations;
+import org.apache.olingo.odata2.api.edm.EdmAssociation;
+import org.apache.olingo.odata2.api.edm.EdmAssociationEnd;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+
+public class EdmAssociationImplProv extends EdmNamedImplProv implements EdmAssociation, EdmAnnotatable {
+
+ private Association association;
+ private String namespace;
+
+ public EdmAssociationImplProv(final EdmImplProv edm, final Association association, final String namespace) throws EdmException {
+ super(edm, association.getName());
+ this.association = association;
+ this.namespace = namespace;
+ }
+
+ @Override
+ public String getNamespace() throws EdmException {
+ return namespace;
+ }
+
+ @Override
+ public EdmTypeKind getKind() {
+ return EdmTypeKind.ASSOCIATION;
+ }
+
+ @Override
+ public EdmAssociationEnd getEnd(final String role) throws EdmException {
+ AssociationEnd end = association.getEnd1();
+ if (end.getRole().equals(role)) {
+ return new EdmAssociationEndImplProv(edm, end);
+ }
+ end = association.getEnd2();
+ if (end.getRole().equals(role)) {
+ return new EdmAssociationEndImplProv(edm, end);
+ }
+
+ return null;
+ }
+
+ @Override
+ public EdmAnnotations getAnnotations() throws EdmException {
+ return new EdmAnnotationsImplProv(association.getAnnotationAttributes(), association.getAnnotationElements());
+ }
+
+ public EdmMultiplicity getEndMultiplicity(final String role) {
+ if (association.getEnd1().getRole().equals(role)) {
+ return association.getEnd1().getMultiplicity();
+ }
+
+ if (association.getEnd2().getRole().equals(role)) {
+ return association.getEnd2().getMultiplicity();
+ }
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetEndImplProv.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetEndImplProv.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetEndImplProv.java
new file mode 100644
index 0000000..4bbc1f7
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetEndImplProv.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.core.edm.provider;
+
+import org.apache.olingo.odata2.api.edm.EdmAnnotatable;
+import org.apache.olingo.odata2.api.edm.EdmAnnotations;
+import org.apache.olingo.odata2.api.edm.EdmAssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+
+public class EdmAssociationSetEndImplProv implements EdmAssociationSetEnd, EdmAnnotatable {
+
+ private EdmEntitySet entitySet;
+ private String role;
+ private AssociationSetEnd end;
+
+ public EdmAssociationSetEndImplProv(final AssociationSetEnd end, final EdmEntitySet entitySet) throws EdmException {
+ this.end = end;
+ this.entitySet = entitySet;
+ role = end.getRole();
+ }
+
+ @Override
+ public EdmEntitySet getEntitySet() throws EdmException {
+ return entitySet;
+ }
+
+ @Override
+ public String getRole() {
+ return role;
+ }
+
+ @Override
+ public EdmAnnotations getAnnotations() throws EdmException {
+ return new EdmAnnotationsImplProv(end.getAnnotationAttributes(), end.getAnnotationElements());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetImplProv.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetImplProv.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetImplProv.java
new file mode 100644
index 0000000..a831615
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmAssociationSetImplProv.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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.core.edm.provider;
+
+import org.apache.olingo.odata2.api.edm.EdmAnnotatable;
+import org.apache.olingo.odata2.api.edm.EdmAnnotations;
+import org.apache.olingo.odata2.api.edm.EdmAssociation;
+import org.apache.olingo.odata2.api.edm.EdmAssociationSet;
+import org.apache.olingo.odata2.api.edm.EdmAssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+
+public class EdmAssociationSetImplProv extends EdmNamedImplProv implements EdmAssociationSet, EdmAnnotatable {
+
+ private AssociationSet associationSet;
+ private EdmEntityContainer edmEntityContainer;
+
+ public EdmAssociationSetImplProv(final EdmImplProv edm, final AssociationSet associationSet, final EdmEntityContainer edmEntityContainer) throws EdmException {
+ super(edm, associationSet.getName());
+ this.associationSet = associationSet;
+ this.edmEntityContainer = edmEntityContainer;
+ }
+
+ @Override
+ public EdmAssociation getAssociation() throws EdmException {
+ EdmAssociation association = edm.getAssociation(associationSet.getAssociation().getNamespace(), associationSet.getAssociation().getName());
+ if (association == null) {
+ throw new EdmException(EdmException.COMMON);
+ }
+ return association;
+ }
+
+ @Override
+ public EdmAssociationSetEnd getEnd(final String role) throws EdmException {
+ AssociationSetEnd end;
+
+ if (associationSet.getEnd1().getRole().equals(role)) {
+ end = associationSet.getEnd1();
+ } else if (associationSet.getEnd2().getRole().equals(role)) {
+ end = associationSet.getEnd2();
+ } else {
+ return null;
+ }
+
+ EdmEntitySet entitySet = edmEntityContainer.getEntitySet(end.getEntitySet());
+ if (entitySet == null) {
+ throw new EdmException(EdmException.COMMON);
+ }
+
+ return new EdmAssociationSetEndImplProv(end, entitySet);
+ }
+
+ @Override
+ public EdmEntityContainer getEntityContainer() throws EdmException {
+ return edmEntityContainer;
+ }
+
+ @Override
+ public EdmAnnotations getAnnotations() throws EdmException {
+ return new EdmAnnotationsImplProv(associationSet.getAnnotationAttributes(), associationSet.getAnnotationElements());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmComplexPropertyImplProv.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmComplexPropertyImplProv.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmComplexPropertyImplProv.java
new file mode 100644
index 0000000..70b48c6
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmComplexPropertyImplProv.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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.core.edm.provider;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+
+/**
+ * @author SAP AG
+ */
+public class EdmComplexPropertyImplProv extends EdmPropertyImplProv {
+
+ private ComplexProperty property;
+
+ public EdmComplexPropertyImplProv(final EdmImplProv edm, final ComplexProperty property) throws EdmException {
+ super(edm, property.getType(), property);
+ this.property = property;
+ }
+
+ @Override
+ public EdmType getType() throws EdmException {
+ if (edmType == null) {
+ edmType = edm.getComplexType(property.getType().getNamespace(), property.getType().getName());
+ }
+ if (edmType == null) {
+ throw new EdmException(EdmException.PROVIDERPROBLEM);
+ }
+ return edmType;
+ }
+
+ @Override
+ public boolean isSimple() {
+ return false;
+ }
+}