blob: 956fa83431773907f1e38e5bb4a5f8641343ed10 [file] [log] [blame]
/*******************************************************************************
* 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.EdmTyped;
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.setNamespace(currentNamespace);
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>();
FullQualifiedName fqName ;
function.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME));
function.setHttpMethod(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08,
XmlMetadataConstants.EDM_FUNCTION_IMPORT_HTTP_METHOD));
String entitySet = reader.getAttributeValue(null, XmlMetadataConstants.EDM_ENTITY_SET);
function.setEntitySet(entitySet);
String returnTypeString = reader.getAttributeValue(null, XmlMetadataConstants.EDM_FUNCTION_IMPORT_RETURN);
EdmTypedImpl returnType = new EdmTypedImpl();
if (returnTypeString != null) {
if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) {
returnTypeString = returnTypeString.substring(returnTypeString.indexOf("(") + 1, returnTypeString.length() - 1);
returnType.setMultiplicity(EdmMultiplicity.MANY);
} else {
returnType.setMultiplicity(EdmMultiplicity.ONE);
}
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 validateFunctionImport() throws EntityProviderException, EdmException {
for (EdmFunctionImport functionImport : edmFunctionImportList) {
EdmTyped returnType = functionImport.getReturnType();
if (returnType != null) {
FullQualifiedName fqn = extractFQName(returnType.toString());
String entitySet = ((EdmFunctionImportImpl)functionImport).getEntitySetName();
if (returnType.getMultiplicity() == EdmMultiplicity.MANY && entitySet == null && entityTypesMap.get(
fqn) != null) {
throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("EntitySet = "
+ entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT + " = " + functionImport.getName()));
} else if (returnType.getMultiplicity() != EdmMultiplicity.MANY && entitySet != null && entityTypesMap.get(
fqn) == null) {
throw new EntityProviderException(EntityProviderException.INVALID_ATTRIBUTE.addContent("EntitySet = "
+ entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT
+ " = " + functionImport.getName()));
}
}
}
}
private void validate() throws EntityProviderException, EdmException {
checkMandatoryNamespacesAvailable();
validateEntityTypes();
validateComplexTypes();
validateRelationship();
validateEntitySet();
validateAssociation();
validateFunctionImport();
}
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);
}
}