Search in sources :

Example 36 with CobiGenRuntimeException

use of com.devonfw.cobigen.api.exception.CobiGenRuntimeException in project cobigen by devonfw.

the class GenerationProcessorImpl method generate.

/**
 * Generates code for the given input with the given template and the given {@link TriggerInterpreter} to the
 * destination specified by the templates configuration.
 *
 * @param template to be processed for generation
 * @param triggerInterpreter {@link TriggerInterpreter} to be used for reading the input and creating the model
 * @param origToTmpFileTrace the mapping of temporary generated files to their original target destination to
 *        eventually finalizing the generation process
 * @param progressCallback to track progress
 * @throws InvalidConfigurationException if the inputs do not fit to the configuration or there are some configuration
 *         failures
 */
private void generate(TemplateTo template, TriggerInterpreter triggerInterpreter, Map<File, File> origToTmpFileTrace, BiConsumer<String, Integer> progressCallback) {
    Trigger trigger = this.configurationHolder.readContextConfiguration().getTrigger(template.getTriggerId());
    InputReader inputReader = triggerInterpreter.getInputReader();
    if (!inputReader.isValidInput(this.input)) {
        throw new CobiGenRuntimeException("An invalid input of type " + this.input.getClass() + " has been passed to " + inputReader.getClass() + " (derived from trigger '" + trigger.getId() + "')");
    }
    List<Object> inputObjects = this.inputResolver.resolveContainerElements(this.input, trigger);
    TemplatesConfiguration tConfig = this.configurationHolder.readTemplatesConfiguration(trigger);
    String templateEngineName = tConfig.getTemplateEngine();
    TextTemplateEngine templateEngine = TemplateEngineRegistry.getEngine(templateEngineName);
    templateEngine.setTemplateFolder(this.configurationHolder.readContextConfiguration().getConfigurationPath().resolve(trigger.getTemplateFolder()));
    Template templateEty = tConfig.getTemplate(template.getId());
    if (templateEty == null) {
        throw new UnknownTemplateException(template.getId());
    }
    for (Object generatorInput : inputObjects) {
        progressCallback.accept("Building template model for input " + generatorInput, 1);
        Map<String, Object> model = buildModel(triggerInterpreter, trigger, generatorInput, templateEty);
        String targetCharset = templateEty.getTargetCharset();
        // resolve temporary file paths
        @SuppressWarnings("unchecked") PathExpressionResolver pathExpressionResolver = new PathExpressionResolver(Variables.fromMap((Map<String, String>) model.get(ModelBuilderImpl.NS_VARIABLES)));
        String resolvedTargetDestinationPath = pathExpressionResolver.evaluateExpressions(templateEty.getUnresolvedTargetPath());
        String resolvedTmpDestinationPath = pathExpressionResolver.evaluateExpressions(templateEty.getUnresolvedTemplatePath());
        File originalFile = this.targetRootPath.resolve(resolvedTargetDestinationPath).toFile();
        File tmpOriginalFile;
        if (origToTmpFileTrace.containsKey(originalFile)) {
            // use the available temporary file
            tmpOriginalFile = origToTmpFileTrace.get(originalFile);
        } else {
            tmpOriginalFile = this.tmpTargetRootPath.resolve(resolvedTmpDestinationPath).toFile();
            // remember mapping to later on copy the generated resources to its target destinations
            origToTmpFileTrace.put(originalFile, tmpOriginalFile);
        }
        if (originalFile.exists() || tmpOriginalFile.exists()) {
            if (!tmpOriginalFile.exists()) {
                try {
                    FileUtils.copyFile(originalFile, tmpOriginalFile);
                } catch (IOException e) {
                    throw new CobiGenRuntimeException("Could not copy file " + originalFile.getPath() + " to tmp generation directory! Generation skipped.", e);
                }
            }
            if ((this.forceOverride || template.isForceOverride()) && templateEty.getMergeStrategy() == null || ConfigurationConstants.MERGE_STRATEGY_OVERRIDE.equals(templateEty.getMergeStrategy())) {
                try (Formatter formatter = new Formatter()) {
                    formatter.format("Overriding %1$-40s FROM %2$-50s TO %3$s ...", originalFile.getName(), templateEty.getName(), resolvedTargetDestinationPath);
                    LOG.info(formatter.out().toString());
                    progressCallback.accept(formatter.out().toString(), 1);
                }
                progressCallback.accept("Generating " + template.getId() + " for " + generatorInput, 1);
                generateTemplateAndWriteFile(tmpOriginalFile, templateEty, templateEngine, model, targetCharset);
            } else if (templateEty.getMergeStrategy() != null) {
                try (Formatter formatter = new Formatter()) {
                    formatter.format("Merging    %1$-40s FROM %2$-50s TO %3$s ...", originalFile.getName(), templateEty.getName(), resolvedTargetDestinationPath);
                    LOG.info(formatter.out().toString());
                    progressCallback.accept(formatter.out().toString(), 1);
                }
                String patch = null;
                try (Writer out = new StringWriter()) {
                    templateEngine.process(templateEty, model, out, targetCharset);
                    patch = out.toString();
                    String mergeResult = null;
                    Merger merger = PluginRegistry.getMerger(templateEty.getMergeStrategy());
                    if (merger != null) {
                        mergeResult = merger.merge(tmpOriginalFile, patch, targetCharset);
                    } else {
                        throw new PluginNotAvailableException("merge strategy '" + templateEty.getMergeStrategy() + "'", null);
                    }
                    if (mergeResult != null) {
                        LOG.debug("Merge {} with char set {}.", tmpOriginalFile.getName(), targetCharset);
                        FileUtils.writeStringToFile(tmpOriginalFile, mergeResult, targetCharset);
                    } else {
                        throw new PluginProcessingException("Merger " + merger.getType() + " returned null on merge(...), which is not allowed.");
                    }
                } catch (MergeException e) {
                    writeBrokenPatchFile(targetCharset, tmpOriginalFile, patch);
                    // enrich merge exception to provide template ID
                    throw new MergeException(e, templateEty.getAbsoluteTemplatePath());
                } catch (IOException e) {
                    throw new CobiGenRuntimeException("Could not write file " + tmpOriginalFile.toPath() + " after merge.", e);
                }
            }
        } else {
            try (Formatter formatter = new Formatter()) {
                formatter.format("Generating %1$-40s FROM %2$-50s TO %3$s ...", originalFile.getName(), templateEty.getName(), resolvedTargetDestinationPath);
                LOG.info(formatter.out().toString());
                progressCallback.accept(formatter.out().toString(), 1);
            }
            generateTemplateAndWriteFile(tmpOriginalFile, templateEty, templateEngine, model, targetCharset);
        }
    }
}
Also used : CobiGenRuntimeException(com.devonfw.cobigen.api.exception.CobiGenRuntimeException) Formatter(java.util.Formatter) IOException(java.io.IOException) PluginNotAvailableException(com.devonfw.cobigen.api.exception.PluginNotAvailableException) PluginProcessingException(com.devonfw.cobigen.impl.exceptions.PluginProcessingException) TemplatesConfiguration(com.devonfw.cobigen.impl.config.TemplatesConfiguration) Template(com.devonfw.cobigen.impl.config.entity.Template) InputReader(com.devonfw.cobigen.api.extension.InputReader) Trigger(com.devonfw.cobigen.impl.config.entity.Trigger) Merger(com.devonfw.cobigen.api.extension.Merger) StringWriter(java.io.StringWriter) TextTemplateEngine(com.devonfw.cobigen.api.extension.TextTemplateEngine) MergeException(com.devonfw.cobigen.api.exception.MergeException) UnknownTemplateException(com.devonfw.cobigen.impl.exceptions.UnknownTemplateException) Map(java.util.Map) File(java.io.File) PathExpressionResolver(com.devonfw.cobigen.impl.config.resolver.PathExpressionResolver) Writer(java.io.Writer) StringWriter(java.io.StringWriter)

Example 37 with CobiGenRuntimeException

use of com.devonfw.cobigen.api.exception.CobiGenRuntimeException in project cobigen by devonfw.

the class TemplateEngineRegistry method register.

/**
 * Registers a new {@link TextTemplateEngine template engine}
 *
 * @param <T> type of the {@link TextTemplateEngine template engine} to be registered
 * @param templateEngine {@link TextTemplateEngine template engine} to be registered
 * @param name of the template engine
 */
public static <T extends TextTemplateEngine> void register(Class<T> templateEngine, String name) {
    try {
        TextTemplateEngine engine = templateEngine.newInstance();
        LOG.info("Register template engine '{}'.", templateEngine.getCanonicalName());
        if (StringUtils.isNotBlank(name)) {
            if (registeredEngines.containsKey(name)) {
                throw new CobiGenRuntimeException("An template engine with name " + name + " has already been registered.");
            }
            registeredEngines.put(name, engine);
        } else {
            throw new CobiGenRuntimeException("Cannot register a template engine without a type.");
        }
    } catch (InstantiationException | IllegalAccessException e) {
        throw new CobiGenRuntimeException("Could not intantiate TemplateEngine '" + templateEngine.getCanonicalName(), e);
    }
}
Also used : CobiGenRuntimeException(com.devonfw.cobigen.api.exception.CobiGenRuntimeException) TextTemplateEngine(com.devonfw.cobigen.api.extension.TextTemplateEngine)

Example 38 with CobiGenRuntimeException

use of com.devonfw.cobigen.api.exception.CobiGenRuntimeException in project cobigen by devonfw.

the class ConfigurationInterpreterImpl method resolveTemplateDestinationPath.

@Override
public Path resolveTemplateDestinationPath(Path targetRootPath, TemplateTo template, Object input) {
    Trigger trigger = this.configurationHolder.readContextConfiguration().getTrigger(template.getTriggerId());
    InputValidator.validateTrigger(trigger);
    TriggerInterpreter triggerInterpreter = PluginRegistry.getTriggerInterpreter(trigger.getType());
    // the GenerationReportTo won't be further processed
    Variables variables = new ContextVariableResolver(input, trigger).resolveVariables(triggerInterpreter, new GenerationReportTo());
    Template templateEty = this.configurationHolder.readTemplatesConfiguration(trigger).getTemplate(template.getId());
    try {
        String resolvedDestinationPath = new PathExpressionResolver(variables).evaluateExpressions(templateEty.getUnresolvedTargetPath());
        return targetRootPath.resolve(resolvedDestinationPath).normalize();
    } catch (UnknownContextVariableException e) {
        throw new CobiGenRuntimeException("Could not resolve path '" + templateEty.getUnresolvedTargetPath() + "' for input '" + (input instanceof Object[] ? Arrays.toString((Object[]) input) : input.toString()) + "' and template '" + templateEty.getAbsoluteTemplatePath() + "'. Available variables: " + variables.toString());
    }
}
Also used : TriggerInterpreter(com.devonfw.cobigen.api.extension.TriggerInterpreter) Variables(com.devonfw.cobigen.impl.config.entity.Variables) Trigger(com.devonfw.cobigen.impl.config.entity.Trigger) GenerationReportTo(com.devonfw.cobigen.api.to.GenerationReportTo) CobiGenRuntimeException(com.devonfw.cobigen.api.exception.CobiGenRuntimeException) ContextVariableResolver(com.devonfw.cobigen.impl.model.ContextVariableResolver) PathExpressionResolver(com.devonfw.cobigen.impl.config.resolver.PathExpressionResolver) UnknownContextVariableException(com.devonfw.cobigen.impl.exceptions.UnknownContextVariableException) Template(com.devonfw.cobigen.impl.config.entity.Template)

Example 39 with CobiGenRuntimeException

use of com.devonfw.cobigen.api.exception.CobiGenRuntimeException in project cobigen by devonfw.

the class ExternalProcess method _request.

/**
 * {@link #request(HttpMethod, String, Object, MediaType)} without requesting the server to start
 */
@SuppressWarnings("javadoc")
private String _request(HttpMethod httpMethod, String path, Object body, MediaType mediaType) {
    String endpointUrl = getBasePath() + path;
    LOG.debug("Requesting {} {} with media type {}", httpMethod, endpointUrl, mediaType);
    try {
        Response response = null;
        switch(httpMethod) {
            case POST:
                response = this.httpClient.newCall(new Request.Builder().url(endpointUrl).post(RequestBody.create(new Gson().toJson(body), mediaType)).build()).execute();
                break;
            case GET:
                response = this.httpClient.newCall(new Request.Builder().url(endpointUrl).get().build()).execute();
        }
        if (response != null && (response.code() == 200 || response.code() == 201 || response.code() == 204)) {
            LOG.debug("Responded {}", response.code());
            return response.body().string();
        } else {
            throw new CobiGenRuntimeException("Unable to send or receive the message from the service. Response code: " + (response != null ? response.code() : null));
        }
    } catch (IOException e) {
        throw new CobiGenRuntimeException("Unable to send or receive the message from the service", e);
    }
}
Also used : Response(okhttp3.Response) CobiGenRuntimeException(com.devonfw.cobigen.api.exception.CobiGenRuntimeException) Gson(com.google.gson.Gson) IOException(java.io.IOException)

Example 40 with CobiGenRuntimeException

use of com.devonfw.cobigen.api.exception.CobiGenRuntimeException in project cobigen by devonfw.

the class ExternalProcess method startServer.

/**
 * Executes the exe file
 *
 * @return true only if the exe has been correctly executed
 */
private synchronized boolean startServer() {
    // server ist already running
    if (this.process != null && this.process.getProcess() != null && this.process.getProcess().isAlive()) {
        LOG.debug("Server was already running - {}", this.process.getProcess());
        return true;
    } else {
        LOG.debug("Server was not yet running, starting...");
    }
    String fileName;
    if (OS.indexOf("win") >= 0) {
        fileName = this.serverFileName + "-" + this.serverVersion + ".exe";
    } else {
        fileName = this.serverFileName + "-" + this.serverVersion;
    }
    String filePath = ExternalProcessConstants.EXTERNAL_PROCESS_FOLDER.toString() + File.separator + fileName;
    try {
        if (exeIsNotValid(filePath)) {
            filePath = downloadExecutable(filePath, fileName);
        }
        setPermissions(filePath);
    } catch (IOException e) {
        LOG.error("Unable to download {} to {} and set permissions", filePath, this.serverDownloadUrl, e);
        return false;
    }
    int currentTry = 0;
    while (currentTry < 10) {
        try {
            this.process = new ProcessExecutor().command(filePath, String.valueOf(this.port)).destroyOnExit().redirectError(Slf4jStream.of(LoggerFactory.getLogger(getClass().getName() + "." + this.serverFileName)).asError()).redirectOutput(Slf4jStream.of(LoggerFactory.getLogger(getClass().getName() + "." + this.serverFileName)).asInfo()).start();
            Future<ProcessResult> result = this.process.getFuture();
            int retry = 0;
            do {
                if (result.isDone()) {
                    // if process terminated already, it was failing
                    LOG.error("Could not start server in 5s. Closed with output:\n{}", result.get().getOutput());
                    this.process.getProcess().destroyForcibly();
                    return false;
                }
                Thread.sleep(100);
                retry++;
                LOG.info("Waiting process to be alive for {}s", 100 * retry / 1000d);
            } while (!isConnectedAndValidService() && retry <= 50);
            if (retry > 50) {
                LOG.error("Server could not be started at port {}", this.port);
                return false;
            }
            // add JVM shutdown hook
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                try {
                    LOG.info("Closing {} - {}", this.serverFileName, this.process.getProcess());
                    ExternalProcess.this.finalize();
                } catch (Throwable e) {
                    LOG.warn("Could not close external process", e);
                }
            }));
            LOG.info("Server started at port {}", this.port);
            return true;
        } catch (Throwable e) {
            BindException bindException = ExceptionUtil.getCause(e, BindException.class);
            ConnectException connectException = ExceptionUtil.getCause(e, ConnectException.class);
            if (bindException != null || connectException != null) {
                try {
                    this.process.getProcess().destroyForcibly().waitFor();
                } catch (InterruptedException e1) {
                    LOG.error("Interrupted wait for process termination to complete", e1);
                }
                int newPort = aquireNewPort();
                LOG.debug("Port {} already in use, trying port {}", this.port, newPort, e);
                this.port = newPort;
                currentTry++;
            }
            throw new CobiGenRuntimeException("Unable to start the exe/server", e);
        }
    }
    LOG.error("Stopped trying to start the server after 10 retries");
    return false;
}
Also used : CobiGenRuntimeException(com.devonfw.cobigen.api.exception.CobiGenRuntimeException) ProcessResult(org.zeroturnaround.exec.ProcessResult) BindException(java.net.BindException) IOException(java.io.IOException) ProcessExecutor(org.zeroturnaround.exec.ProcessExecutor) ConnectException(java.net.ConnectException)

Aggregations

CobiGenRuntimeException (com.devonfw.cobigen.api.exception.CobiGenRuntimeException)43 IOException (java.io.IOException)22 Path (java.nio.file.Path)15 File (java.io.File)8 LoggerFactory (org.slf4j.LoggerFactory)5 InvalidConfigurationException (com.devonfw.cobigen.api.exception.InvalidConfigurationException)4 TextTemplateEngine (com.devonfw.cobigen.api.extension.TextTemplateEngine)4 GenerationReportTo (com.devonfw.cobigen.api.to.GenerationReportTo)4 Trigger (com.devonfw.cobigen.impl.config.entity.Trigger)4 InputStream (java.io.InputStream)4 URL (java.net.URL)4 URLClassLoader (java.net.URLClassLoader)4 CobiGen (com.devonfw.cobigen.api.CobiGen)3 TriggerInterpreter (com.devonfw.cobigen.api.extension.TriggerInterpreter)3 TemplateTo (com.devonfw.cobigen.api.to.TemplateTo)3 BackupFailedException (com.devonfw.cobigen.impl.exceptions.BackupFailedException)3 Paths (java.nio.file.Paths)3 HashMap (java.util.HashMap)3 List (java.util.List)3 Logger (org.slf4j.Logger)3