public EdmDataServices parseMetadata(XMLEventReader2 reader) { List<EdmSchema.Builder> schemas = new ArrayList<EdmSchema.Builder>(); List<PrefixedNamespace> namespaces = null; ODataVersion version = null; boolean foundDataServices = false; while (reader.hasNext()) { XMLEvent2 event = reader.nextEvent(); boolean shouldReturn = false; if (event.isStartElement()) { if (isElement(event, XmlFormatParser.EDMX_EDMX)) { namespaces = getExtensionNamespaces(event.asStartElement()); } else if (isElement(event, EDMX_DATASERVICES)) { foundDataServices = true; String str = getAttributeValueIfExists( event.asStartElement(), new QName2(NS_METADATA, "DataServiceVersion")); version = str != null ? ODataVersion.parse(str) : null; } else if (isElement( event, EDM2006_SCHEMA, EDM2007_SCHEMA, EDM2008_1_SCHEMA, EDM2008_9_SCHEMA, EDM2009_8_SCHEMA, EDM2009_11_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(); }
private void resolve() { final Map<String, EdmEntityType.Builder> allEetsByFQName = Enumerable.create(dataServices.getEntityTypes()) .toMap(EdmEntityType.Builder.func1_getFullyQualifiedTypeName()); final Map<String, EdmEntityType.Builder> allEetsByFQAliasName = Enumerable.create(dataServices.getEntityTypes()) .where(EdmEntityType.Builder.pred1_hasAlias()) .toMap(EdmEntityType.Builder.func1_getFQAliasName()); final Map<String, EdmAssociation.Builder> allEasByFQName = Enumerable.create(dataServices.getAssociations()) .toMap(EdmAssociation.Builder.func1_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()); if (ea == null) throw new IllegalArgumentException( "Invalid relationship name " + 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) eet = allEetsByFQAliasName.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) .setAnnotationElements(tmpEes.getAnnotationElements()) .setAnnotations(tmpEes.getAnnotations())); } } // 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 = ea.getEnd1().getRole().equals(input.getRoleName()) ? ea.getEnd1() : ea.getEnd2().getRole().equals(input.getRoleName()) ? ea.getEnd2() : null; 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) .setAnnotationElements(input.getAnnotationElements()) .setAnnotations(input.getAnnotations()); } }) .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()) .setAnnotationElements(tmpEfi.getAnnotationElements()) .setAnnotations(tmpEfi.getAnnotations())); } } // resolve type hierarchy for (Entry<String, EdmEntityType.Builder> entry : allEetsByFQName.entrySet()) { String baseTypeName = entry.getValue().getFQBaseTypeName(); if (baseTypeName != null) { EdmEntityType.Builder baseType = allEetsByFQName.get(baseTypeName); if (baseType == null) { throw new IllegalArgumentException("Invalid baseType: " + baseTypeName); } entry.getValue().setBaseType(baseType); } } } }