com.sap.cds.reflect.impl.CdsEntityBuilder Maven / Gradle / Ivy
/************************************************************************
* © 2020-2024 SAP SE or an SAP affiliate company. All rights reserved. *
************************************************************************/
package com.sap.cds.reflect.impl;
import static com.sap.cds.impl.localized.LocaleUtils.isLocalizedEntityName;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.Select;
import com.sap.cds.ql.StructuredType;
import com.sap.cds.ql.cqn.CqnSelect;
import com.sap.cds.ql.cqn.Modifier;
import com.sap.cds.reflect.CdsAction;
import com.sap.cds.reflect.CdsAnnotation;
import com.sap.cds.reflect.CdsEntity;
import com.sap.cds.reflect.CdsFunction;
import com.sap.cds.reflect.CdsKind;
import com.sap.cds.reflect.CdsOperationNotFoundException;
import com.sap.cds.reflect.CdsParameter;
import com.sap.cds.util.ConstantLiteralSealingModifier;
import com.sap.cds.util.ProjectionQueryNormalizer;
public class CdsEntityBuilder extends CdsStructuredTypeBuilder {
private static final Logger logger = LoggerFactory.getLogger(CdsEntityBuilder.class);
public static final Modifier LITERAL_SEALING_MODIFIER = new ConstantLiteralSealingModifier();
private final boolean isAbstract;
private final boolean isView;
private final CqnSelect query;
private final String name;
private final Map> actions = new HashMap<>();
private final Map> functions = new HashMap<>();
private final List params = new ArrayList<>();
private CdsEntityImpl impl;
private CdsEntityBuilder(List> annotations, String name, String qualifiedName, boolean isAbstract,
CqnSelect query, boolean isView, String doc) {
super(annotations, qualifiedName, name, CdsKind.ENTITY, doc);
this.isAbstract = isAbstract;
this.query = query;
this.isView = isView;
this.name = name;
}
public static CdsEntityBuilder create(String name, String qualifiedName, List> annotations,
boolean isAbstract, String query, String doc) {
CqnSelect select = null;
boolean isView = query != null;
if (isView) {
try {
Select> parsedStatement = Select.cqn(query);
if (parsedStatement.from().isJoin()) {
select = parsedStatement; // Join cannot be copied
} else {
select = CQL.copy(parsedStatement, LITERAL_SEALING_MODIFIER);
if (!select.items().isEmpty() && select.from().isRef()) {
select = CQL.copy(select, new ProjectionQueryNormalizer(select.from().asRef()));
}
}
} catch (RuntimeException e) {
logger.warn(
"Query in view '{}' is not supported by CDS model reader and cannot be accessed via reflection: {}",
qualifiedName, query);
}
}
return new CdsEntityBuilder(annotations, name, qualifiedName, isAbstract, select, isView, doc);
}
public boolean isAbstract() {
return isAbstract;
}
public Stream> actions() {
return actions.values().stream();
}
void addAction(CdsOperationBuilder action) {
this.actions.put(action.getName(), action);
}
void addActions(List> actions) {
actions.forEach(this::addAction);
}
public Stream> functions() {
return functions.values().stream();
}
void addFunction(CdsOperationBuilder function) {
this.functions.put(function.getName(), function);
}
void addFunctions(List> functions) {
functions.forEach(this::addFunction);
}
void addParams(List params) {
this.params.addAll(params);
}
@Override
public CdsEntity build() {
if (impl == null) {
impl = new CdsEntityImpl(annotations, name, qualifiedName, isAbstract(), query, params, isView, doc);
putElements(impl);
actions.forEach((n, ab) -> impl.actions.put(ab.getName(), ab.build()));
functions.forEach((n, fb) -> impl.functions.put(fb.getName(), fb.build()));
}
return impl;
}
@Override
boolean toBeIgnored(String path) {
return super.toBeIgnored(path) || isLocalizedEntityName(path);
}
private static class CdsEntityImpl extends CdsStructuredTypeBuilder.CdsStructuredTypeImpl implements CdsEntity {
private final boolean isAbstract;
private final boolean isView;
private final CqnSelect query;
private final List params;
private final Map actions = new HashMap<>();
private final Map functions = new HashMap<>();
private CdsEntityImpl(Collection> annotations, String name, String qualifiedName,
boolean isAbstract, CqnSelect query, List params, boolean isView, String doc) {
super(annotations, qualifiedName, name, doc);
this.isAbstract = isAbstract;
this.query = query;
this.params = params;
this.isView = isView;
}
@Override
public boolean isAbstract() {
return isAbstract;
}
@Override
public boolean isView() {
return isView;
}
@Override
public boolean isProjection() {
throw new UnsupportedOperationException();
}
@Override
public Optional query() {
return Optional.ofNullable(query);
}
@Override
public Stream params() {
return params.stream();
}
@Override
public Stream actions() {
return actions.values().stream();
}
@Override
public CdsAction getAction(String name) {
return findAction(name).orElseThrow(() -> new CdsOperationNotFoundException(CdsKind.ACTION, name, this));
}
@Override
public Optional findAction(String name) {
return Optional.ofNullable(actions.get(name));
}
@Override
public Stream functions() {
return functions.values().stream();
}
@Override
public CdsFunction getFunction(String name) {
return findFunction(name)
.orElseThrow(() -> new CdsOperationNotFoundException(CdsKind.FUNCTION, name, this));
}
@Override
public Optional findFunction(String name) {
return Optional.ofNullable(functions.get(name));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy