com.sap.cds.adapter.odata.v2.metadata.ODataV2EdmProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cds-adapter-odata-v2 Show documentation
Show all versions of cds-adapter-odata-v2 Show documentation
OData V2 adapter for CDS Services Java
/**************************************************************************
* (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
**************************************************************************/
package com.sap.cds.adapter.odata.v2.metadata;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.odata2.api.edm.FullQualifiedName;
import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
import org.apache.olingo.odata2.api.edm.provider.Association;
import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
import org.apache.olingo.odata2.api.edm.provider.ComplexType;
import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
import org.apache.olingo.odata2.api.edm.provider.EntityContainerInfo;
import org.apache.olingo.odata2.api.edm.provider.EntitySet;
import org.apache.olingo.odata2.api.edm.provider.EntityType;
import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
import org.apache.olingo.odata2.api.edm.provider.Schema;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.core.commons.XmlHelper;
import org.apache.olingo.odata2.core.edm.provider.EdmxProvider;
public class ODataV2EdmProvider extends EdmProvider {
private static final String EDM_REFERENCE = "Reference";
private static final String EDM_INCLUDE = "Include";
private static final String EDM_NAMESPACE = "Namespace";
private static final String EDM_ALIAS = "Alias";
private static final String EDMX_INCLUDE = "edmx:Include";
private static final String XMLNS_EDMX = "xmlns:edmx";
private static final String EDMX_REFERENCE = "edmx:Reference";
private static final String EDMX = "edmx";
private static final String URI = "Uri";
private final EdmProvider provider;
private final Map edmxRefMap;
public ODataV2EdmProvider(InputStream edmxFile) throws ODataException, XMLStreamException, IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
IOUtils.copy(edmxFile, byteArrayOutputStream);
// copy the content of input stream to reuse it
byte[] inputContent = byteArrayOutputStream.toByteArray();
InputStream inputStream1 = new ByteArrayInputStream(inputContent);
this.provider = new EdmxProvider().parse(inputStream1, true);
InputStream inputStream2 = new ByteArrayInputStream(inputContent);
this.edmxRefMap = populateEdmxReference(inputStream2);
}
// Fetch the edmx reference tags part of the generated metadata file
private Map populateEdmxReference(InputStream is) throws ODataException, XMLStreamException {
Map edmxRefMap = new HashMap<>();
int index = 1;
XMLStreamReader streamReader = XmlHelper.createStreamReader(is);
while (streamReader.hasNext()) {
streamReader.next();
if (streamReader.getEventType() == XMLStreamConstants.START_ELEMENT) {
if (EDM_REFERENCE.equals(streamReader.getLocalName())) {
EdmxReference edmxRef = new EdmxReference();
if (streamReader.getNamespaceCount() != 0) {
edmxRef.setNamespacePrefix(streamReader.getNamespacePrefix(0));
edmxRef.setNamespaceUri(streamReader.getNamespaceURI(0));
}
edmxRef.setUri(streamReader.getAttributeValue(0));
streamReader.next();
if (streamReader.getEventType() == XMLStreamConstants.START_ELEMENT && EDM_INCLUDE.equals(streamReader.getLocalName())) {
for (int i = 0; i < streamReader.getAttributeCount(); i++) {
if (EDM_NAMESPACE.equals(streamReader.getAttributeName(i).toString())) {
edmxRef.setNamespace(streamReader.getAttributeValue(i));
}
else if (EDM_ALIAS.equals(streamReader.getAttributeName(i).toString())) {
edmxRef.setAlias(streamReader.getAttributeValue(i));
}
}
} else {
streamReader.next();
if (streamReader.getEventType() == XMLStreamConstants.START_ELEMENT && EDM_INCLUDE.equals(streamReader.getLocalName())) {
for (int i = 0; i < streamReader.getAttributeCount(); i++) {
if (EDM_NAMESPACE.equals(streamReader.getAttributeName(i).toString())) {
edmxRef.setNamespace(streamReader.getAttributeValue(i));
}
else if (EDM_ALIAS.equals(streamReader.getAttributeName(i).toString())) {
edmxRef.setAlias(streamReader.getAttributeValue(i));
}
}
}
}
edmxRefMap.put(index++, edmxRef);
}
}
}
return edmxRefMap;
}
public Map getEdmxReferencesMap() {
return edmxRefMap;
}
// Generate the edmx reference tags in the V2 metadata
public VocabAnnotationElement generateAnnotationElement(Map edmxRefMap) {
VocabAnnotationElement vocabEle = new VocabAnnotationElement();
List annoElements = new ArrayList();
for (int i = 0; i < edmxRefMap.size(); i++) {
EdmxReference edmxRef = edmxRefMap.get(i + 1);
List childAttributes = new ArrayList();
childAttributes.add(new AnnotationAttribute().setName(EDM_ALIAS).setText(edmxRef.getAlias()));
childAttributes.add(new AnnotationAttribute().setName(EDM_NAMESPACE).setText(edmxRef.getNamespace()));
List referenceAttributes = new ArrayList();
List childElements = new ArrayList();
childElements.add(new AnnotationElement().setName(EDMX_INCLUDE).setAttributes(childAttributes));
if (edmxRef.getNamespaceUri() != null) {
referenceAttributes.add(new AnnotationAttribute().setName(XMLNS_EDMX).setText(edmxRef.getNamespaceUri()));
}
referenceAttributes.add(new AnnotationAttribute().setName(URI).setText(edmxRef.getUri()));
annoElements.add(new AnnotationElement().setName(EDMX_REFERENCE).setPrefix(EDMX).setAttributes(referenceAttributes).setChildElements(childElements));
}
vocabEle.setAnnotationElements(annoElements);
return vocabEle;
}
@Override
public EntityContainerInfo getEntityContainerInfo(final String name)
throws ODataException {
// since no schema is specified, we take the first match in any schema
return getEntityContainer(getSchemas(), name);
}
private EntityContainer getEntityContainer(List schemas, String name) {
if (schemas == null) {
return null;
}
// since no schema is specified, we take the first match in any schema
for (Schema schema : schemas) {
List entityContainers = schema
.getEntityContainers();
if (entityContainers == null) {
return null;
}
for (EntityContainer entityContainer : entityContainers) {
if ((entityContainer.isDefaultEntityContainer() && name == null)
|| entityContainer.getName().equals(name)) {
return entityContainer;
}
}
}
return null;
}
@Override
public List getSchemas() throws ODataException {
return this.provider.getSchemas();
}
@Override
public EntitySet getEntitySet(final String entityContainer,
final String name) throws ODataException {
// since no schema is specified, we take the first match in any schema
EntityContainer container = getEntityContainer(getSchemas(),
entityContainer);
if (container == null) {
return null;
}
List sets = container.getEntitySets();
if (sets == null) {
return null;
}
for (EntitySet set : sets) {
if (set.getName().equals(name)) {
return set;
}
}
return null;
}
@Override
public AssociationSet getAssociationSet(final String entityContainer,
final FullQualifiedName association,
final String sourceEntitySetName, final String sourceEntitySetRole)
throws ODataException {
// since no schema is specified, we take the first match in any schema
EntityContainer container = getEntityContainer(getSchemas(),
entityContainer);
if (container == null) {
return null;
}
List sets = container.getAssociationSets();
if (sets == null) {
return null;
}
for (AssociationSet set : sets) {
if (set.getAssociation().getNamespace()
.equals(association.getNamespace())
&& set.getAssociation().getName()
.equals(association.getName())
&& ((set.getEnd1().getEntitySet().equals(sourceEntitySetName)
&& set.getEnd1().getRole().equals(sourceEntitySetRole)) || (set.getEnd2().getEntitySet().equals(sourceEntitySetName)
&& set.getEnd2().getRole().equals(sourceEntitySetRole)))) {
return set;
}
}
return null;
}
@Override
public FunctionImport getFunctionImport(final String entityContainer,
final String name) throws ODataException {
// since no schema is specified, we take the first match in any schema
EntityContainer container = getEntityContainer(getSchemas(),
entityContainer);
if (container == null) {
return null;
}
List functionImports = container.getFunctionImports();
if (functionImports == null) {
return null;
}
for (FunctionImport functionImport : functionImports) {
if (functionImport.getName().equals(name)) {
return functionImport;
}
}
return null;
}
@Override
public EntityType getEntityType(final FullQualifiedName edmFQName)
throws ODataException {
List schemas = getSchemas();
if (schemas == null) {
return null;
}
for (Schema schema : schemas) {
if (schema.getNamespace().equals(edmFQName.getNamespace())) {
List types = schema.getEntityTypes();
if (types == null) {
return null;
}
for (EntityType type : types) {
if (type.getName().equals(edmFQName.getName())) {
return type;
}
}
}
}
return null;
}
@Override
public ComplexType getComplexType(final FullQualifiedName edmFQName)
throws ODataException {
List schemas = getSchemas();
if (schemas == null) {
return null;
}
for (Schema schema : schemas) {
if (schema.getNamespace().equals(edmFQName.getNamespace())) {
List types = schema.getComplexTypes();
if (types == null) {
return null;
}
for (ComplexType type : types) {
if (type.getName().equals(edmFQName.getName())) {
return type;
}
}
}
}
return null;
}
@Override
public Association getAssociation(final FullQualifiedName edmFQName)
throws ODataException {
List schemas = getSchemas();
if (schemas == null) {
return null;
}
for (Schema schema : schemas) {
if (schema.getNamespace().equals(edmFQName.getNamespace())) {
List associations = schemas.get(0)
.getAssociations();
if (associations == null) {
return null;
}
for (Association association : associations) {
if (association.getName().equals(edmFQName.getName())) {
return association;
}
}
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy