com.sap.cds.generator.Cds4jCodegen Maven / Gradle / Ivy
/*******************************************************************
* © 2019 SAP SE or an SAP affiliate company. All rights reserved. *
*******************************************************************/
package com.sap.cds.generator;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.util.Collection;
import java.util.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.sap.cds.generator.Cds4jCodegen.Result.Status;
import com.sap.cds.generator.util.GeneratedFile.Consumer;
import com.sap.cds.generator.util.GeneratorMode;
import com.sap.cds.generator.util.ParserMode;
import com.sap.cds.generator.writer.ModelWriter;
import com.sap.cds.reflect.CdsDefinition;
import com.sap.cds.reflect.CdsModel;
import com.sap.cds.reflect.CdsVisitor;
import com.sap.cds.reflect.impl.CdsAnnotatableImpl;
import com.sap.cds.reflect.impl.CdsModelReader;
import com.sap.cds.reflect.impl.reader.issuecollector.Issue;
import com.sap.cds.reflect.impl.reader.issuecollector.IssueCollector;
import com.sap.cds.reflect.impl.reader.issuecollector.IssueCollectorFactory;
import com.sap.cds.reflect.impl.reader.issuecollector.IssueType;
import com.sap.cds.reflect.impl.reader.model.CdsConstants;
public class Cds4jCodegen {
private static final Logger logger = LoggerFactory.getLogger(Cds4jCodegen.class);
private static final IssueCollector issueCollector = IssueCollectorFactory.getIssueCollector(Cds4jCodegen.class);
private final Configuration cfg;
public Cds4jCodegen(Configuration cfg) {
this.cfg = cfg;
}
public Result generate(CsnSupplier csn, Consumer consumer) throws IOException {
IssueCollectorFactory.clearIssues();
IssueCollectorFactory.enableUnrecognizedLogging();
Result result = new Result();
try {
CdsModel cdsModel = CdsModelReader.read(
new CdsModelReader.Config.Builder().setReadDocs(true).build(),
new String(csn.get(), UTF_8), false);
result.status = generate(cdsModel, consumer);
} catch (NoSuchFileException e) {
String msg = "CSN file not found: ";
logger.debug(msg, e);
issueCollector.critical("", msg + e.getFile());
} catch (Throwable t) { // NOSONAR
logger.error("Stopped execution due to exception: ", t);
issueCollector.critical("", t.getMessage());
}
result.issues.addAll(IssueCollectorFactory.getIssues());
return result;
}
private Status generate(CdsModel cdsModel, Consumer consumer) {
if (noRelevantIssues(cfg.getParserMode(), cfg.getGeneratorMode())) {
CdsVisitor visitor = new ModelWriter(consumer, cfg, cdsModel);
cdsModel.accept(visitor);
return Status.SUCCESS;
}
return Status.FAILURE;
}
protected static boolean noRelevantIssues(ParserMode parserMode, GeneratorMode generatorMode) {
if (IssueCollectorFactory.hasIssues(IssueType.CRITICAL)) {
return false;
}
if (parserMode == ParserMode.STRICT && IssueCollectorFactory.hasIssues(IssueType.UNRECOGNIZED)) {
return false;
}
if (generatorMode == GeneratorMode.STRICT) {
if (IssueCollectorFactory.hasIssues(IssueType.ERROR)) {
return false;
}
if (IssueCollectorFactory.hasIssues(IssueType.UNSUPPORTED)) {
return false;
}
}
return true;
}
@FunctionalInterface
public interface CsnSupplier {
byte[] get() throws IOException;
}
public static class Result {
final Collection issues = Lists.newLinkedList();
Status status = Status.FAILURE;
public Status getStatus() {
return status;
}
public Collection getIssues() {
return Collections.unmodifiableCollection(issues);
}
public enum Status {
SUCCESS, FAILURE
}
}
/**
* Checks whether the given {@link CdsDefinition} is to be ignored by the code
* generation.
*
* @param def the cds definition
* @return true if to be ignored by the code gen, false otherwise
*/
public static boolean isIgnored(CdsDefinition def) {
String cdsJavaIgnore = CdsAnnotatableImpl.removeAt(CdsConstants.ANNOTATION_CDS_JAVA_IGNORE);
return def.getAnnotationValue(cdsJavaIgnore, false);
}
}