com.sap.cds.adapter.odata.v4.metadata.cds.CdsServiceEdmEntityContainer 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.cds;
import static com.sap.cds.adapter.odata.v4.metadata.cds.CdsServiceEdmUtils.fqn;
import static com.sap.cds.adapter.odata.v4.metadata.cds.CdsServiceEdmUtils.isIncludedEntitySetAssociation;
import static com.sap.cds.adapter.odata.v4.metadata.cds.CdsServiceEdmUtils.isParameterized;
import static com.sap.cds.adapter.odata.v4.metadata.cds.CdsServiceEdmUtils.name;
import static com.sap.cds.adapter.odata.v4.metadata.cds.CdsServiceEdmUtils.target;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
import org.apache.olingo.commons.api.edm.provider.CsdlBindingTarget;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
import org.apache.olingo.commons.api.edm.provider.CsdlFunctionImport;
import org.apache.olingo.commons.api.edm.provider.CsdlNamed;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
import com.sap.cds.adapter.odata.v4.utils.mapper.EdmxFlavourMapper;
import com.sap.cds.reflect.CdsAction;
import com.sap.cds.reflect.CdsDefinition;
import com.sap.cds.reflect.CdsEntity;
import com.sap.cds.reflect.CdsFunction;
import com.sap.cds.reflect.CdsKind;
import com.sap.cds.reflect.CdsService;
import com.sap.cds.services.utils.model.CdsAnnotations;
class CdsServiceEdmEntityContainer extends CsdlEntityContainer {
static final String ENTITY_CONTAINER_NAME = "EntityContainer";
private final EdmxFlavourMapper edmxFlavourMapper;
private final Map entityLookup = new HashMap<>();
private final Map actionLookup = new HashMap<>();
private final Map functionLookup = new HashMap<>();
private final Map cached = new HashMap<>();
CdsServiceEdmEntityContainer(CdsService service, EdmxFlavourMapper edmxFlavourMapper) {
this.edmxFlavourMapper = edmxFlavourMapper;
service.entities()
.filter(CdsServiceEdmUtils::isIncludedEntitySet)
.forEach(e -> entityLookup.put(name(e), e));
service.actions().forEach(a -> actionLookup.put(name(a), a));
service.functions().forEach(f -> functionLookup.put(name(f), f));
setName(ENTITY_CONTAINER_NAME);
setEntitySets(null);
setSingletons(null);
setActionImports(null);
setFunctionImports(null);
}
@Override
public CsdlEntitySet getEntitySet(String name) {
CdsEntity entity = entityLookup.get(name);
if (entity != null && !CdsAnnotations.SINGLETON.isTrue(entity)) {
return (CsdlEntitySet) buildBindingTarget(entity);
}
return null;
}
@Override
public List getEntitySets() {
return entityLookup.values().stream().filter(e -> !CdsAnnotations.SINGLETON.isTrue(e))
.map(e -> (CsdlEntitySet) buildBindingTarget(e)).toList();
}
@Override
public CsdlSingleton getSingleton(String name) {
CdsEntity entity = entityLookup.get(name);
if (entity != null && CdsAnnotations.SINGLETON.isTrue(entity)) {
return (CsdlSingleton) buildBindingTarget(entity);
}
return null;
}
@Override
public List getSingletons() {
return entityLookup.values().stream().filter(CdsAnnotations.SINGLETON::isTrue)
.map(e -> (CsdlSingleton) buildBindingTarget(e)).toList();
}
private CsdlBindingTarget buildBindingTarget(CdsEntity entity) {
return (CsdlBindingTarget) cached.computeIfAbsent(entity, e -> {
boolean isParameterized = isParameterized(entity);
CsdlBindingTarget bindingTarget;
if (CdsAnnotations.SINGLETON.isTrue(entity)) {
bindingTarget = new CsdlSingleton();
} else {
bindingTarget = new CsdlEntitySet();
}
bindingTarget.setName(name(entity));
bindingTarget.setType(fqn(entity) + (isParameterized ? "Parameters" : ""));
edmxFlavourMapper.createMappings(entity).filter(m -> isIncludedEntitySetAssociation(m.getTargetElement())).forEach(assoc -> {
CsdlNavigationPropertyBinding binding = new CsdlNavigationPropertyBinding();
binding.setPath((isParameterized ? "Set/" : "") + assoc.getEdmxName());
binding.setTarget(name(target(entity, assoc.getTargetElement())));
bindingTarget.getNavigationPropertyBindings().add(binding);
});
if (isParameterized) {
CsdlNavigationPropertyBinding parametersBinding = new CsdlNavigationPropertyBinding();
parametersBinding.setPath("Set/Parameters");
parametersBinding.setTarget(name(entity));
bindingTarget.getNavigationPropertyBindings().add(parametersBinding);
}
return bindingTarget;
});
}
@Override
public CsdlActionImport getActionImport(String name) {
CdsAction action = actionLookup.get(name);
if (action != null) {
return buildActionImport(action);
}
return null;
}
@Override
public List getActionImports(String name) {
return List.of(getActionImport(name));
}
@Override
public List getActionImports() {
return actionLookup.values().stream().map(this::buildActionImport).toList();
}
private CsdlActionImport buildActionImport(CdsAction action) {
return (CsdlActionImport) cached.computeIfAbsent(action, a -> {
CsdlActionImport actionImport = new CsdlActionImport();
actionImport.setAction(fqn(action));
actionImport.setName(name(action));
action.returnType().filter(r -> r.getKind() == CdsKind.ENTITY)
.map(r -> name(r)).ifPresent(actionImport::setEntitySet);
return actionImport;
});
}
@Override
public CsdlFunctionImport getFunctionImport(String name) {
CdsFunction function = functionLookup.get(name);
if (function != null) {
return buildFunctionImport(function);
}
return null;
}
@Override
public List getFunctionImports(String name) {
return List.of(getFunctionImport(name));
}
@Override
public List getFunctionImports() {
return functionLookup.values().stream().map(this::buildFunctionImport).toList();
}
private CsdlFunctionImport buildFunctionImport(CdsFunction function) {
return (CsdlFunctionImport) cached.computeIfAbsent(function, f -> {
CsdlFunctionImport functionImport = new CsdlFunctionImport();
functionImport.setFunction(fqn(function));
functionImport.setName(name(function));
if (function.getReturnType().getKind() == CdsKind.ENTITY) {
functionImport.setEntitySet(name(function.getReturnType()));
}
return functionImport;
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy