/** * personium.io * Modifications copyright 2014 FUJITSU LIMITED * * Licensed 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. * -------------------------------------------------- * This code is based on EdmxFormatParser.java of odata4j-core, and some modifications * for personium.io are applied by us. * - Add support for IsDeclared property and Format property in parseEdmProperty(). * - Add support for OpenType in parseEdmEntityType(). * -------------------------------------------------- * The copyright and the license text of the original code is as follows: */ /**************************************************************************** * Copyright (c) 2010 odata4j * * Licensed 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 com.fujitsu.dc.core.odata; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.core4j.Enumerable; import org.core4j.Func1; import org.core4j.Predicate1; import org.odata4j.core.ODataVersion; import org.odata4j.core.OPredicates; import org.odata4j.core.PrefixedNamespace; import org.odata4j.edm.EdmAssociation; import org.odata4j.edm.EdmAssociationEnd; import org.odata4j.edm.EdmAssociationSet; import org.odata4j.edm.EdmAssociationSetEnd; import org.odata4j.edm.EdmCollectionType; import org.odata4j.edm.EdmComplexType; import org.odata4j.edm.EdmDataServices; import org.odata4j.edm.EdmEntityContainer; import org.odata4j.edm.EdmEntitySet; import org.odata4j.edm.EdmEntityType; import org.odata4j.edm.EdmFunctionImport; import org.odata4j.edm.EdmFunctionParameter; import org.odata4j.edm.EdmFunctionParameter.Mode; import org.odata4j.edm.EdmMultiplicity; import org.odata4j.edm.EdmNavigationProperty; import org.odata4j.edm.EdmProperty; import org.odata4j.edm.EdmProperty.CollectionKind; import org.odata4j.edm.EdmSchema; import org.odata4j.edm.EdmType; import org.odata4j.format.xml.EdmxFormatParser; import org.odata4j.stax2.Attribute2; import org.odata4j.stax2.QName2; import org.odata4j.stax2.StartElement2; import org.odata4j.stax2.XMLEvent2; import org.odata4j.stax2.XMLEventReader2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fujitsu.dc.core.model.ctl.Common; import com.fujitsu.dc.core.model.ctl.CtlSchema; /** * barインストール時に使用するEdmxのXML解析用パーサクラス. */ public class DcEdmxFormatParser extends EdmxFormatParser { /** * ログ用オブジェクト. */ static Logger log = LoggerFactory.getLogger(DcEdmxFormatParser.class); private final EdmDataServices.Builder dataServices = EdmDataServices.newBuilder(); /** * コンストラクタ. */ public DcEdmxFormatParser() { } /** * Edmxの解析. * @param reader 解析用EdmxのReaderオブジェクト * @return EdmDataServices 解析したEdmxのJAXBオブジェクト */ @Override public EdmDataServices parseMetadata(XMLEventReader2 reader) { List<EdmSchema.Builder> schemas = new ArrayList<EdmSchema.Builder>(); List<PrefixedNamespace> namespaces = new ArrayList<PrefixedNamespace>(); namespaces.add(new PrefixedNamespace(Common.DC_NAMESPACE.getUri(), Common.DC_NAMESPACE.getPrefix())); ODataVersion version = null; boolean foundDataServices = false; while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); boolean shouldReturn = false; // if (isStartElement(event, XmlFormatParser.EDMX_EDMX)) { // // should extract the declared namespaces here... // } if (isStartElement(event, EDMX_DATASERVICES)) { foundDataServices = true; String str = getAttributeValueIfExists( event.asStartElement(), new QName2(NS_METADATA, "DataServiceVersion")); if (str != null) { version = ODataVersion.parse(str); } else { version = null; } } if (isStartElement(event, EDM2006_SCHEMA, EDM2007_SCHEMA, EDM2008_SCHEMA, EDM2009_SCHEMA)) { schemas.add(parseEdmSchema(reader, event.asStartElement())); if (!foundDataServices) { // some dallas services have Schema as the document element! shouldReturn = true; } } if (isEndElement(event, EDMX_DATASERVICES)) { shouldReturn = true; } if (shouldReturn) { dataServices.setVersion(version).addSchemas(schemas).addNamespaces(namespaces); resolve(); return dataServices.build(); } } throw new UnsupportedOperationException(); } /** * resolve. */ private void resolve() { final Map<String, EdmEntityType.Builder> allEetsByFQName = Enumerable.create(dataServices.getEntityTypes()).toMap(new Func1<EdmEntityType.Builder, String>() { public String apply(EdmEntityType.Builder input) { if (input.getFQAliasName() != null) { return input.getFQAliasName(); } else { return input.getFullyQualifiedTypeName(); } } }); final Map<String, EdmAssociation.Builder> allEasByFQName = Enumerable.create(dataServices.getAssociations()).toMap(new Func1<EdmAssociation.Builder, String>() { public String apply(EdmAssociation.Builder input) { if (input.getFQAliasName() != null) { return input.getFQAliasName(); } else { return input.getFQNamespaceName(); } } }); for (EdmSchema.Builder edmSchema : dataServices.getSchemas()) { // resolve associations for (int i = 0; i < edmSchema.getAssociations().size(); i++) { EdmAssociation.Builder tmpAssociation = edmSchema.getAssociations().get(i); tmpAssociation.getEnd1().setType(allEetsByFQName.get(tmpAssociation.getEnd1().getTypeName())); tmpAssociation.getEnd2().setType(allEetsByFQName.get(tmpAssociation.getEnd2().getTypeName())); } // resolve navproperties for (EdmEntityType.Builder eet : edmSchema.getEntityTypes()) { List<EdmNavigationProperty.Builder> navProps = eet.getNavigationProperties(); for (int i = 0; i < navProps.size(); i++) { final EdmNavigationProperty.Builder tmp = navProps.get(i); final EdmAssociation.Builder ea = allEasByFQName.get(tmp.getRelationshipName()); List<EdmAssociationEnd.Builder> finalEnds = Enumerable.create( tmp.getFromRoleName(), tmp.getToRoleName()) .select(new Func1<String, EdmAssociationEnd.Builder>() { public EdmAssociationEnd.Builder apply(String input) { if (ea.getEnd1().getRole().equals(input)) { return ea.getEnd1(); } if (ea.getEnd2().getRole().equals(input)) { return ea.getEnd2(); } throw new IllegalArgumentException("Invalid role name " + input); } }).toList(); tmp.setRelationship(ea).setFromTo(finalEnds.get(0), finalEnds.get(1)); } } // resolve entitysets for (EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getEntitySets().size(); i++) { final EdmEntitySet.Builder tmpEes = edmEntityContainer.getEntitySets().get(i); EdmEntityType.Builder eet = allEetsByFQName.get(tmpEes.getEntityTypeName()); if (eet == null) { throw new IllegalArgumentException("Invalid entity type " + tmpEes.getEntityTypeName()); } edmEntityContainer.getEntitySets().set( i, EdmEntitySet.newBuilder().setName(tmpEes.getName()).setEntityType(eet)); } } // resolve associationsets for (final EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getAssociationSets().size(); i++) { final EdmAssociationSet.Builder tmpEas = edmEntityContainer.getAssociationSets().get(i); final EdmAssociation.Builder ea = allEasByFQName.get(tmpEas.getAssociationName()); List<EdmAssociationSetEnd.Builder> finalEnds = Enumerable.create(tmpEas.getEnd1(), tmpEas.getEnd2()) .select(new Func1<EdmAssociationSetEnd.Builder, EdmAssociationSetEnd.Builder>() { public EdmAssociationSetEnd.Builder apply(final EdmAssociationSetEnd.Builder input) { EdmAssociationEnd.Builder eae = null; if (ea.getEnd1().getRole().equals(input.getRoleName())) { eae = ea.getEnd1(); } else if (ea.getEnd2().getRole().equals(input.getRoleName())) { eae = ea.getEnd2(); } if (eae == null) { throw new IllegalArgumentException("Invalid role name " + input.getRoleName()); } EdmEntitySet.Builder ees = Enumerable.create(edmEntityContainer.getEntitySets()) .first(OPredicates.nameEquals( EdmEntitySet.Builder.class, input.getEntitySetName())); return EdmAssociationSetEnd.newBuilder().setRole(eae).setEntitySet(ees); } }).toList(); tmpEas.setAssociation(ea).setEnds(finalEnds.get(0), finalEnds.get(1)); } } // resolve functionimports for (final EdmEntityContainer.Builder edmEntityContainer : edmSchema.getEntityContainers()) { for (int i = 0; i < edmEntityContainer.getFunctionImports().size(); i++) { final EdmFunctionImport.Builder tmpEfi = edmEntityContainer.getFunctionImports().get(i); EdmEntitySet.Builder ees = Enumerable.create( edmEntityContainer.getEntitySets()).firstOrNull(new Predicate1<EdmEntitySet.Builder>() { public boolean apply(EdmEntitySet.Builder input) { return input.getName().equals(tmpEfi.getEntitySetName()); } }); EdmType.Builder<?, ?> typeBuilder = null; if (tmpEfi.getReturnTypeName() != null) { typeBuilder = dataServices.resolveType(tmpEfi.getReturnTypeName()); if (typeBuilder == null) { throw new RuntimeException("Edm-type not found: " + tmpEfi.getReturnTypeName()); } if (tmpEfi.isCollection()) { typeBuilder = EdmCollectionType.newBuilder() .setKind(CollectionKind.Collection).setCollectionType(typeBuilder); } } edmEntityContainer.getFunctionImports().set(i, EdmFunctionImport.newBuilder() .setName(tmpEfi.getName()) .setEntitySet(ees) .setReturnType(typeBuilder) .setHttpMethod(tmpEfi.getHttpMethod()) .addParameters(tmpEfi.getParameters())); } } // resolve type hierarchy for (Entry<String, EdmEntityType.Builder> entry : allEetsByFQName.entrySet()) { String baseTypeName = entry.getValue().getFQBaseTypeName(); if (null != baseTypeName) { EdmEntityType.Builder baseType = allEetsByFQName.get(baseTypeName); if (baseType == null) { throw new IllegalArgumentException("Invalid baseType: " + baseTypeName); } entry.getValue().setBaseType(baseType); } } } } /** * parseEdmSchema. * @param reader reader * @param schemaElement schemaElement * @return EdmSchema.Builder */ private EdmSchema.Builder parseEdmSchema(XMLEventReader2 reader, StartElement2 schemaElement) { String schemaNamespace = schemaElement.getAttributeByName(new QName2("Namespace")).getValue(); String schemaAlias = getAttributeValueIfExists(schemaElement, new QName2("Alias")); final List<EdmEntityType.Builder> edmEntityTypes = new ArrayList<EdmEntityType.Builder>(); List<EdmComplexType.Builder> edmComplexTypes = new ArrayList<EdmComplexType.Builder>(); List<EdmAssociation.Builder> edmAssociations = new ArrayList<EdmAssociation.Builder>(); List<EdmEntityContainer.Builder> edmEntityContainers = new ArrayList<EdmEntityContainer.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (isStartElement(event, EDM2006_ENTITYTYPE, EDM2007_ENTITYTYPE, EDM2008_ENTITYTYPE, EDM2009_ENTITYTYPE)) { EdmEntityType.Builder edmEntityType = parseEdmEntityType(reader, schemaNamespace, schemaAlias, event.asStartElement()); edmEntityTypes.add(edmEntityType); } if (isStartElement( event, EDM2006_ASSOCIATION, EDM2007_ASSOCIATION, EDM2008_ASSOCIATION, EDM2009_ASSOCIATION)) { EdmAssociation.Builder edmAssociation = parseEdmAssociation(reader, schemaNamespace, schemaAlias, event.asStartElement()); edmAssociations.add(edmAssociation); } if (isStartElement( event, EDM2006_COMPLEXTYPE, EDM2007_COMPLEXTYPE, EDM2008_COMPLEXTYPE, EDM2009_COMPLEXTYPE)) { EdmComplexType.Builder edmComplexType = parseEdmComplexType(reader, schemaNamespace, event.asStartElement()); edmComplexTypes.add(edmComplexType); } if (isStartElement(event, EDM2006_ENTITYCONTAINER, EDM2007_ENTITYCONTAINER, EDM2008_ENTITYCONTAINER, EDM2009_ENTITYCONTAINER)) { // PMD指摘により、parseEdmEntityContainerの第2引数からschemaNamespaceを削除 EdmEntityContainer.Builder edmEntityContainer = parseEdmEntityContainer(reader, event.asStartElement()); edmEntityContainers.add(edmEntityContainer); } if (isEndElement(event, schemaElement.getName())) { return EdmSchema.newBuilder().setNamespace(schemaNamespace).setAlias(schemaAlias) .addEntityTypes(edmEntityTypes) .addComplexTypes(edmComplexTypes) .addAssociations(edmAssociations) .addEntityContainers(edmEntityContainers); } } throw new UnsupportedOperationException(); } /** * parseEdmEntityContainer. * @param reader reader * @param entityContainerElement entityContainerElement * @return EdmEntityContainer.Builder */ private EdmEntityContainer.Builder parseEdmEntityContainer( XMLEventReader2 reader, StartElement2 entityContainerElement) { String name = entityContainerElement.getAttributeByName("Name").getValue(); boolean isDefault = "true".equals( getAttributeValueIfExists(entityContainerElement, new QName2(NS_METADATA, "IsDefaultEntityContainer"))); String lazyLoadingEnabledValue = getAttributeValueIfExists(entityContainerElement, new QName2(NS_EDMANNOTATION, "LazyLoadingEnabled")); Boolean lazyLoadingEnabled = null; if (lazyLoadingEnabledValue != null) { lazyLoadingEnabled = lazyLoadingEnabledValue.equals("true"); } List<EdmEntitySet.Builder> edmEntitySets = new ArrayList<EdmEntitySet.Builder>(); List<EdmAssociationSet.Builder> edmAssociationSets = new ArrayList<EdmAssociationSet.Builder>(); List<EdmFunctionImport.Builder> edmFunctionImports = new ArrayList<EdmFunctionImport.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (isStartElement(event, EDM2006_ENTITYSET, EDM2007_ENTITYSET, EDM2008_ENTITYSET, EDM2009_ENTITYSET)) { edmEntitySets.add( EdmEntitySet.newBuilder().setName(getAttributeValueIfExists(event.asStartElement(), "Name")) .setEntityTypeName(getAttributeValueIfExists(event.asStartElement(), "EntityType"))); } // PMD指摘により、parseEdmAssociationSetの第2引数からschemaNamespaceを削除 if (isStartElement(event, EDM2006_ASSOCIATIONSET, EDM2007_ASSOCIATIONSET, EDM2008_ASSOCIATIONSET, EDM2009_ASSOCIATIONSET)) { edmAssociationSets.add(parseEdmAssociationSet(reader, event.asStartElement())); } // PMD指摘により、parseEdmFunctionImportの第2引数からschemaNamespaceを削除 if (isStartElement(event, EDM2006_FUNCTIONIMPORT, EDM2007_FUNCTIONIMPORT, EDM2008_FUNCTIONIMPORT, EDM2009_FUNCTIONIMPORT)) { edmFunctionImports.add(parseEdmFunctionImport(reader, event.asStartElement())); } if (isEndElement(event, entityContainerElement.getName())) { return EdmEntityContainer.newBuilder().setName(name) .setIsDefault(isDefault).setLazyLoadingEnabled(lazyLoadingEnabled) .addEntitySets(edmEntitySets) .addAssociationSets(edmAssociationSets).addFunctionImports(edmFunctionImports); } } throw new UnsupportedOperationException(); } /** * parseEdmFunctionImport. * @param reader reader * @param functionImportElement functionImportElement * @return EdmFunctionImport.Builder */ private EdmFunctionImport.Builder parseEdmFunctionImport( XMLEventReader2 reader, StartElement2 functionImportElement) { String name = functionImportElement.getAttributeByName("Name").getValue(); String entitySet = getAttributeValueIfExists(functionImportElement, "EntitySet"); Attribute2 returnTypeAttr = functionImportElement.getAttributeByName("ReturnType"); String returnType = null; if (returnTypeAttr != null) { returnType = returnTypeAttr.getValue(); } else { returnType = null; } // strict parsing boolean isCollection = null != returnType && returnType.matches("^Collection\\(.*\\)$"); if (isCollection) { final int beginIndex = 11; returnType = returnType.substring(beginIndex, returnType.length() - 1); } String httpMethod = getAttributeValueIfExists(functionImportElement, new QName2(NS_METADATA, "HttpMethod")); List<EdmFunctionParameter.Builder> parameters = new ArrayList<EdmFunctionParameter.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (isStartElement(event, EDM2006_PARAMETER, EDM2007_PARAMETER, EDM2008_PARAMETER, EDM2009_PARAMETER)) { // Mode attribute is optional and thus can be null Attribute2 modeAttribute = event.asStartElement().getAttributeByName("Mode"); Mode mode = null; if (modeAttribute != null) { mode = Mode.valueOf(modeAttribute.getValue()); } else { mode = null; } parameters.add(EdmFunctionParameter.newBuilder() .setName(event.asStartElement().getAttributeByName("Name").getValue()) //.setType(EdmType.get(event.asStartElement().getAttributeByName("Type").getValue())) .setType(EdmType.newDeferredBuilder( event.asStartElement().getAttributeByName("Type").getValue(), dataServices)) .setMode(mode)); } if (isEndElement(event, functionImportElement.getName())) { return EdmFunctionImport.newBuilder().setName(name).setEntitySetName(entitySet) .setReturnTypeName(returnType).setIsCollection(isCollection).setHttpMethod(httpMethod) .addParameters(parameters); } } throw new UnsupportedOperationException(); } /** * parseEdmAssociationSet. * @param reader reader * @param associationSetElement associationSetElement * @return EdmAssociationSet.Builder */ private EdmAssociationSet.Builder parseEdmAssociationSet( XMLEventReader2 reader, StartElement2 associationSetElement) { String name = associationSetElement.getAttributeByName("Name").getValue(); String associationName = associationSetElement.getAttributeByName("Association").getValue(); List<EdmAssociationSetEnd.Builder> ends = new ArrayList<EdmAssociationSetEnd.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (isStartElement(event, EDM2006_END, EDM2007_END, EDM2008_END, EDM2009_END)) { ends.add(EdmAssociationSetEnd.newBuilder() .setRoleName(event.asStartElement().getAttributeByName("Role").getValue()) .setEntitySetName(event.asStartElement().getAttributeByName("EntitySet").getValue())); } if (isEndElement(event, associationSetElement.getName())) { return EdmAssociationSet.newBuilder().setName(name) .setAssociationName(associationName).setEnds(ends.get(0), ends.get(1)); } } throw new UnsupportedOperationException(); } /** * parseEdmAssociation. * @param reader reader * @param schemaNamespace schemaNamespace * @param schemaAlias schemaAlias * @param associationElement associationElement * @return EdmAssociation.Builder */ private EdmAssociation.Builder parseEdmAssociation( XMLEventReader2 reader, String schemaNamespace, String schemaAlias, StartElement2 associationElement) { String name = associationElement.getAttributeByName("Name").getValue(); List<EdmAssociationEnd.Builder> ends = new ArrayList<EdmAssociationEnd.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (isStartElement(event, EDM2006_END, EDM2007_END, EDM2008_END, EDM2009_END)) { ends.add(EdmAssociationEnd.newBuilder() .setRole(event.asStartElement().getAttributeByName("Role").getValue()) .setTypeName(event.asStartElement().getAttributeByName("Type").getValue()) .setMultiplicity(EdmMultiplicity.fromSymbolString( event.asStartElement().getAttributeByName("Multiplicity").getValue()))); } if (isEndElement(event, associationElement.getName())) { return EdmAssociation.newBuilder().setNamespace(schemaNamespace). setAlias(schemaAlias).setName(name).setEnds(ends.get(0), ends.get(1)); } } throw new UnsupportedOperationException(); } /** * parseEdmProperty. * @param event event * @return EdmProperty.Builder */ private EdmProperty.Builder parseEdmProperty(XMLEvent2 event) { String propertyName = getAttributeValueIfExists(event.asStartElement(), "Name"); String propertyType = getAttributeValueIfExists(event.asStartElement(), "Type"); String propertyNullable = getAttributeValueIfExists(event.asStartElement(), "Nullable"); String maxLength = getAttributeValueIfExists(event.asStartElement(), "MaxLength"); String unicode = getAttributeValueIfExists(event.asStartElement(), "Unicode"); String fixedLength = getAttributeValueIfExists(event.asStartElement(), "FixedLength"); String collectionKindS = getAttributeValueIfExists(event.asStartElement(), "CollectionKind"); CollectionKind ckind = CollectionKind.NONE; if (null != collectionKindS) { ckind = Enum.valueOf(CollectionKind.class, collectionKindS); } String defaultValue = getAttributeValueIfExists(event.asStartElement(), "DefaultValue"); String precision = getAttributeValueIfExists(event.asStartElement(), "Precision"); String scale = getAttributeValueIfExists(event.asStartElement(), "Scale"); String isDeclared = getAttributeValueIfExists( event.asStartElement(), new QName2(Common.DC_NAMESPACE.getUri(), "IsDeclared")); String format = getAttributeValueIfExists( event.asStartElement(), new QName2(Common.DC_NAMESPACE.getUri(), "Format")); String storeGeneratedPattern = getAttributeValueIfExists( event.asStartElement(), new QName2(NS_EDMANNOTATION, "StoreGeneratedPattern")); String fcTargetPath = getAttributeValueIfExists(event.asStartElement(), M_FC_TARGETPATH); String fcContentKind = getAttributeValueIfExists(event.asStartElement(), M_FC_CONTENTKIND); String fcKeepInContent = getAttributeValueIfExists(event.asStartElement(), M_FC_KEEPINCONTENT); String fcEpmContentKind = getAttributeValueIfExists(event.asStartElement(), M_FC_EPMCONTENTKIND); String fcEpmKeepInContent = getAttributeValueIfExists(event.asStartElement(), M_FC_EPMKEEPINCONTENT); Integer maxLengthVal = null; if (maxLength != null) { if (maxLength.equals("Max")) { maxLengthVal = Integer.MAX_VALUE; } else { maxLengthVal = Integer.parseInt(maxLength); } } Integer precisionVal = null; if (precision != null) { precisionVal = Integer.parseInt(precision); } Integer scaleVal = null; if (scale != null) { scaleVal = Integer.parseInt(scale); } Boolean nullableVal = true; if (propertyNullable != null) { if (!"true".equals(propertyNullable) && !"false".equals(propertyNullable)) { String message = "Invalid Nullable value '%s'"; throw new IllegalArgumentException(String.format(message, propertyNullable)); } nullableVal = Boolean.parseBoolean(propertyNullable); } EdmProperty.Builder builder = EdmProperty.newBuilder(propertyName) .setType(EdmType.newDeferredBuilder(propertyType, dataServices)) .setNullable(nullableVal) .setMaxLength(maxLengthVal) .setUnicode("false".equals(unicode)) .setFixedLength("false".equals(fixedLength)) .setStoreGeneratedPattern(storeGeneratedPattern) .setFcTargetPath(fcTargetPath) .setFcContentKind(fcContentKind) .setFcKeepInContent(fcKeepInContent) .setFcEpmContentKind(fcEpmContentKind) .setFcEpmKeepInContent(fcEpmKeepInContent) .setCollectionKind(ckind) .setDefaultValue(defaultValue) .setPrecision(precisionVal) .setScale(scaleVal); if (isDeclared != null) { builder.setAnnotations(CtlSchema.createIsDecleardAnnotation(isDeclared)); } if (format != null) { builder.setAnnotations(CtlSchema.createFormatAnnotation(format)); } return builder; } /** * parseEdmComplexType. * @param reader reader * @param schemaNamespace schemaNamespace * @param complexTypeElement complexTypeElement * @return EdmComplexType.Builder */ private EdmComplexType.Builder parseEdmComplexType( XMLEventReader2 reader, String schemaNamespace, StartElement2 complexTypeElement) { String name = complexTypeElement.getAttributeByName("Name").getValue(); String isAbstractS = getAttributeValueIfExists(complexTypeElement, "Abstract"); List<EdmProperty.Builder> edmProperties = new ArrayList<EdmProperty.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (isStartElement(event, EDM2006_PROPERTY, EDM2007_PROPERTY, EDM2008_PROPERTY, EDM2009_PROPERTY)) { edmProperties.add(parseEdmProperty(event)); } if (isEndElement(event, complexTypeElement.getName())) { EdmComplexType.Builder complexType = EdmComplexType.newBuilder() .setNamespace(schemaNamespace).setName(name).addProperties(edmProperties); if (isAbstractS != null) { complexType.setIsAbstract("true".equals(isAbstractS)); } return complexType; } } throw new UnsupportedOperationException(); } /** * parseEdmEntityType. * @param reader reader * @param schemaNamespace schemaNamespace * @param schemaAlias schemaAlias * @param entityTypeElement entityTypeElement * @return EdmEntityType.Builder */ private EdmEntityType.Builder parseEdmEntityType( XMLEventReader2 reader, String schemaNamespace, String schemaAlias, StartElement2 entityTypeElement) { String name = entityTypeElement.getAttributeByName("Name").getValue(); String hasStreamValue = getAttributeValueIfExists(entityTypeElement, new QName2(NS_METADATA, "HasStream")); Boolean hasStream = null; if (hasStreamValue != null) { hasStream = hasStreamValue.equals("true"); } String baseType = getAttributeValueIfExists(entityTypeElement, "BaseType"); String openType = getAttributeValueIfExists(entityTypeElement, "OpenType"); String isAbstractS = getAttributeValueIfExists(entityTypeElement, "Abstract"); List<String> keys = new ArrayList<String>(); List<EdmProperty.Builder> edmProperties = new ArrayList<EdmProperty.Builder>(); List<EdmNavigationProperty.Builder> edmNavigationProperties = new ArrayList<EdmNavigationProperty.Builder>(); while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); if (event.isStartElement()) { StartElement2 stElem = event.asStartElement(); log.debug("tagName: " + stElem.getName()); log.debug("Nullable(API): " + stElem.getAttributeByName("Nullable")); } if (isStartElement(event, EDM2006_PROPERTYREF, EDM2007_PROPERTYREF, EDM2008_PROPERTYREF, EDM2009_PROPERTYREF)) { keys.add(event.asStartElement().getAttributeByName("Name").getValue()); } if (isStartElement(event, EDM2006_PROPERTY, EDM2007_PROPERTY, EDM2008_PROPERTY, EDM2009_PROPERTY)) { edmProperties.add(parseEdmProperty(event)); } if (isStartElement(event, EDM2006_NAVIGATIONPROPERTY, EDM2007_NAVIGATIONPROPERTY, EDM2008_NAVIGATIONPROPERTY, EDM2009_NAVIGATIONPROPERTY)) { String associationName = event.asStartElement().getAttributeByName("Name").getValue(); String relationshipName = event.asStartElement().getAttributeByName("Relationship").getValue(); String fromRoleName = event.asStartElement().getAttributeByName("FromRole").getValue(); String toRoleName = event.asStartElement().getAttributeByName("ToRole").getValue(); edmNavigationProperties.add(EdmNavigationProperty.newBuilder(associationName) .setRelationshipName(relationshipName).setFromToName(fromRoleName, toRoleName)); } if (isEndElement(event, entityTypeElement.getName())) { Boolean isAbstractVal = null; if (isAbstractS != null) { isAbstractVal = "true".equals(isAbstractS); } EdmEntityType.Builder builder = EdmEntityType.newBuilder() .setNamespace(schemaNamespace) .setAlias(schemaAlias) .setName(name) .setHasStream(hasStream) .addKeys(keys) .addProperties(edmProperties) .addNavigationProperties(edmNavigationProperties) .setBaseType(baseType) .setIsAbstract(isAbstractVal); if (openType != null) { builder.setAnnotations(CtlSchema.OPENTYPE); } return builder; } } throw new UnsupportedOperationException(); } }