All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.metaeffekt.notice.engine.NoticeEngine Maven / Gradle / Ivy

There is a newer version: 0.132.0
Show newest version
/*
 * Copyright 2021-2024 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.metaeffekt.notice.engine;

import com.metaeffekt.artifact.analysis.utils.FileUtils;
import com.metaeffekt.artifact.terms.model.NormalizationMetaData;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.metaeffekt.common.notice.model.NoticeParameters;
import org.metaeffekt.common.notice.model.ProjectContext;
import org.metaeffekt.core.inventory.processor.report.PreFormattedEscapeUtils;
import org.metaeffekt.notice.engine.utils.NoticeUtils;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class NoticeEngine {

    private VelocityEngine velocityEngine;

    private Template template;

    /**
     * The {@link VelocityContext} is invocation-specific and may change (FIXME: isolate as ThreadLocal)
     */
    private transient VelocityContext velocityContext;

    private final File fileResourcePath;

    private ProjectContext projectContext = new ProjectContext();

    /**
     * Constructor using notice template from classpath.
     */
    public NoticeEngine() {
        this.fileResourcePath = null;
    }

    /**
     * Constructor using notice templates in given fileResourcePath.
     *
     * @param fileResourcePath The path where the template resources are located.
     */
    public NoticeEngine(File fileResourcePath) {
        this.fileResourcePath = fileResourcePath;
    }

    public String applyTemplate(File noticeInputDefinition, NormalizationMetaData normalizationMetaData) throws IOException {
        return applyTemplate(NoticeParameters.readYaml(noticeInputDefinition), normalizationMetaData);
    }

    public String applyTemplate(NoticeParameters param, NormalizationMetaData normalizationMetaData) {
        initializeVelocityEngineAndTemplate();

        initializeVelocityContext(param, normalizationMetaData);

        StringWriter stringWriter = new StringWriter();
        this.template.merge(this.velocityContext, stringWriter);
        return postprocess(stringWriter.getBuffer().toString());
    }

    private void initializeVelocityContext(NoticeParameters param, NormalizationMetaData normalizationMetaData) {
        final Map contextMap = new HashMap<>();
        contextMap.put("engine", this);
        contextMap.put("context", new NoticeUtils(normalizationMetaData));
        contextMap.put("noticeParameters", param);
        contextMap.put("escape", new PreFormattedEscapeUtils());
        contextMap.put("projectContext", projectContext);
        this.velocityContext = new VelocityContext(contextMap);
    }

    private synchronized void initializeVelocityEngineAndTemplate() {
        if (this.velocityEngine == null) {
            // prepare configuration
            final Properties properties = new Properties();
            if (fileResourcePath == null) {
                properties.put("class.resource.loader.class", ClasspathResourceLoader.class.getName());
            } else {
                properties.put(Velocity.FILE_RESOURCE_LOADER_PATH, fileResourcePath.getAbsolutePath());
            }
            properties.put(Velocity.RESOURCE_LOADER, "class, file");
            properties.put(Velocity.INPUT_ENCODING, FileUtils.ENCODING_UTF_8);
            properties.put(Velocity.OUTPUT_ENCODING, FileUtils.ENCODING_UTF_8);
            properties.put(Velocity.SET_NULL_ALLOWED, true);

            // initialize velocity engine
            this.velocityEngine = new VelocityEngine(properties);
            this.velocityEngine.init();

            // initialize template
            this.template = this.velocityEngine.getTemplate("notice-template/template.vm");
        }
    }

    private String postprocess(String string) {
        string = string.trim();
        string = string.replaceAll("\\s*", "");
        string = string.replaceAll("\\s*", "");

        string = string.replaceAll("\\s*", "\n");
        string = string.replaceAll("

\\s*

", "

"); final int index = string.lastIndexOf("

"); if (index >= 0) { if (string.substring(index).trim().equals("

")) { string = string.substring(0, index); } } string = string.replaceAll("\n\\s*

", "\n

"); string = string.replaceAll("\n\\s*([^<])", " $1"); return string; } public String executeTemplate(String file) { Template template = velocityEngine.getTemplate(file); StringWriter writer = new StringWriter(); template.merge(velocityContext, writer); return writer.getBuffer().toString(); } public void setProjectContext(ProjectContext projectContext) { this.projectContext = projectContext; } public ProjectContext getProjectContext() { return projectContext; } public boolean resourceExists(String resource) { return this.velocityEngine.resourceExists(resource); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy