http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java
----------------------------------------------------------------------
diff --git
a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java
b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java
new file mode 100644
index 0000000..73d62c1
--- /dev/null
+++
b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java
@@ -0,0 +1,1570 @@
+/*******************************************************************************
+ * 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.client.core.ep.deserializer;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+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.EdmAnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.EdmAnnotationElement;
+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.EdmAssociationSet;
+import org.apache.olingo.odata2.api.edm.EdmAssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.EdmComplexType;
+import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
+import org.apache.olingo.odata2.api.edm.EdmContentKind;
+import org.apache.olingo.odata2.api.edm.EdmCustomizableFeedMappings;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmParameter;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmReferentialConstraint;
+import org.apache.olingo.odata2.api.edm.EdmReferentialConstraintRole;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
+import org.apache.olingo.odata2.api.edm.provider.Facets;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.client.api.edm.EdmDataServices;
+import org.apache.olingo.odata2.client.api.edm.EdmSchema;
+import org.apache.olingo.odata2.client.api.edm.EdmUsing;
+import org.apache.olingo.odata2.client.core.edm.EdmMetadataAssociationEnd;
+import
org.apache.olingo.odata2.client.core.edm.Impl.EdmAnnotationAttributeImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmAnnotationElementImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmAnnotationsImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmAssociationEndImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmAssociationImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmAssociationSetEndImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmAssociationSetImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmComplexPropertyImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmComplexTypeImpl;
+import
org.apache.olingo.odata2.client.core.edm.Impl.EdmCustomizableFeedMappingsImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmEntityContainerImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmEntitySetImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmEntityTypeImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmFunctionImportImpl;
+import
org.apache.olingo.odata2.client.core.edm.Impl.EdmFunctionImportParameter;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmKeyImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmNamedImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmNavigationPropertyImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmOnDeleteImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmParameterImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmPropertyImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmPropertyRefImpl;
+import
org.apache.olingo.odata2.client.core.edm.Impl.EdmReferentialConstraintImpl;
+import
org.apache.olingo.odata2.client.core.edm.Impl.EdmReferentialConstraintRoleImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmSchemaImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmSimplePropertyImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmTypedImpl;
+import org.apache.olingo.odata2.client.core.edm.Impl.EdmUsingImpl;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
+import org.apache.olingo.odata2.core.edm.EdmSimpleTypeFacadeImpl;
+import org.apache.olingo.odata2.core.ep.util.XmlMetadataConstants;
+
+/**
+ * This class deserializes Metadata document
+ *
+ */
+public class XmlMetadataDeserializer {
+
+ 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, EdmEntityType> entityTypesMap = new
HashMap<FullQualifiedName, EdmEntityType>();
+ private Map<FullQualifiedName, EdmComplexType> complexTypesMap = new
HashMap<FullQualifiedName, EdmComplexType>();
+ private Map<FullQualifiedName, EdmProperty> complexPropertyMap = new
HashMap<FullQualifiedName, EdmProperty>();
+ private Map<FullQualifiedName, EdmAssociation> associationsMap = new
HashMap<FullQualifiedName, EdmAssociation>();
+ private Map<String, EdmAssociationSet> associationSetMap = new
HashMap<String, EdmAssociationSet>();
+ private Map<String, EdmAssociationSet> tempAssociationSetMap = new
HashMap<String, EdmAssociationSet>();
+ private Map<String, List<EdmAssociationSetEndImpl>> associationSetEndMap =
+ new HashMap<String, List<EdmAssociationSetEndImpl>>();
+ private Map<FullQualifiedName, EdmEntityContainer> containerMap =
+ new HashMap<FullQualifiedName, EdmEntityContainer>();
+ //Map for base type relation
+ private Map<FullQualifiedName, FullQualifiedName> entityBaseTypeMap =
+ new HashMap<FullQualifiedName, FullQualifiedName>();
+ private Map<FullQualifiedName, FullQualifiedName> complexBaseTypeMap =
+ new HashMap<FullQualifiedName, FullQualifiedName>();
+ private List<EdmFunctionImport> edmFunctionImportList = new
ArrayList<EdmFunctionImport>();
+ private List<EdmEntitySet> edmEntitySetList = new ArrayList<EdmEntitySet>();
+ private List<EdmNavigationProperty> navProperties = new
ArrayList<EdmNavigationProperty>();
+ private String currentHandledStartTagName;
+ private String currentNamespace;
+ private String edmNamespace = Edm.NAMESPACE_EDM_2008_09;
+ private Set<String> edmNamespaces;
+ private EdmEntityContainer defaultEdmEntityContainer;
+
+ /**
+ *
+ * @param content
+ * @param validate
+ * @return EdmDataServices
+ * @throws EntityProviderException
+ * @throws EdmException
+ */
+ public EdmDataServices readMetadata(final InputStream content, final boolean
validate)//NOSONAR
+ throws EntityProviderException, EdmException {
+ try {
+ initialize();
+ EdmDataServices dataServices = new EdmDataServices();
+ List<EdmSchema> schemas = new ArrayList<EdmSchema>();
+ EdmImpl edm = new EdmImpl();
+ XMLStreamReader reader = XmlHelper.createStreamReader(content);
+ 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())) {
//NOSONAR
+ edmNamespace = reader.getNamespaceURI();
+ checkEdmNamespace();
+ schemas.add(readSchema(reader, edm));
+ } 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));
+ }
+
+ setBaseTypeForEntityType();
+ setBaseTypeForComplexType();
+ setDetailsForEntitySet();
+ setAssociationSetForNavigations();
+ if (validate) {
+ validate();
+ }
+ edm.setEdmSchemas(schemas);
+ dataServices.setClientEdm(edm);
+ reader.close();
+ return dataServices;
+ } catch (XMLStreamException e) {
+ throw new
EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+
+ }
+
+ private EdmSchema readSchema(final XMLStreamReader reader, EdmImpl edm)
//NOSONAR
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_SCHEMA);
+ final EdmSchemaImpl schemaImpl = new EdmSchemaImpl();
+ final List<EdmUsing> usings = new ArrayList<EdmUsing>();
+ final List<EdmComplexType> complexTypes = new ArrayList<EdmComplexType>();
+ final List<EdmEntityType> entityTypes = new ArrayList<EdmEntityType>();
+ final List<EdmAssociation> associations = new ArrayList<EdmAssociation>();
+ final List<EdmEntityContainer> entityContainers = new
ArrayList<EdmEntityContainer>();
+ final List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ schemaImpl.setNamespace(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_SCHEMA_NAMESPACE));
+ inscopeMap.put(schemaImpl.getNamespace(), new HashSet<String>());
+ schemaImpl.setAlias(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_SCHEMA_ALIAS));
+ schemaImpl.setAnnotationAttributes(readAnnotationAttribute(reader));
+ currentNamespace = schemaImpl.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, schemaImpl.getNamespace()));
+ } else if
(XmlMetadataConstants.EDM_ENTITY_TYPE.equals(currentHandledStartTagName)) {
+ entityTypes.add(readEntityType(reader, edm));
+ } else if
(XmlMetadataConstants.EDM_COMPLEX_TYPE.equals(currentHandledStartTagName)) {
+ complexTypes.add(readComplexType(reader, edm));
+ } else if
(XmlMetadataConstants.EDM_ASSOCIATION.equals(currentHandledStartTagName)) {
+ associations.add(readAssociation(reader, edm));
+ } else if
(XmlMetadataConstants.EDM_ENTITY_CONTAINER.equals(currentHandledStartTagName)) {
+ entityContainers.add(readEntityContainer(reader, (EdmImpl) edm));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (schemaImpl.getAlias() != null) {
+ aliasNamespaceMap.put(schemaImpl.getAlias(), schemaImpl.getNamespace());
+ edm.setAliasToNamespaceInfo(aliasNamespaceMap);
+ }
+ if (!annotationElements.isEmpty()) {
+ schemaImpl.setAnnotationElements(annotationElements);
+ }
+ schemaImpl
+ .setUsings(usings)
+ .setEntityTypes(entityTypes)
+ .setComplexTypes(complexTypes)
+ .setAssociations(associations)
+ .setEntityContainers(entityContainers);
+
+ edm.setAliasToNamespaceInfo(aliasNamespaceMap)
+ .setEdmAssociations(associationsMap)
+ .setEdmComplexTypes(complexTypesMap)
+ .setEdmEntityContainers(containerMap)
+ .setDefaultEntityContainer(defaultEdmEntityContainer)
+ .setEdmEntitySets(edmEntitySetList)
+ .setEdmEntityTypes(entityTypesMap)
+ .setEdmFunctionImports(edmFunctionImportList);
+
+
+ return schemaImpl;
+ }
+
+ private void setAssociationSetForNavigations() throws EdmException {
+ for(EdmEntitySet edmEntitySet:edmEntitySetList){
+ List<String> navigations =
edmEntitySet.getEntityType().getNavigationPropertyNames();
+ if(navigations!=null && !navigations.isEmpty()){
+ for (EdmNavigationProperty navigationProperty : navProperties) {
+ if (navigations.contains(navigationProperty.getName())) { //NOSONAR
+ FullQualifiedName associationName = ((EdmNavigationPropertyImpl)
navigationProperty).getRelationshipName();
+ String toRoleName = ((EdmNavigationPropertyImpl)
navigationProperty).getToRole();
+ EdmAssociationEnd end =
associationsMap.get(associationName).getEnd(toRoleName);
+ if (end == null) {
+ throw new EdmException(EdmException.ASSOCIATIONNOTFOUND);
+ }
+ String relation = associationName.toString();
+ StringBuilder key = new StringBuilder();
+ key.append(edmEntitySet.getName());
+ key.append(">>");
+ key.append(relation);
+ key.append(">>");
+ key.append(navigationProperty.getFromRole());
+ ((EdmNavigationPropertyImpl)
navigationProperty).setMultiplicity(end.getMultiplicity());
+ associationSetMap.put(key.toString(),
tempAssociationSetMap.get(relation));
+ }
+ }
+ }
+ }
+ }
+
+ private void setDetailsForEntitySet() throws EdmException {
+ for (EdmEntitySet entitySet : edmEntitySetList) {
+ EdmEntitySetImpl entitySetImpl = (EdmEntitySetImpl) entitySet;
+ FullQualifiedName entityTypeKey = entitySetImpl.getEntityTypeName();
+
if(aliasNamespaceMap.get(entitySetImpl.getEntityTypeName().getNamespace()) !=
null){
+ entityTypeKey = new
FullQualifiedName(aliasNamespaceMap.get(entitySetImpl.getEntityTypeName().getNamespace()),
+ entitySetImpl.getEntityTypeName().getName());
+ }
+ if (entitySetImpl.getEntityType() == null && entityTypeKey != null) {
+ if(entityTypesMap.get(entityTypeKey) != null){
+ entitySetImpl.setEdmEntityType(entityTypesMap.get(entityTypeKey));
+ }else{
+ EdmEntityTypeImpl edmEntityType = new EdmEntityTypeImpl();
+ edmEntityType.setName(entitySetImpl.getEntityTypeName().getName());
+
edmEntityType.setNamespace(entitySetImpl.getEntityTypeName().getNamespace());
+ entitySetImpl.setEdmEntityType(edmEntityType);
+ }
+ }
+ if (associationSetEndMap.get(entitySet.getName())!=null) {
+ List<EdmAssociationSetEndImpl> ends =
associationSetEndMap.get(entitySet.getName());
+ for(EdmAssociationSetEndImpl end:ends){
+ end.setEntitySet(entitySet);
+ }
+ }
+ }
+
+ }
+
+ private void setBaseTypeForComplexType() throws EdmException {
+ for (Entry<FullQualifiedName, EdmComplexType> entity :
complexTypesMap.entrySet()) {
+ EdmComplexTypeImpl entityType = (EdmComplexTypeImpl) entity.getValue();
+ if (((EdmComplexTypeImpl) entity.getValue()).getEdmBaseTypeName() !=
null &&
+ entity.getValue().getBaseType() == null) {
+ FullQualifiedName fqname = entityType.getEdmBaseTypeName();
+ if(complexTypesMap.get(entityType.getEdmBaseTypeName()) != null){
+ entityType.setEdmBaseType(complexTypesMap.get(fqname));
+ }else if (aliasNamespaceMap.containsKey(fqname.getNamespace())) {
+ FullQualifiedName changedName = new FullQualifiedName(
+ aliasNamespaceMap.get(fqname.getNamespace()), fqname.getName());
+ entityType.setEdmBaseType(complexTypesMap.get(changedName));
+ }else{
+ //Adding dummy basetype awhich will fail during validation
+ EdmComplexTypeImpl newBaseType = new EdmComplexTypeImpl();
+ newBaseType.setName(fqname.getName());
+ newBaseType.setNamespace(fqname.getNamespace());
+ ((EdmComplexTypeImpl) entity.getValue()).setEdmBaseType(newBaseType);
+ break;
+ }
+
+ }
+ }
+ setBaseTypePropertiesForComplexType(complexBaseTypeMap);
+ }
+
+ private void setBaseTypeForEntityType() throws EdmException {
+ for (Entry<FullQualifiedName, EdmEntityType> entity :
entityTypesMap.entrySet()) {
+ EdmEntityTypeImpl entityType = (EdmEntityTypeImpl) entity.getValue();
+ if (entityType.getBaseTypeName() != null && entity.getValue()
+ .getBaseType() == null) {
+ FullQualifiedName fqname = entityType.getBaseTypeName();
+ if (entityTypesMap.get(entityType.getBaseTypeName()) != null) {
+ entityType.setEdmBaseType(entityTypesMap.get(fqname));
+ } else if (aliasNamespaceMap.containsKey(fqname.getNamespace())) {
+ FullQualifiedName changedName = new FullQualifiedName(
+ aliasNamespaceMap.get(fqname.getNamespace()), fqname.getName());
+ entityType.setEdmBaseType(entityTypesMap.get(changedName));
+ } else {// Adding dummy basetype which will fail during validation
+ EdmEntityTypeImpl newBaseType = new EdmEntityTypeImpl();
+ newBaseType.setName(fqname.getName());
+ newBaseType.setNamespace(fqname.getNamespace());
+ entityType.setEdmBaseType(newBaseType);
+ break;
+ }
+ }
+ }
+ setBaseTypePropertiesForEntityType(entityBaseTypeMap);
+ }
+
+ private void setBaseTypePropertiesForEntityType(
+ Map<FullQualifiedName, FullQualifiedName> baseTypeMap) throws
EdmException{
+ changeAliasNamespaces(baseTypeMap);
+ while(!baseTypeMap.isEmpty()){
+ Iterator<Entry<FullQualifiedName, FullQualifiedName>> iterator =
baseTypeMap.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry<FullQualifiedName, FullQualifiedName> baseType = iterator.next();
+ if(baseTypeMap.get(baseType.getValue()) == null){
+ EdmEntityType entityType = entityTypesMap.get(baseType.getKey());
+ List<String> properties = entityType.getPropertyNames();
+ if(entityTypesMap.get(baseType.getValue())!=null){ //NOSONAR
+
properties.addAll(entityTypesMap.get(baseType.getValue()).getPropertyNames());
+ }
+ iterator.remove();
+ }
+ }
+ }
+ }
+ private void setBaseTypePropertiesForComplexType(
+ Map<FullQualifiedName, FullQualifiedName> baseTypeMap) throws
EdmException{
+ changeAliasNamespaces(baseTypeMap);
+ while(!baseTypeMap.isEmpty()){
+ Iterator<Entry<FullQualifiedName, FullQualifiedName>> iterator =
baseTypeMap.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry<FullQualifiedName, FullQualifiedName> baseType = iterator.next();
+ if(baseTypeMap.get(baseType.getValue()) == null){
+ EdmComplexType entityType = complexTypesMap.get(baseType.getKey());
+ List<String> properties = entityType.getPropertyNames();
+ if(complexTypesMap.get(baseType.getValue())!=null){ //NOSONAR
+
properties.addAll(complexTypesMap.get(baseType.getValue()).getPropertyNames());
+ }
+ iterator.remove();
+ }
+ }
+ }
+ }
+ private void changeAliasNamespaces(Map<FullQualifiedName, FullQualifiedName>
baseTypeMap) {
+ for(Entry<FullQualifiedName, FullQualifiedName>
entry:baseTypeMap.entrySet()){
+ if (aliasNamespaceMap.containsKey(entry.getKey().getNamespace())) {
+ FullQualifiedName value = baseTypeMap.get(entry.getKey());
+ FullQualifiedName name = new
FullQualifiedName(aliasNamespaceMap.get(entry.getKey().getNamespace()),
+ entry.getKey().getName());
+ baseTypeMap.put(name, value);
+ baseTypeMap.remove(entry.getKey());
+ }
+ if (aliasNamespaceMap.containsKey(entry.getValue().getNamespace())) {
+ FullQualifiedName value = new
FullQualifiedName(aliasNamespaceMap.get(entry.getValue().getNamespace()),
+ entry.getValue().getName());
+ baseTypeMap.remove(entry.getKey());
+ baseTypeMap.put(entry.getKey(), value);
+ }
+
+ }
+
+ }
+
+ private EdmUsingImpl readUsing(final XMLStreamReader reader, final String
schemaNamespace)
+ throws XMLStreamException, EntityProviderException {
+
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_USING);
+
+ EdmUsingImpl using = new EdmUsingImpl();
+ 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<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ 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 EdmEntityContainer readEntityContainer(final XMLStreamReader reader,
EdmImpl edm)//NOSONAR
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ENTITY_CONTAINER);
+ EdmEntityContainerImpl container = new EdmEntityContainerImpl(edm);
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+
+ List<EdmEntitySet> edmEntitySets = new ArrayList<EdmEntitySet>();
+ List<EdmFunctionImport> edmFunctionImports = new
ArrayList<EdmFunctionImport>();
+ List<EdmAssociationSet> edmAssociationSets = new
ArrayList<EdmAssociationSet>();
+
+ container.setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ if (reader.getAttributeValue(Edm.NAMESPACE_M_2007_08,
XmlMetadataConstants.EDM_CONTAINER_IS_DEFAULT) != null) {
+ container.setDefaultContainer(
+
"true".equalsIgnoreCase(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08,
+ "IsDefaultEntityContainer")));
+ defaultEdmEntityContainer = container;
+ }
+ container.setExtendz(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_CONTAINER_EXTENDZ));
+ List<EdmAnnotationAttribute> annotationAttribute =
readAnnotationAttribute(reader);
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ annotations.setAnnotationAttributes(annotationAttribute);
+ container.setAnnotations(annotations);
+
+ 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)) {
+ EdmEntitySetImpl entity = readEntitySet(reader);
+ entity.setEdmEntityContainer(container);
+ edmEntitySets.add(entity);
+ } else if
(XmlMetadataConstants.EDM_ASSOCIATION_SET.equals(currentHandledStartTagName)) {
+ EdmAssociationSet association = readAssociationSet(reader, edm);
+ edmAssociationSets.add(association);
+ } else if
(XmlMetadataConstants.EDM_FUNCTION_IMPORT.equals(currentHandledStartTagName)) {
+ edmFunctionImports.add(readFunctionImport(reader, edm));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ annotations.setAnnotationElements(annotationElements);
+ container.setAnnotations(annotations);
+ }
+ if (edmFunctionImports != null && !edmFunctionImports.isEmpty()) {
+ setContainerInFunctionImport(edmFunctionImports, container);
+ }
+ if (edmAssociationSets != null && !edmAssociationSets.isEmpty()) {
+ setConatinerInAssociationSet(edmAssociationSets, container);
+ }
+
container.setEdmEntitySets(edmEntitySets).setEdmAssociationSets(edmAssociationSets).setEdmFunctionImports(
+ edmFunctionImports);
+
+ containerMap.put(new FullQualifiedName(currentNamespace,
container.getName()),
+ container);
+ edmEntitySetList.addAll(edmEntitySets);
+ edmFunctionImportList.addAll(edmFunctionImports);
+ return container;
+ }
+
+ private void setConatinerInAssociationSet(List<EdmAssociationSet>
edmAssociationSets,
+ EdmEntityContainerImpl containerImpl) {
+ for (EdmAssociationSet associationSet : edmAssociationSets) {
+ EdmAssociationSetImpl assocationSetImpl = (EdmAssociationSetImpl)
associationSet;
+ assocationSetImpl.setEdmEntityContainer(containerImpl);
+ }
+ containerImpl.setEdmAssociationSetMap(associationSetMap);
+ }
+
+ /**
+ * @param functionImports
+ * @param containerImpl
+ */
+ private void setContainerInFunctionImport(List<EdmFunctionImport>
functionImports,
+ EdmEntityContainerImpl containerImpl) {
+ for (EdmFunctionImport funcImport : functionImports) {
+ EdmFunctionImportImpl functionImpl = (EdmFunctionImportImpl) funcImport;
+ functionImpl.setEdmEntityContainer(containerImpl);
+ }
+ }
+
+ private EdmFunctionImport readFunctionImport(final XMLStreamReader reader,
EdmImpl edm)
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_FUNCTION_IMPORT);
+ EdmFunctionImportImpl function = new EdmFunctionImportImpl();
+ ArrayList<EdmFunctionImportParameter> functionImportParameters = new
ArrayList<EdmFunctionImportParameter>();
+ Map<String, ArrayList<EdmFunctionImportParameter>> functionParameters =
+ new HashMap<String, ArrayList<EdmFunctionImportParameter>>();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ Map<String, EdmParameter> edmParamMap = new HashMap<String,
EdmParameter>();
+ List<String> parametersList = new ArrayList<String>();
+
+ 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);
+ EdmTypedImpl returnType = new EdmTypedImpl();
+ if (returnTypeString != null) {
+ 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);
+ ((EdmNamedImpl) returnType).setName(fqName.getName());
+ ((EdmNamedImpl) returnType).setEdm(edm);
+ function.setReturnType(returnType);
+ }
+ annotations.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))
{
+ EdmFunctionImportParameter edmFunctionImportParameter =
readFunctionImportParameter(reader);
+ functionImportParameters.add(edmFunctionImportParameter);
+ EdmParameterImpl edmParamImpl = new EdmParameterImpl();
+ edmParamImpl.setEdm(edm);
+ edmParamImpl.setName(edmFunctionImportParameter.getName());
+ edmParamImpl.setFacets(edmFunctionImportParameter.getFacets());
+ edmParamImpl.setMapping(edmFunctionImportParameter.getMapping());
+ edmParamImpl.setMultiplicity(returnType.getMultiplicity());
+ edmParamImpl.setParameter(edmFunctionImportParameter);
+
edmParamImpl.setTypeName(edmFunctionImportParameter.getType().getFullQualifiedName());
+
edmParamImpl.setAnnotations(edmFunctionImportParameter.getAnnotations());
+ parametersList.add(edmParamImpl.getName());
+ edmParamMap.put(edmFunctionImportParameter.getName(), edmParamImpl);
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ function.setAnnotations(annotations);
+ functionParameters.put(function.getName(), functionImportParameters);
+ function.setParameters(functionParameters);
+ function.setEdmParameters(edmParamMap);
+ function.setParametersList(parametersList);
+ return function;
+ }
+
+ private EdmFunctionImportParameter readFunctionImportParameter(final
XMLStreamReader reader)
+ throws EntityProviderException, XMLStreamException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_FUNCTION_PARAMETER);
+ EdmFunctionImportParameter functionParameter = new
EdmFunctionImportParameter();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+
+ 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()));
+ EdmFacets facets = readFacets(reader);
+ functionParameter.setFacets(facets);
+ annotations.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()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ functionParameter.setAnnotations(annotations);
+ return functionParameter;
+ }
+
+ private EdmAssociationSet readAssociationSet(final XMLStreamReader reader,
EdmImpl edm)
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ASSOCIATION_SET);
+ EdmAssociationSetImpl associationSet = new EdmAssociationSetImpl();
+ List<EdmAssociationSetEnd> ends = new ArrayList<EdmAssociationSetEnd>();
+ EdmAnnotationsImpl annotation = new EdmAnnotationsImpl();
+ String entitySetName = null;
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ 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));
+ }
+ annotation.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)) {
+ EdmAssociationSetEndImpl associationSetEnd = new
EdmAssociationSetEndImpl();
+ entitySetName = reader.getAttributeValue(null,
XmlMetadataConstants.EDM_ENTITY_SET);
+ associationSetEnd.setEntitySetName(entitySetName);
+ associationSetEnd.setRole(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_ROLE));
+ ends.add(associationSetEnd);
+ List<EdmAssociationSetEndImpl> associationSetEndList;
+ if(associationSetEndMap.get(entitySetName) == null){
+ associationSetEndList = new ArrayList<EdmAssociationSetEndImpl>();
+ }else{
+ associationSetEndList= associationSetEndMap.get(entitySetName);
+ }
+ associationSetEndList.add(associationSetEnd);
+ associationSetEndMap.put(entitySetName, associationSetEndList);
+ } 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));
+ associationSet.setEnd2(ends.get(1));
+ }
+ if (!annotationElements.isEmpty()) {
+ annotation.setAnnotationElements(annotationElements);
+ }
+ //Updating temporary map for association post processing
+
tempAssociationSetMap.put(associationSet.getAssociationSetFQName().toString(),
associationSet);
+ associationSet.setAnnotations(annotation);
+ associationSet.setEdm(edm);
+ return associationSet;
+ }
+
+ private EdmEntitySetImpl readEntitySet(final XMLStreamReader reader) throws
XMLStreamException,
+ EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ENTITY_SET);
+ EdmEntitySetImpl entitySet = new EdmEntitySetImpl();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ 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.setEdmEntityTypeName(fqName);
+ } else {
+ throw new
EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE
+
.addContent(XmlMetadataConstants.EDM_ENTITY_TYPE).addContent(XmlMetadataConstants.EDM_ENTITY_SET));
+ }
+ annotations.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()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ entitySet.setAnnotations(annotations);
+ return entitySet;
+ }
+
+ private EdmAssociation readAssociation(final XMLStreamReader reader, EdmImpl
edm)
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ASSOCIATION);
+
+ EdmAssociationImpl association = new EdmAssociationImpl();
+ association.setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ association.setNamespace(currentNamespace);
+ List<EdmMetadataAssociationEnd> associationEnds = new
ArrayList<EdmMetadataAssociationEnd>();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ annotations.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, edm));
+ } 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()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ association.setAnnotations(annotations);
+ association.setEdm(edm);
+ association.setAssociationEnds(associationEnds);
+ associationsMap.put(new FullQualifiedName(currentNamespace,
association.getName()), association);
+ return association;
+ }
+
+ private EdmReferentialConstraint readReferentialConstraint(final
XMLStreamReader reader) throws XMLStreamException,
+ EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ASSOCIATION_CONSTRAINT);
+ EdmReferentialConstraintImpl refConstraint = new
EdmReferentialConstraintImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ annotations.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()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ refConstraint.setAnnotations(annotations);
+ return refConstraint;
+ }
+
+ private EdmReferentialConstraintRole readReferentialConstraintRole(final
XMLStreamReader reader)
+ throws EntityProviderException, XMLStreamException, EdmException {
+ EdmReferentialConstraintRoleImpl rcRole = new
EdmReferentialConstraintRoleImpl();
+ rcRole.setRoleName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_ROLE));
+ List<EdmPropertyImpl> properties = new ArrayList<EdmPropertyImpl>();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ List<String> refNames = new ArrayList<String>();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ annotations.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)) {
+ EdmPropertyImpl property = (EdmPropertyImpl) readPropertyRef(reader);
+ properties.add(property );
+ refNames.add(property.getName());
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ rcRole.setProperty(properties);
+ rcRole.setRefNames(refNames);
+ rcRole.setAnnotations(annotations);
+ return rcRole;
+ }
+
+ private EdmComplexType readComplexType(final XMLStreamReader reader, Edm edm)
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_COMPLEX_TYPE);
+
+ EdmComplexTypeImpl complexType = new EdmComplexTypeImpl();
+ complexType.setEdmTypeKind(EdmTypeKind.COMPLEX);
+ List<EdmProperty> properties = new ArrayList<EdmProperty>();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ complexType.setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ complexType.setNamespace(currentNamespace);
+ String baseType = reader.getAttributeValue(null,
XmlMetadataConstants.EDM_BASE_TYPE);
+ if (baseType != null) {
+ FullQualifiedName fqname = extractFQName(baseType);
+ complexType.setBaseTypeName(fqname);
+ complexBaseTypeMap.put(new FullQualifiedName(complexType.getNamespace(),
complexType.getName()), fqname);
+ }
+ if (reader.getAttributeValue(null, XmlMetadataConstants.EDM_TYPE_ABSTRACT)
!= null) {
+
complexType.setAbstract("true".equalsIgnoreCase(reader.getAttributeValue(null,
+ XmlMetadataConstants.EDM_TYPE_ABSTRACT)));
+ }
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ annotations.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, edm));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ complexType.setProperties(properties);
+ List<String> edmPropertyNames = new ArrayList<String>();
+ for (EdmProperty name : properties) {
+ edmPropertyNames.add(name.getName());
+ }
+ complexType.setEdmPropertyNames(edmPropertyNames);
+ if (complexType.getName() != null) {
+ FullQualifiedName fqName = new FullQualifiedName(currentNamespace,
complexType.getName());
+ complexTypesMap.put(fqName, complexType);
+ if (complexPropertyMap.get(fqName) != null) {// POST processing to set
the edm types for complex types
+ ((EdmComplexPropertyImpl)
complexPropertyMap.get(fqName)).setEdmType(complexType);
+ }
+ } else {
+ throw new
EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("Name"));
+ }
+ return complexType;
+
+ }
+
+ private EdmEntityType readEntityType(final XMLStreamReader reader,
+ EdmImpl edm) throws XMLStreamException, EntityProviderException,
EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ENTITY_TYPE);
+ EdmEntityTypeImpl entityType = new EdmEntityTypeImpl();
+ List<EdmProperty> properties = new ArrayList<EdmProperty>();
+ List<String> edmPropertyNames = new ArrayList<String>();
+ List<EdmNavigationProperty> edmNavProperties = new
ArrayList<EdmNavigationProperty>();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ List<String> edmNavigationPropertyNames = new ArrayList<String>();
+ List<String> edmKeyPropertyNames = new ArrayList<String>();
+ List<EdmProperty> edmKeyProperties = new ArrayList<EdmProperty>();
+ EdmKeyImpl key = null;
+ ((EdmNamedImpl) entityType).setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ entityType.setNamespace(currentNamespace);
+ entityType.setEdm((EdmImpl) edm);
+ 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) {
+ FullQualifiedName fqName = extractFQName(baseType);
+ entityType.setBaseType(fqName);
+ //Populating base type map with child and parent for multiple inheritance
+ entityBaseTypeMap.put(extractFQNameFromEntityType(entityType), fqName);
+ }
+
entityType.setCustomizableFeedMappings(readCustomizableFeedMappings(reader));
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ annotations.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, edm));
+ } else if
(XmlMetadataConstants.EDM_NAVIGATION_PROPERTY.equals(currentHandledStartTagName))
{
+ edmNavProperties.add(readNavigationProperty(reader, edm));
+ } else {
+ annotationElements.add(readAnnotationElement(reader));
+ }
+ extractNamespaces(reader);
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+
+ for (EdmProperty property : properties) {
+ edmPropertyNames.add(property.getName());
+ if (key != null) {
+ for(EdmProperty keyProperty: key.getKeys()){
+ if(property.getName().equals(keyProperty.getName())){
+ edmKeyPropertyNames.add(keyProperty.getName());
+ edmKeyProperties.add(property);
+ }
+ }
+ }
+ }
+ for ( EdmNavigationProperty navigations : edmNavProperties){
+ edmNavigationPropertyNames.add(navigations.getName());
+ }
+
+ entityType.setAnnotations(annotations);
+ entityType.setEdmKeyProperties(edmKeyProperties);
+ entityType.setNavigationProperties(edmNavProperties);
+ entityType.setEdmNavigationPropertyNames(edmNavigationPropertyNames);
+ entityType.setEdmKeyPropertyNames(edmKeyPropertyNames);
+ entityType.setProperties(properties);
+ entityType.setEdmPropertyNames(edmPropertyNames);
+ 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 EdmKeyImpl readEntityTypeKey(final XMLStreamReader reader) throws
XMLStreamException,
+ EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ENTITY_TYPE_KEY);
+ List<EdmProperty> keys = new ArrayList<EdmProperty>();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ List<EdmAnnotationAttribute> 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));
+ }
+ }
+ }
+ EdmKeyImpl key = new
EdmKeyImpl().setKeys(keys).setAnnotationAttributes(annotationAttributes);
+ if (!annotationElements.isEmpty()) {
+ key.setAnnotationElements(annotationElements);
+ }
+ return key;
+ }
+
+ private EdmProperty readPropertyRef(final XMLStreamReader reader) throws
XMLStreamException,
+ EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_PROPERTY_REF);
+ EdmPropertyImpl propertyRef = new EdmPropertyRefImpl();
+ propertyRef.setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ EdmAnnotations annotations = new EdmAnnotationsImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ ((EdmAnnotationsImpl)
annotations).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()) {
+ ((EdmAnnotationsImpl)
annotations).setAnnotationElements(annotationElements);
+ }
+ propertyRef.setAnnotations(annotations);
+ return propertyRef;
+ }
+
+ private EdmNavigationProperty readNavigationProperty(final XMLStreamReader
reader, EdmImpl edm)
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_NAVIGATION_PROPERTY);
+
+ EdmNavigationPropertyImpl navProperty = new EdmNavigationPropertyImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ 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.setRelationshipName(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));
+ EdmAnnotations annotations = new EdmAnnotationsImpl();
+ ((EdmAnnotationsImpl)
annotations).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()) {
+ ((EdmAnnotationsImpl)
annotations).setAnnotationElements(annotationElements);
+ }
+ navProperty.setAnnotations(annotations);
+ navProperty.setEdm(edm);
+ navProperties.add(navProperty);
+ return navProperty;
+ }
+
+ private EdmProperty readProperty(final XMLStreamReader reader, Edm edm)
+ throws XMLStreamException, EntityProviderException, EdmException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_PROPERTY);
+ EdmPropertyImpl property;
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ 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, edm);
+ }
+ property.setFacets(readFacets(reader));
+ property.setCustomizableFeedMappings(readCustomizableFeedMappings(reader));
+ property.setMimeType(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08,
XmlMetadataConstants.M_MIMETYPE));
+ EdmAnnotations annotations = new EdmAnnotationsImpl();
+ ((EdmAnnotationsImpl)
annotations).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()) {
+ ((EdmAnnotationsImpl)
annotations).setAnnotationElements(annotationElements);
+ }
+ property.setAnnotations(annotations);
+ return property;
+ }
+
+ private EdmPropertyImpl readComplexProperty(final XMLStreamReader reader,
final FullQualifiedName fqName, Edm edm)
+ throws XMLStreamException, EdmException {
+ EdmComplexPropertyImpl property = new EdmComplexPropertyImpl();
+ property.setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ property.setTypeName(fqName);
+ property.setEdm((EdmImpl) edm);
+ complexPropertyMap.put(fqName, property);
+ return property;
+ }
+
+ private EdmPropertyImpl readSimpleProperty(final XMLStreamReader reader,
final FullQualifiedName fqName)
+ throws XMLStreamException, EdmException {
+ EdmSimplePropertyImpl property = new EdmSimplePropertyImpl();
+ property.setName(reader.getAttributeValue(null,
XmlMetadataConstants.EDM_NAME));
+ property.setTypeName(fqName);
+ property.setSimpleType(EdmSimpleTypeKind.valueOf(fqName.getName()));
+
property.setEdmType(EdmSimpleTypeFacadeImpl.getEdmSimpleType(property.getSimpleType()));
+ return property;
+ }
+
+ private EdmFacets 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) {
+ EdmFacets facets = new Facets();
+ if (isNullable != null) {
+ ((Facets) 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) facets).setMaxLength(Integer.MAX_VALUE);
+ } else {
+ ((Facets) facets).setMaxLength(Integer.parseInt(maxLength));
+ }
+ }
+ if (precision != null) {
+ ((Facets) facets).setPrecision(Integer.parseInt(precision));
+ }
+ if (scale != null) {
+ ((Facets) facets).setScale(Integer.parseInt(scale));
+ }
+ if (isFixedLength != null) {
+ ((Facets)
facets).setFixedLength("true".equalsIgnoreCase(isFixedLength));
+ }
+ if (isUnicode != null) {
+ ((Facets) facets).setUnicode("true".equalsIgnoreCase(isUnicode));
+ }
+ for (int i = 0; i < EdmConcurrencyMode.values().length; i++) {
+ if
(EdmConcurrencyMode.values()[i].name().equalsIgnoreCase(concurrencyMode)) {
+ ((Facets) facets).setConcurrencyMode(EdmConcurrencyMode.values()[i]);
+ }
+ }
+ ((Facets) facets).setDefaultValue(defaultValue);
+ ((Facets) facets).setCollation(collation);
+ return facets;
+ } else {
+ return null;
+ }
+ }
+
+ private EdmCustomizableFeedMappings 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) {
+ EdmCustomizableFeedMappings feedMapping = new
EdmCustomizableFeedMappingsImpl();
+ EdmCustomizableFeedMappingsImpl feedMappingImpl =
(EdmCustomizableFeedMappingsImpl) feedMapping;
+ if (keepInContent != null) {
+ feedMappingImpl.setFcKeepInContent("true".equals(keepInContent));
+ }
+ for (int i = 0; i < EdmContentKind.values().length; i++) {
+ if (EdmContentKind.values()[i].name().equalsIgnoreCase(contentKind)) {
+ feedMappingImpl.setFcContentKind(EdmContentKind.values()[i]);
+ }
+ }
+
feedMappingImpl.setFcTargetPath(targetPath).setFcSourcePath(sourcePath).setFcNsUri(nsUri).setFcNsPrefix(nsPrefix);
+ return feedMapping;
+ } else {
+ return null;
+ }
+
+ }
+
+ private EdmMetadataAssociationEnd readAssociationEnd(final XMLStreamReader
reader,
+ EdmImpl edm) throws EntityProviderException, XMLStreamException {
+ reader.require(XMLStreamConstants.START_ELEMENT, edmNamespace,
XmlMetadataConstants.EDM_ASSOCIATION_END);
+
+ EdmAssociationEndImpl associationEnd = new EdmAssociationEndImpl();
+ EdmAnnotationsImpl annotations = new EdmAnnotationsImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ 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.setEdm(edm);
+ associationEnd.setType(extractFQName(type));
+ annotations.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))
{
+ EdmOnDeleteImpl onDelete = new EdmOnDeleteImpl();
+ 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()) {
+ annotations.setAnnotationElements(annotationElements);
+ }
+ associationEnd.setAnnotations(annotations);
+ return associationEnd;
+ }
+
+ private EdmAnnotationElement readAnnotationElement(final XMLStreamReader
reader) throws XMLStreamException {
+ EdmAnnotationElementImpl elementImpl = new EdmAnnotationElementImpl();
+ List<EdmAnnotationElement> annotationElements = new
ArrayList<EdmAnnotationElement>();
+ List<EdmAnnotationAttribute> annotationAttributes = new
ArrayList<EdmAnnotationAttribute>();
+ elementImpl.setName(reader.getLocalName());
+ String elementNamespace = reader.getNamespaceURI();
+ if (!edmNamespaces.contains(elementNamespace)) {
+ elementImpl.setPrefix(reader.getPrefix());
+ elementImpl.setNamespace(elementNamespace);
+ }
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ EdmAnnotationAttributeImpl annotationAttribute = new
EdmAnnotationAttributeImpl();
+ 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()) {
+ elementImpl.setAttributes(annotationAttributes);
+ }
+
+ boolean justRead = false;
+ if (reader.hasNext()) {
+ reader.next();
+ justRead = true;
+ }
+
+ while (justRead && !(reader.isEndElement() && elementImpl.getName() != null
+ && elementImpl.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());
+ elementImpl.setText(elementText);
+ }
+ }
+ if (!annotationElements.isEmpty()) {
+ elementImpl.setChildElements(annotationElements);
+ }
+ return elementImpl;
+ }
+
+ private List<EdmAnnotationAttribute> readAnnotationAttribute(final
XMLStreamReader reader) {
+ List<EdmAnnotationAttribute> annotationAttributes = new
ArrayList<EdmAnnotationAttribute>();
+ 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
EdmAnnotationAttributeImpl().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;
+ }
+ //Ignoring the duplicate tags, parent tag namespace takes precedence
+ if (!xmlNamespaceMap.containsKey(namespacePrefix)) {
+ 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 extractFQNameFromEntityType(final EdmEntityType
entity)
+ throws EntityProviderException, EdmException {
+ return new FullQualifiedName(entity.getNamespace(), entity.getName());
+ }
+
+ 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,
EdmException {
+ for (Map.Entry<FullQualifiedName, EdmEntityType> entityTypes :
entityTypesMap.entrySet()) {
+ if (entityTypes.getValue() != null && entityTypes.getKey() != null) {
+ EdmEntityTypeImpl entityType = (EdmEntityTypeImpl)
entityTypes.getValue();
+ if (entityType.getBaseTypeName() != null) {
+ FullQualifiedName baseTypeFQName = entityType.getBaseTypeName();
+ EdmEntityType baseEntityType;
+ if (!entityTypesMap.containsKey(baseTypeFQName)) {
+ FullQualifiedName fqName =
validateEntityTypeWithAlias(baseTypeFQName);
+ baseEntityType = entityTypesMap.get(fqName);
+ } else {
+ baseEntityType = fetchLastBaseType(baseTypeFQName, entityTypesMap);
+ }
+ if (baseEntityType != null &&
+ (baseEntityType.getKeyProperties() == null ||
baseEntityType.getKeyProperties().isEmpty())) {
+ throw new
EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT
+ .addContent("Missing key for EntityType " +
baseEntityType.getName()));
+ }
+ } else if (entityType.getKeyProperties() == null ||
entityType.getKeyProperties().isEmpty()) {
+ 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 EdmEntityType fetchLastBaseType(FullQualifiedName baseTypeFQName,
+ Map<FullQualifiedName, EdmEntityType> entityTypesMap2)
+ throws EntityProviderException, EdmException {
+
+ EdmEntityTypeImpl baseEntityType = null;
+ while (baseTypeFQName != null) {
+ baseEntityType = (EdmEntityTypeImpl) entityTypesMap2.get(baseTypeFQName);
+ if(baseEntityType != null){
+ if (baseEntityType.getKeyPropertyNames() != null &&
!baseEntityType.getKeyPropertyNames().isEmpty()) {
+ break;
+ } else if (baseEntityType.getBaseType() != null) {
+ baseTypeFQName = baseEntityType.getBaseTypeName();
+ } 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,
EdmException {
+ for (Map.Entry<FullQualifiedName, EdmComplexType> complexTypes :
complexTypesMap.entrySet()) {
+ if (complexTypes.getValue() != null && complexTypes.getKey() != null) {
+ EdmComplexTypeImpl complexType = (EdmComplexTypeImpl)
complexTypes.getValue();
+ if (complexType.getBaseType() != null) {
+ FullQualifiedName baseTypeFQName = complexType.getEdmBaseTypeName();
+ if (!complexTypesMap.containsKey(baseTypeFQName)) {
+ validateComplexTypeWithAlias(baseTypeFQName);
+ }
+ }
+ }
+ }
+ }
+
+ private void validateRelationship() throws EntityProviderException,
EdmException {
+ for (EdmNavigationProperty navProperty : navProperties) {
+ EdmNavigationPropertyImpl navigationImpl = (EdmNavigationPropertyImpl)
navProperty;
+ if (associationsMap.containsKey(navigationImpl.getRelationshipName())) {
+ EdmAssociationImpl assoc = (EdmAssociationImpl)
associationsMap.get(navigationImpl.getRelationshipName());
+ 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(extractFQNameFromEntityType(assoc.getEnd1().getEntityType())))
{
+ EdmEntityType entityType = assoc.getEnd1().getEntityType();
+ validateEntityTypeWithAlias(extractFQNameFromEntityType(entityType));
+ }
+ if
(!entityTypesMap.containsKey(extractFQNameFromEntityType(assoc.getEnd2().getEntityType())))
{
+ EdmEntityType entityType = assoc.getEnd2().getEntityType();
+ validateEntityTypeWithAlias(extractFQNameFromEntityType(entityType));
+ }
+ } else {
+ throw new
EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent("Invalid
Relationship"));
+ }
+ }
+
+ }
+
+ private void validateAssociation() throws EntityProviderException,
EdmException {
+ for (Map.Entry<FullQualifiedName, EdmEntityContainer> container :
containerMap.entrySet()) {
+ for (EdmAssociationSet associationSet :
container.getValue().getAssociationSets()) {
+ FullQualifiedName association = new
FullQualifiedName(associationSet.getAssociation().getNamespace(),
+ associationSet.getAssociation().getName());
+ if (associationsMap.containsKey(association)) {
+ validateAssociationEnd(((EdmAssociationSetImpl)
associationSet).getEnd1(), associationsMap.get(association));
+ validateAssociationEnd(((EdmAssociationSetImpl)
associationSet).getEnd2(), associationsMap.get(association));
+ boolean end1 = false;
+ boolean end2 = false;
+ for (EdmEntitySet entitySet : container.getValue().getEntitySets()) {
+ EdmAssociationSetEnd associationSetEnd1 = ((EdmAssociationSetImpl)
associationSet).getEnd1();
+ if (entitySet.getName().equals(((EdmAssociationSetEndImpl)
associationSetEnd1).getEntitySetName())) {
+ end1 = true;
+ }
+ EdmAssociationSetEnd associationSetEnd2 = ((EdmAssociationSetImpl)
associationSet).getEnd2();
+ if (entitySet.getName().equals(((EdmAssociationSetEndImpl)
associationSetEnd2).getEntitySetName())) {
+ 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 EdmAssociationSetEnd end, final
EdmAssociation association)
+ throws EntityProviderException, EdmException {
+ 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,
EdmException {
+ for (Map.Entry<FullQualifiedName, EdmEntityContainer> container :
containerMap.entrySet()) {
+ for (EdmEntitySet entitySet : container.getValue().getEntitySets()) {
+ FullQualifiedName entityType =
extractFQNameFromEntityType(entitySet.getEntityType());
+ if (!(entityTypesMap.containsKey(entityType))) {
+ validateEntityTypeWithAlias(entityType);
+ }
+ }
+ }
+ }
+
+ private void validate() throws EntityProviderException, EdmException {
+ 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);
+
+ }
+}