| /******************************************************************************* |
| * 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.ep.consumer; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| 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 org.apache.olingo.odata2.core.ep.util.XmlMetadataConstants; |
| |
| public class XmlMetadataConsumer { |
| |
| 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 String edmNamespace = Edm.NAMESPACE_EDM_2008_09; |
| private Set<String> edmNamespaces; |
| |
| 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()) |
| && XmlMetadataConstants.EDMX_TAG.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| if (XmlMetadataConstants.EDM_SCHEMA.equals(reader.getLocalName())) { |
| edmNamespace = reader.getNamespaceURI(); |
| checkEdmNamespace(); |
| schemas.add(readSchema(reader)); |
| } else if (XmlMetadataConstants.EDM_DATA_SERVICES.equals(reader |
| .getLocalName())) { |
| dataServices.setDataServiceVersion(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, "DataServiceVersion")); |
| } |
| } |
| } |
| |
| if (!reader.isEndElement() || !XmlMetadataConstants.EDMX_TAG.equals(reader.getLocalName())) { |
| throw new EntityProviderException(EntityProviderException.MISSING_TAG |
| .addContent(XmlMetadataConstants.EDMX_TAG)); |
| } |
| |
| 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, edmNamespace, XmlMetadataConstants.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, XmlMetadataConstants.EDM_SCHEMA_NAMESPACE)); |
| inscopeMap.put(schema.getNamespace(), new HashSet<String>()); |
| schema.setAlias(reader.getAttributeValue(null, XmlMetadataConstants.EDM_SCHEMA_ALIAS)); |
| schema.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| currentNamespace = schema.getNamespace(); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_SCHEMA.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_USING.equals(currentHandledStartTagName)) { |
| usings.add(readUsing(reader, schema.getNamespace())); |
| } else if (XmlMetadataConstants.EDM_ENTITY_TYPE.equals(currentHandledStartTagName)) { |
| entityTypes.add(readEntityType(reader)); |
| } else if (XmlMetadataConstants.EDM_COMPLEX_TYPE.equals(currentHandledStartTagName)) { |
| complexTypes.add(readComplexType(reader)); |
| } else if (XmlMetadataConstants.EDM_ASSOCIATION.equals(currentHandledStartTagName)) { |
| associations.add(readAssociation(reader)); |
| } else if (XmlMetadataConstants.EDM_ENTITY_CONTAINER.equals(currentHandledStartTagName)) { |
| entityContainers.add(readEntityContainer(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (schema.getAlias() != null) { |
| aliasNamespaceMap.put(schema.getAlias(), schema.getNamespace()); |
| } |
| if (!annotationElements.isEmpty()) { |
| schema.setAnnotationElements(annotationElements); |
| } |
| schema.setUsings(usings).setEntityTypes(entityTypes).setComplexTypes(complexTypes).setAssociations(associations) |
| .setEntityContainers(entityContainers); |
| return schema; |
| } |
| |
| private Using readUsing(final XMLStreamReader reader, final String schemaNamespace) |
| throws XMLStreamException, EntityProviderException { |
| |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_USING); |
| |
| Using using = new Using(); |
| using.setNamespace(reader.getAttributeValue(null, XmlMetadataConstants.EDM_SCHEMA_NAMESPACE)); |
| inscopeMap.get(schemaNamespace).add(using.getNamespace()); |
| using.setAlias(reader.getAttributeValue(null, XmlMetadataConstants.EDM_SCHEMA_ALIAS)); |
| using.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| while (reader.hasNext() && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_USING.equals(reader.getLocalName()))) { |
| |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| 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, edmNamespace, XmlMetadataConstants.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, XmlMetadataConstants.EDM_NAME)); |
| if (reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.EDM_CONTAINER_IS_DEFAULT) != null) { |
| container.setDefaultEntityContainer("true".equalsIgnoreCase(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, |
| "IsDefaultEntityContainer"))); |
| } |
| container.setExtendz(reader.getAttributeValue(null, XmlMetadataConstants.EDM_CONTAINER_EXTENDZ)); |
| container.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ENTITY_CONTAINER.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_ENTITY_SET.equals(currentHandledStartTagName)) { |
| entitySets.add(readEntitySet(reader)); |
| } else if (XmlMetadataConstants.EDM_ASSOCIATION_SET.equals(currentHandledStartTagName)) { |
| associationSets.add(readAssociationSet(reader)); |
| } else if (XmlMetadataConstants.EDM_FUNCTION_IMPORT.equals(currentHandledStartTagName)) { |
| functionImports.add(readFunctionImport(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| container.setAnnotationElements(annotationElements); |
| } |
| container.setEntitySets(entitySets).setAssociationSets(associationSets).setFunctionImports(functionImports); |
| |
| containerMap.put(new FullQualifiedName(currentNamespace, container.getName()), container); |
| return container; |
| } |
| |
| private FunctionImport readFunctionImport(final XMLStreamReader reader) |
| throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_FUNCTION_IMPORT); |
| FunctionImport function = new FunctionImport(); |
| List<FunctionImportParameter> functionParameters = new ArrayList<FunctionImportParameter>(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| |
| function.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| function.setHttpMethod(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, |
| XmlMetadataConstants.EDM_FUNCTION_IMPORT_HTTP_METHOD)); |
| function.setEntitySet(reader.getAttributeValue(null, XmlMetadataConstants.EDM_ENTITY_SET)); |
| |
| String returnTypeString = reader.getAttributeValue(null, XmlMetadataConstants.EDM_FUNCTION_IMPORT_RETURN); |
| if (returnTypeString != null) { |
| ReturnType returnType = new ReturnType(); |
| if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) { |
| returnType.setMultiplicity(EdmMultiplicity.MANY); |
| returnTypeString = returnTypeString.substring(returnTypeString.indexOf("(") + 1, returnTypeString.length() - 1); |
| } else { |
| returnType.setMultiplicity(EdmMultiplicity.ONE); |
| } |
| FullQualifiedName fqName = extractFQName(returnTypeString); |
| returnType.setTypeName(fqName); |
| function.setReturnType(returnType); |
| } |
| function.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_FUNCTION_IMPORT.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_FUNCTION_PARAMETER.equals(currentHandledStartTagName)) { |
| functionParameters.add(readFunctionImportParameter(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| function.setAnnotationElements(annotationElements); |
| } |
| function.setParameters(functionParameters); |
| return function; |
| } |
| |
| private FunctionImportParameter readFunctionImportParameter(final XMLStreamReader reader) |
| throws EntityProviderException, XMLStreamException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_FUNCTION_PARAMETER); |
| FunctionImportParameter functionParameter = new FunctionImportParameter(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| |
| functionParameter.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| functionParameter.setMode(reader.getAttributeValue(null, XmlMetadataConstants.EDM_FUNCTION_PARAMETER_MODE)); |
| String type = reader.getAttributeValue(null, XmlMetadataConstants.EDM_TYPE); |
| if (type == null) { |
| throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE |
| .addContent(XmlMetadataConstants.EDM_TYPE).addContent(XmlMetadataConstants.EDM_FUNCTION_PARAMETER)); |
| } |
| functionParameter.setType(EdmSimpleTypeKind.valueOf(extractFQName(type).getName())); |
| functionParameter.setFacets(readFacets(reader)); |
| functionParameter.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_FUNCTION_PARAMETER.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| functionParameter.setAnnotationElements(annotationElements); |
| } |
| return functionParameter; |
| } |
| |
| private AssociationSet readAssociationSet(final XMLStreamReader reader) |
| throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_ASSOCIATION_SET); |
| AssociationSet associationSet = new AssociationSet(); |
| List<AssociationSetEnd> ends = new ArrayList<AssociationSetEnd>(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| |
| associationSet.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| String association = reader.getAttributeValue(null, XmlMetadataConstants.EDM_ASSOCIATION); |
| if (association != null) { |
| associationSet.setAssociation(extractFQName(association)); |
| } else { |
| throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE |
| .addContent(XmlMetadataConstants.EDM_ASSOCIATION).addContent(XmlMetadataConstants.EDM_ASSOCIATION_SET)); |
| } |
| associationSet.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ASSOCIATION_SET.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_ASSOCIATION_END.equals(currentHandledStartTagName)) { |
| AssociationSetEnd associationSetEnd = new AssociationSetEnd(); |
| associationSetEnd.setEntitySet(reader.getAttributeValue(null, XmlMetadataConstants.EDM_ENTITY_SET)); |
| associationSetEnd.setRole(reader.getAttributeValue(null, XmlMetadataConstants.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)); |
| } |
| if (!annotationElements.isEmpty()) { |
| associationSet.setAnnotationElements(annotationElements); |
| } |
| return associationSet; |
| } |
| |
| private EntitySet readEntitySet(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_ENTITY_SET); |
| EntitySet entitySet = new EntitySet(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| entitySet.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| String entityType = reader.getAttributeValue(null, XmlMetadataConstants.EDM_ENTITY_TYPE); |
| if (entityType != null) { |
| FullQualifiedName fqName = extractFQName(entityType); |
| entitySet.setEntityType(fqName); |
| } else { |
| throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE |
| .addContent(XmlMetadataConstants.EDM_ENTITY_TYPE).addContent(XmlMetadataConstants.EDM_ENTITY_SET)); |
| } |
| entitySet.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ENTITY_SET.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| entitySet.setAnnotationElements(annotationElements); |
| } |
| return entitySet; |
| } |
| |
| private Association readAssociation(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_ASSOCIATION); |
| |
| Association association = new Association(); |
| association.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| List<AssociationEnd> associationEnds = new ArrayList<AssociationEnd>(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| association.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ASSOCIATION.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_ASSOCIATION_END.equals(currentHandledStartTagName)) { |
| associationEnds.add(readAssociationEnd(reader)); |
| } else if (XmlMetadataConstants.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")); |
| } |
| if (!annotationElements.isEmpty()) { |
| association.setAnnotationElements(annotationElements); |
| } |
| association.setEnd1(associationEnds.get(0)).setEnd2(associationEnds.get(1)); |
| associationsMap.put(new FullQualifiedName(currentNamespace, association.getName()), association); |
| return association; |
| } |
| |
| private ReferentialConstraint readReferentialConstraint(final XMLStreamReader reader) throws XMLStreamException, |
| EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_ASSOCIATION_CONSTRAINT); |
| ReferentialConstraint refConstraint = new ReferentialConstraint(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| refConstraint.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ASSOCIATION_CONSTRAINT.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_ASSOCIATION_PRINCIPAL.equals(currentHandledStartTagName)) { |
| reader |
| .require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_ASSOCIATION_PRINCIPAL); |
| refConstraint.setPrincipal(readReferentialConstraintRole(reader)); |
| } else if (XmlMetadataConstants.EDM_ASSOCIATION_DEPENDENT.equals(currentHandledStartTagName)) { |
| reader |
| .require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_ASSOCIATION_DEPENDENT); |
| refConstraint.setDependent(readReferentialConstraintRole(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| refConstraint.setAnnotationElements(annotationElements); |
| } |
| return refConstraint; |
| } |
| |
| private ReferentialConstraintRole readReferentialConstraintRole(final XMLStreamReader reader) |
| throws EntityProviderException, XMLStreamException { |
| ReferentialConstraintRole rcRole = new ReferentialConstraintRole(); |
| rcRole.setRole(reader.getAttributeValue(null, XmlMetadataConstants.EDM_ROLE)); |
| List<PropertyRef> propertyRefs = new ArrayList<PropertyRef>(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| rcRole.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && (XmlMetadataConstants.EDM_ASSOCIATION_PRINCIPAL.equals(reader.getLocalName()) |
| || XmlMetadataConstants.EDM_ASSOCIATION_DEPENDENT.equals(reader.getLocalName())))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_PROPERTY_REF.equals(currentHandledStartTagName)) { |
| propertyRefs.add(readPropertyRef(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| rcRole.setAnnotationElements(annotationElements); |
| } |
| rcRole.setPropertyRefs(propertyRefs); |
| return rcRole; |
| } |
| |
| private ComplexType readComplexType(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_COMPLEX_TYPE); |
| |
| ComplexType complexType = new ComplexType(); |
| List<Property> properties = new ArrayList<Property>(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| complexType.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| String baseType = reader.getAttributeValue(null, XmlMetadataConstants.EDM_BASE_TYPE); |
| if (baseType != null) { |
| complexType.setBaseType(extractFQName(baseType)); |
| } |
| if (reader.getAttributeValue(null, XmlMetadataConstants.EDM_TYPE_ABSTRACT) != null) { |
| complexType.setAbstract("true".equalsIgnoreCase(reader.getAttributeValue(null, |
| XmlMetadataConstants.EDM_TYPE_ABSTRACT))); |
| } |
| complexType.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_COMPLEX_TYPE.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_PROPERTY.equals(currentHandledStartTagName)) { |
| properties.add(readProperty(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| complexType.setAnnotationElements(annotationElements); |
| } |
| complexType.setProperties(properties); |
| 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, edmNamespace, XmlMetadataConstants.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, XmlMetadataConstants.EDM_NAME)); |
| String hasStream = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.M_ENTITY_TYPE_HAS_STREAM); |
| if (hasStream != null) { |
| entityType.setHasStream("true".equalsIgnoreCase(hasStream)); |
| } |
| |
| if (reader.getAttributeValue(null, XmlMetadataConstants.EDM_TYPE_ABSTRACT) != null) { |
| entityType.setAbstract("true".equalsIgnoreCase(reader.getAttributeValue(null, |
| XmlMetadataConstants.EDM_TYPE_ABSTRACT))); |
| } |
| String baseType = reader.getAttributeValue(null, XmlMetadataConstants.EDM_BASE_TYPE); |
| if (baseType != null) { |
| entityType.setBaseType(extractFQName(baseType)); |
| } |
| entityType.setCustomizableFeedMappings(readCustomizableFeedMappings(reader)); |
| entityType.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() |
| && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ENTITY_TYPE.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_ENTITY_TYPE_KEY.equals(currentHandledStartTagName)) { |
| key = readEntityTypeKey(reader); |
| } else if (XmlMetadataConstants.EDM_PROPERTY.equals(currentHandledStartTagName)) { |
| properties.add(readProperty(reader)); |
| } else if (XmlMetadataConstants.EDM_NAVIGATION_PROPERTY.equals(currentHandledStartTagName)) { |
| navProperties.add(readNavigationProperty(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| extractNamespaces(reader); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| entityType.setAnnotationElements(annotationElements); |
| } |
| entityType.setKey(key).setProperties(properties).setNavigationProperties(navProperties); |
| 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, edmNamespace, XmlMetadataConstants.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() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ENTITY_TYPE_KEY.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.EDM_PROPERTY_REF.equals(currentHandledStartTagName)) { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_PROPERTY_REF); |
| keys.add(readPropertyRef(reader)); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| Key key = new Key().setKeys(keys).setAnnotationAttributes(annotationAttributes); |
| if (!annotationElements.isEmpty()) { |
| key.setAnnotationElements(annotationElements); |
| } |
| return key; |
| } |
| |
| private PropertyRef readPropertyRef(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_PROPERTY_REF); |
| PropertyRef propertyRef = new PropertyRef(); |
| propertyRef.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| propertyRef.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_PROPERTY_REF.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| propertyRef.setAnnotationElements(annotationElements); |
| } |
| return propertyRef; |
| } |
| |
| private NavigationProperty readNavigationProperty(final XMLStreamReader reader) throws XMLStreamException, |
| EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_NAVIGATION_PROPERTY); |
| |
| NavigationProperty navProperty = new NavigationProperty(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| navProperty.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); |
| String relationship = reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAVIGATION_RELATIONSHIP); |
| if (relationship != null) { |
| FullQualifiedName fqName = extractFQName(relationship); |
| navProperty.setRelationship(fqName); |
| |
| } else { |
| throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE |
| .addContent(XmlMetadataConstants.EDM_NAVIGATION_RELATIONSHIP).addContent( |
| XmlMetadataConstants.EDM_NAVIGATION_PROPERTY)); |
| } |
| |
| navProperty.setFromRole(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAVIGATION_FROM_ROLE)); |
| navProperty.setToRole(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAVIGATION_TO_ROLE)); |
| navProperty.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_NAVIGATION_PROPERTY.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| navProperty.setAnnotationElements(annotationElements); |
| } |
| navProperties.add(navProperty); |
| return navProperty; |
| } |
| |
| private Property readProperty(final XMLStreamReader reader) throws XMLStreamException, EntityProviderException { |
| reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace, XmlMetadataConstants.EDM_PROPERTY); |
| Property property; |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| String type = reader.getAttributeValue(null, XmlMetadataConstants.EDM_TYPE); |
| if (type == null) { |
| throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE |
| .addContent(XmlMetadataConstants.EDM_TYPE).addContent(XmlMetadataConstants.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, XmlMetadataConstants.M_MIMETYPE)); |
| property.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_PROPERTY.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| 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, XmlMetadataConstants.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, XmlMetadataConstants.EDM_NAME)); |
| property.setType(EdmSimpleTypeKind.valueOf(fqName.getName())); |
| return property; |
| } |
| |
| private Facets readFacets(final XMLStreamReader reader) throws XMLStreamException { |
| String isNullable = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_NULLABLE); |
| String maxLength = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_MAX_LENGTH); |
| String precision = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_PRECISION); |
| String scale = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_SCALE); |
| String isFixedLength = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_FIXED_LENGTH); |
| String isUnicode = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_UNICODE); |
| String concurrencyMode = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_CONCURRENCY_MODE); |
| String defaultValue = reader.getAttributeValue(null, XmlMetadataConstants.EDM_PROPERTY_DEFAULT_VALUE); |
| String collation = reader.getAttributeValue(null, XmlMetadataConstants.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 (XmlMetadataConstants.EDM_PROPERTY_MAX_LENGTH_MAX_VALUE_FIRST_UPPERCASE.equals(maxLength) |
| || XmlMetadataConstants.EDM_PROPERTY_MAX_LENGTH_MAX_VALUE_LOWERCASE.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, XmlMetadataConstants.M_FC_TARGET_PATH); |
| String sourcePath = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.M_FC_SOURCE_PATH); |
| String nsUri = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.M_FC_NS_URI); |
| String nsPrefix = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.M_FC_PREFIX); |
| String keepInContent = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.M_FC_KEEP_IN_CONTENT); |
| String contentKind = reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.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, edmNamespace, XmlMetadataConstants.EDM_ASSOCIATION_END); |
| |
| AssociationEnd associationEnd = new AssociationEnd(); |
| List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); |
| associationEnd.setRole(reader.getAttributeValue(null, XmlMetadataConstants.EDM_ROLE)); |
| associationEnd.setMultiplicity(EdmMultiplicity.fromLiteral(reader.getAttributeValue(null, |
| XmlMetadataConstants.EDM_ASSOCIATION_MULTIPLICITY))); |
| String type = reader.getAttributeValue(null, XmlMetadataConstants.EDM_TYPE); |
| if (type == null) { |
| throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE |
| .addContent(XmlMetadataConstants.EDM_TYPE).addContent(XmlMetadataConstants.EDM_ASSOCIATION_END)); |
| } |
| associationEnd.setType(extractFQName(type)); |
| associationEnd.setAnnotationAttributes(readAnnotationAttribute(reader)); |
| while (reader.hasNext() && !(reader.isEndElement() && edmNamespace.equals(reader.getNamespaceURI()) |
| && XmlMetadataConstants.EDM_ASSOCIATION_END.equals(reader.getLocalName()))) { |
| reader.next(); |
| if (reader.isStartElement()) { |
| extractNamespaces(reader); |
| currentHandledStartTagName = reader.getLocalName(); |
| if (XmlMetadataConstants.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, XmlMetadataConstants.EDM_ONDELETE_ACTION))) { |
| onDelete.setAction(EdmAction.values()[i]); |
| } |
| } |
| associationEnd.setOnDelete(onDelete); |
| } else { |
| annotationElements.add(readAnnotationElement(reader)); |
| } |
| } |
| } |
| if (!annotationElements.isEmpty()) { |
| 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 (!edmNamespaces.contains(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 (namespace != null && !isDefaultNamespace(namespace)) { |
| annotationAttribute.setNamespace(namespace); |
| } |
| annotationAttributes.add(annotationAttribute); |
| } |
| if (!annotationAttributes.isEmpty()) { |
| aElement.setAttributes(annotationAttributes); |
| } |
| |
| boolean justRead = false; |
| if (reader.hasNext()) { |
| reader.next(); |
| justRead = true; |
| } |
| |
| while (justRead && !(reader.isEndElement() && aElement.getName() != null |
| && aElement.getName().equals(reader.getLocalName()))) { |
| justRead = false; |
| if (reader.isStartElement()) { |
| annotationElements.add(readAnnotationElement(reader)); |
| if (reader.hasNext()) { |
| reader.next(); |
| justRead = true; |
| } |
| } else if (reader.isCharacters()) { |
| String elementText = ""; |
| do { |
| justRead = false; |
| elementText = elementText + reader.getText(); |
| if (reader.hasNext()) { |
| reader.next(); |
| justRead = true; |
| } |
| } while (justRead && reader.isCharacters()); |
| aElement.setText(elementText); |
| } |
| } |
| 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++) { |
| String attributeNamespace = reader.getAttributeNamespace(i); |
| if (attributeNamespace != null && !isDefaultNamespace(attributeNamespace) |
| && !mandatoryNamespaces.containsValue(attributeNamespace) |
| && !edmNamespaces.contains(attributeNamespace)) { |
| annotationAttributes.add(new AnnotationAttribute().setName(reader.getAttributeLocalName(i)). |
| setPrefix(reader.getAttributePrefix(i)).setNamespace(attributeNamespace).setText( |
| reader.getAttributeValue(i))); |
| } |
| } |
| if (annotationAttributes.isEmpty()) { |
| return null; |
| } |
| return annotationAttributes; |
| } |
| |
| private boolean isDefaultNamespace(final String namespace) { |
| return namespace.isEmpty(); |
| } |
| |
| private void checkMandatoryNamespacesAvailable() 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_M_2007_08)); |
| } |
| } |
| |
| private void checkEdmNamespace() throws EntityProviderException { |
| if (!edmNamespaces.contains(edmNamespace)) { |
| throw new EntityProviderException(EntityProviderException.INVALID_NAMESPACE |
| .addContent(XmlMetadataConstants.EDM_SCHEMA)); |
| } |
| } |
| |
| 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 || isDefaultNamespace(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 = fetchLastBaseType(baseTypeFQName,entityTypesMap); |
| } |
| 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())); |
| } |
| } |
| } |
| } |
| |
| |
| /* This method gets the last base type of the EntityType |
| * which has key defined in order to validate it*/ |
| private EntityType fetchLastBaseType |
| (FullQualifiedName baseTypeFQName, Map<FullQualifiedName, EntityType> entityTypesMap) |
| throws EntityProviderException { |
| |
| EntityType baseEntityType = null ; |
| while(baseTypeFQName!=null){ |
| baseEntityType = entityTypesMap.get(baseTypeFQName); |
| if(baseEntityType.getKey()!=null){ |
| break; |
| }else if(baseEntityType !=null && baseEntityType.getBaseType() !=null){ |
| baseTypeFQName = baseEntityType.getBaseType(); |
| }else if(baseEntityType.getBaseType() == null){ |
| break; |
| } |
| } |
| return baseEntityType; |
| } |
| |
| 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 { |
| checkMandatoryNamespacesAvailable(); |
| 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_M, Edm.NAMESPACE_M_2007_08); |
| edmNamespaces = new HashSet<String>(); |
| edmNamespaces.add(Edm.NAMESPACE_EDM_2006_04); |
| edmNamespaces.add(Edm.NAMESPACE_EDM_2007_05); |
| edmNamespaces.add(Edm.NAMESPACE_EDM_2008_01); |
| edmNamespaces.add(Edm.NAMESPACE_EDM_2008_09); |
| |
| } |
| } |