com.sap.cds.adapter.odata.v4.metadata.ODataEdmProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cds-adapter-odata-v4 Show documentation
Show all versions of cds-adapter-odata-v4 Show documentation
OData V4 adapter for CDS Services Java
/**************************************************************************
* (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
**************************************************************************/
package com.sap.cds.adapter.odata.v4.metadata;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.edm.xml.Include;
import org.apache.olingo.client.api.edm.xml.Reference;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
import org.apache.olingo.commons.api.edm.provider.CsdlAliasInfo;
import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
import org.apache.olingo.commons.api.edm.provider.CsdlEnumType;
import org.apache.olingo.commons.api.edm.provider.CsdlFunction;
import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport;
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.commons.api.edmx.EdmxReferenceInclude;
import org.apache.olingo.commons.api.ex.ODataException;
import org.apache.olingo.commons.api.format.ContentType;
public class ODataEdmProvider extends CsdlAbstractEdmProvider {
private XMLMetadata xmlMetadata;
private volatile List csdlAliasInfo = null; // created lazily
public ODataEdmProvider(InputStream edmx) throws Exception {
ODataClient client = ODataClientFactory.getClient();
this.xmlMetadata = client.getDeserializer(ContentType.APPLICATION_XML).toMetadata(edmx);
if (!isV4Metadata()) {
throw new IllegalArgumentException("The provided bytes don't contain OData V4 Metadata");
}
}
XMLMetadata getXMLMetadata() {
return this.xmlMetadata;
}
boolean isServiceDocument() {
return ODataClientFactory.getClient().metadataValidation().isServiceDocument(xmlMetadata);
}
boolean isV4Metadata() throws Exception {
return ODataClientFactory.getClient().metadataValidation().isV4Metadata(xmlMetadata);
}
public List getAllEDMXReference(){
ArrayList edmxReferences = new ArrayList<>();
List referenceList = xmlMetadata.getReferences();
for (Reference ref : referenceList) {
EdmxReference reference = new EdmxReference(ref.getUri());
List includes = ref.getIncludes();
for (Include include : includes) {
reference.addInclude(new EdmxReferenceInclude(include.getNamespace(), include.getAlias()));
}
edmxReferences.add(reference);
}
return edmxReferences;
}
@Override
public List getSchemas() {
return xmlMetadata.getSchemas();
}
@Override
public CsdlEntityContainer getEntityContainer() throws ODataException {
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getEntityContainer() != null) {
return csdlSchema.getEntityContainer();
}
}
return null;
}
@Override
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getEntityContainer() != null) {
entityContainerInfo.setContainerName(
new FullQualifiedName(csdlSchema.getNamespace(), csdlSchema.getEntityContainer().getName()));
return entityContainerInfo;
}
}
return null;
}
@Override
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
List csdlSchemas = getSchemas();
String fqnContainer = null ;
for (CsdlSchema csdlSchema : csdlSchemas) {
// Only 1 EntityContainer in on Edmx file (V4 SPecification)
if (csdlSchema.getEntityContainer() == null) {
continue;
}
fqnContainer = csdlSchema.getNamespace()
+ (((csdlSchema.getEntityContainer() != null) ? ("." + csdlSchema.getEntityContainer().getName()) : ("")));
if (fqnContainer.equals(entityContainer.getFullQualifiedNameAsString())) {
return csdlSchema.getEntityContainer().getEntitySet(entitySetName);
}
}
return null;
}
@Override
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
/*-- Try to fetch the EntityType from the Current Schema --*/
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getNamespace().equals(entityTypeName.getNamespace())) {
return csdlSchema.getEntityType(entityTypeName.getName());
}
}
return null;
}
@Override
public CsdlComplexType getComplexType(FullQualifiedName complexTypeName) throws ODataException {
/*-- Try to fetch the ComplexType from the Current Schema --*/
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getNamespace().equals(complexTypeName.getNamespace())) {
return csdlSchema.getComplexType(complexTypeName.getName());
}
}
return null;
}
@Override
public CsdlFunctionImport getFunctionImport(FullQualifiedName entityContainer, String functionImportName)
throws ODataException {
List csdlSchemas = getSchemas();
CsdlFunctionImport funImport = null;
String fqnContainer = null;
for (CsdlSchema csdlSchema : csdlSchemas) {
// Only 1 EntityContainer in on Edmx file (V4 SPecification)
if (csdlSchema.getEntityContainer() == null) {
continue;
}
fqnContainer = csdlSchema.getNamespace()
+ ((csdlSchema.getEntityContainer() != null) ? ("." + csdlSchema.getEntityContainer().getName()) : (""));
if (fqnContainer.equals(entityContainer.getFullQualifiedNameAsString())) {
funImport = csdlSchema.getEntityContainer().getFunctionImport(functionImportName);
break;
}
}
return funImport;
}
@Override
public List getFunctions(FullQualifiedName functionName) throws ODataException {
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (Objects.equals(csdlSchema.getNamespace(), functionName.getNamespace()) ||
Objects.equals(csdlSchema.getAlias(), functionName.getNamespace())) {
return csdlSchema.getFunctions(functionName.getName());
}
}
return null;
}
@Override
public CsdlActionImport getActionImport(FullQualifiedName entityContainer, String actionImportName)
throws ODataException {
List csdlSchemas = getSchemas();
String fqnContainer = null;
for (CsdlSchema csdlSchema : csdlSchemas) {
// Only 1 EntityContainer in on Edmx file(V4 SPecification)
if (csdlSchema.getEntityContainer() == null) {
continue;
}
fqnContainer = csdlSchema.getNamespace() + "."
+ (csdlSchema.getEntityContainer() != null ? csdlSchema.getEntityContainer().getName() : "");
if (fqnContainer.equals(entityContainer.getFullQualifiedNameAsString())) {
return csdlSchema.getEntityContainer().getActionImport(actionImportName);
}
}
return null;
}
@Override
public List getActions(FullQualifiedName actionName) throws ODataException {
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (Objects.equals(csdlSchema.getNamespace(), actionName.getNamespace()) ||
Objects.equals(csdlSchema.getAlias(), actionName.getNamespace())) {
return csdlSchema.getActions(actionName.getName());
}
}
return Collections.emptyList();
}
@Override
public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException {
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
// FIXME: this seems to be wrong
return csdlSchema.getAnnotationGroup(targetName.getFullQualifiedNameAsString(), qualifier);
}
return null;
}
@Override
public CsdlTypeDefinition getTypeDefinition(FullQualifiedName typeDefinitionName) throws ODataException {
/*-- Try to fetch the Type from the Current Schema --*/
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getNamespace().equals(typeDefinitionName.getNamespace())) {
return csdlSchema.getTypeDefinition(typeDefinitionName.getName());
}
}
// Create the Type if not found. Required to show the Type name in metadata
if ("PropertyPath".equals(typeDefinitionName.getName())) {
return new CsdlTypeDefinition().setName("PropertyPath")
.setUnderlyingType(new FullQualifiedName("Edm", "String"));
} else if ("NavigationPropertyPath".equals(typeDefinitionName.getName())) {
return new CsdlTypeDefinition().setName("NavigationPropertyPath")
.setUnderlyingType(new FullQualifiedName("Edm", "String"));
} else if ("AnnotationPath".equals(typeDefinitionName.getName())) {
return new CsdlTypeDefinition().setName("AnnotationPath")
.setUnderlyingType(new FullQualifiedName("Edm", "String"));
} else if ("PrimitiveType".equals(typeDefinitionName.getName())) {
return new CsdlTypeDefinition().setName("PrimitiveType")
.setUnderlyingType(new FullQualifiedName("Edm", "String"));
}
return null;
}
@Override
public List getAliasInfos() throws ODataException {
if (csdlAliasInfo == null) {
List theCsdlAliasInfo = new ArrayList<>();
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
theCsdlAliasInfo.add(new CsdlAliasInfo().setAlias(csdlSchema.getAlias()));
}
// prevent that list can be read while it is still being built
csdlAliasInfo = theCsdlAliasInfo;
}
return csdlAliasInfo; // NOSONAR
}
@Override
public CsdlEnumType getEnumType(FullQualifiedName enumTypeName) throws ODataException {
/*-- Try to fetch the EntityType from the Current Schema --*/
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getNamespace().equals(enumTypeName.getNamespace())) {
return csdlSchema.getEnumType(enumTypeName.getName());
}
}
return null;
}
@Override
public CsdlSingleton getSingleton(FullQualifiedName entityContainer, String singletonName) throws ODataException {
CsdlSingleton csdlSingleton = null;
String fqnContainer = null;
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
// Only 1 EntityContainer in on Edmx file (V4 SPecification)
if (csdlSchema.getEntityContainer() == null) {
continue;
}
fqnContainer = csdlSchema.getNamespace() + "."
+ (csdlSchema.getEntityContainer() != null ? csdlSchema.getEntityContainer().getName() : "");
if (fqnContainer.equals(entityContainer.getFullQualifiedNameAsString())) {
csdlSingleton = csdlSchema.getEntityContainer().getSingleton(singletonName);
break;
}
}
return csdlSingleton;
}
@Override
public CsdlTerm getTerm(FullQualifiedName termName) throws ODataException {
/*-- Try to fetch the Term from the Current Schema --*/
List csdlSchemas = getSchemas();
for (CsdlSchema csdlSchema : csdlSchemas) {
if (csdlSchema.getNamespace().equals(termName.getNamespace())) {
return csdlSchema.getTerm(termName.getName());
}
}
// Create the Term if not found. Required to show the Term name in metadata
CsdlTerm csdlTerm = new CsdlTerm();
csdlTerm.setName(termName.getName());
csdlTerm.setType(termName.getFullQualifiedNameAsString());
return csdlTerm;
}
}