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

com.jaxio.celerio.template.TemplateEngine Maven / Gradle / Ivy

There is a newer version: 4.0.23
Show newest version
/*
 * Copyright 2015 JAXIO http://www.jaxio.com
 *
 * 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 com.jaxio.celerio.template;

import com.google.common.base.Predicate;
import com.jaxio.celerio.Brand;
import com.jaxio.celerio.Config;
import com.jaxio.celerio.configuration.Module;
import com.jaxio.celerio.configuration.Pack;
import com.jaxio.celerio.configuration.Pattern;
import com.jaxio.celerio.convention.ClassType;
import com.jaxio.celerio.convention.GeneratedPackage;
import com.jaxio.celerio.convention.MethodConvention;
import com.jaxio.celerio.convention.WellKnownFolder;
import com.jaxio.celerio.model.Attribute;
import com.jaxio.celerio.model.Entity;
import com.jaxio.celerio.model.EnumType;
import com.jaxio.celerio.model.Project;
import com.jaxio.celerio.template.pack.PackLoader;
import com.jaxio.celerio.template.pack.Template;
import com.jaxio.celerio.template.pack.TemplatePack;
import com.jaxio.celerio.util.BrandUtil;
import com.jaxio.celerio.util.IdentifiableProperty;
import com.jaxio.celerio.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.reverse;
import static com.google.common.collect.Maps.newHashMap;

@Service
@Slf4j
public class TemplateEngine {
    private static final String DASH_LINE = "-----------------------------------------------------------------------";

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private Config config;

    @Autowired
    private ContentWriter contentWriter;

    @Autowired
    private PackLoader packLoader;

    private Map getGlobalContext() {
        Map context = newHashMap();
        // static values
        context.put("dollar", "$");
        context.put("d", "$");
        context.put("pound", "#");
        context.put("p", "#");
        context.put("serialVersionUID", "    static final private long serialVersionUID = " + 1 + "L;");
        // global context values
        context.put("brand", new Brand());
        context.put("brandUtil", new BrandUtil(config.getOutputResult()));
        context.put("config", config);
        context.put("configuration", config.getCelerio().getConfiguration());
        context.put("generation", config.getCelerio().getConfiguration().getGeneration());
        context.put("databaseInfo", config.getMetadata().getDatabaseInfo());
        context.put("jdbcConnectivity", config.getMetadata().getJdbcConnectivity());
        context.put("project", config.getProject());
        context.put("metadata", config.getOriginalMetadata());
        context.put("StringUtil", StringUtil.class);
        // enums
        ContextUtil.addEnumValues(context, ClassType.values());
        ContextUtil.addEnumValues(context, WellKnownFolder.values());
        ContextUtil.addEnumValues(context, GeneratedPackage.values());
        ContextUtil.addEnumValues(context, Module.values());
        ContextUtil.addEnumValues(context, MethodConvention.values());

        // identifiable
        context.put("identifiableProperty", new IdentifiableProperty(config.getCelerio().getConfiguration().getConventions().getIdentifiableProperty()));

        return context;
    }

    private String s(Collection s) {
        return s.size() <= 1 ? "" : "s";
    }

    public void produce(Project project, boolean bootstrapOnly) throws Exception {

        if (config.getCelerio().getConfiguration().getModules().isEmpty()) {
            log.info("No active module");
        } else {
            log.info("Active modules");
            for (Module module : config.getCelerio().getConfiguration().getModules()) {
                log.info(" . " + module);
            }
        }

        List templatePacks = packLoader.getTemplatePacks();
        if (log.isInfoEnabled()) {
            log.info(DASH_LINE);
            log.info("Working with " + templatePacks.size() + " templates pack" + s(templatePacks) + ".");
            for (TemplatePack templatePack : templatePacks) {
                log.info(". " + templatePack.getName() + " (" + templatePack.getTemplateNames().size() + " resource" + s(templatePack.getTemplateNames()) + ")");

                Pack configPack = config.getCelerio().getConfiguration().getPackByName(templatePack.getName());
                if (configPack != null) {
                    log.info("        Configuration found");
                    for (Pattern p : configPack.getTemplates()) {
                        log.info("        - include: " + p.isInclude() + ", template pattern: " + p.getPattern());
                    }
                    for (Pattern p : configPack.getFilenames()) {
                        log.info("        - include: " + p.isInclude() + ", filename pattern: " + p.getPattern());
                    }
                }
            }
        }

        config.getOutputResult().open();

        // producing bootstrap first
        List packReversed = reverse(templatePacks);
        for (TemplatePack templatePack : packReversed) {
            if (getTemplateNames(templatePack, TemplateType.bootstrap).isEmpty()) {
                continue;
            }

            log.info(DASH_LINE);
            log.info("Template Pack (bootstrap) " + templatePack.getName());
            produceBootstrap(project, templatePack);
            break;
        }

        if (bootstrapOnly) {
            return;
        }

        for (TemplatePack templatePack : templatePacks) {
            log.info(DASH_LINE);
            log.info("Template Pack " + templatePack.getName());

            produceProject(project, templatePack);
            produceEntities(project, templatePack);
            produceCompositePk(project, templatePack);
            produceAttributes(project, templatePack);
            produceEnums(project, templatePack);
            produceStaticTemplates(templatePack);
            produceCelerioExampleTemplates(templatePack);
        }

        config.getOutputResult().close();
    }

    private void produceStaticTemplates(TemplatePack templatePack) throws Exception {
        for (String staticTemplateName : getStaticTemplateNames(templatePack)) {
            Template template = templatePack.getTemplateByName(staticTemplateName);

            // filter
            if (!config.getCelerio().getConfiguration().hasFilename(templatePack.getName(), template.getName())) {
                if (log.isDebugEnabled()) {
                    log.debug("SKIPPING:" + template.getName());
                }
                continue;
            }

            contentWriter.processFile(config.getOutputResult(), templatePack, template, template.getBytes(), template.getName());
        }
    }

    private void produceCelerioExampleTemplates(TemplatePack templatePack) throws Exception {
        for (String staticTemplateName : getCelerioExampleTemplateNames(templatePack)) {
            Template template = templatePack.getTemplateByName(staticTemplateName);

            String physicalTargetFilename = template.getName().replace("celerio-example", "celerio");
            // filter
            if (!config.getCelerio().getConfiguration().hasFilename(templatePack.getName(), physicalTargetFilename)) {
                log.debug("SKIPPING:" + physicalTargetFilename);
                continue;
            }

            contentWriter.processFile(config.getOutputResult(), templatePack, template, template.getBytes(), physicalTargetFilename);
        }
    }

    private void produceProject(Project project, TemplatePack templatePack) throws Exception, IOException {
        for (String templateName : getTemplateNames(templatePack, TemplateType.project)) {
            produce(getGlobalContext(), templatePack, templateName);
        }
    }

    private void produceBootstrap(Project project, TemplatePack templatePack) throws Exception, IOException {
        for (String templateName : getTemplateNames(templatePack, TemplateType.bootstrap)) {
            produce(getGlobalContext(), templatePack, templateName);
        }
    }

    private void produceEntities(Project project, TemplatePack templatePack) throws Exception, IOException {
        for (String templateName : getTemplateNames(templatePack, TemplateType.entity)) {
            for (Entity entity : project.getCurrentEntities()) {
                if (entity.isManyToManyJoinEntity() || entity.isSkip()) {
                    continue;
                }
                Map context = getGlobalContext();
                context.put("entity", entity);
                context.put("primaryKey", entity.getPrimaryKey());
                produce(context, templatePack, templateName);
            }
        }
    }

    private void produceCompositePk(Project project, TemplatePack templatePack) throws Exception, IOException {
        for (String templateName : getTemplateNames(templatePack, TemplateType.compositePrimaryKey)) {
            for (Entity entity : project.getRootEntities().getList()) {
                if (entity.hasCompositePk() && !entity.isManyToManyJoinEntity() && !entity.isSkip()) {
                    Map context = getGlobalContext();
                    context.put("entity", entity);
                    context.put("primaryKey", entity.getPrimaryKey());
                    produce(context, templatePack, templateName);
                }
            }
        }
    }

    private void produceEnums(Project project, TemplatePack templatePack) throws Exception, IOException {
        for (String templateName : getTemplateNames(templatePack, TemplateType.enumeration)) {
            for (EnumType enumType : project.getEnumTypes()) {
                Map context = getGlobalContext();
                context.put("enum", enumType);
                produce(context, templatePack, templateName);
            }
        }
    }

    private void produceAttributes(Project project, TemplatePack templatePack) throws Exception, IOException {
        for (String templateName : getTemplateNames(templatePack, TemplateType.attribute)) {
            for (Entity entity : project.getCurrentEntities()) {
                for (Attribute attribute : entity.getCurrentAttributes()) {
                    Map context = getGlobalContext();
                    context.put("entity", entity);
                    context.put("attribute", attribute);
                    produce(context, templatePack, templateName);
                }
            }
        }
    }

    private void produce(Map context, TemplatePack templatePack, String templateName) throws Exception {
        Template template = templatePack.getTemplateByName(templateName);
        context.put("pack", templatePack.getTemplatePackInfo());
        TemplateExecution execution = applicationContext.getBean("templateExecution", TemplateExecution.class);
        context.put("output", execution);
        execution.write(config.getOutputResult(), context, templatePack, template);
    }

    private List getTemplateNames(TemplatePack templatePack, final TemplateType templateType) {
        Predicate matcher = and(new VelocityNameMatcher(templateType), new TemplateMatcher(templatePack));
        matcher = and(matcher, not(new CelerioTemplateExampleMatcher()));
        return newArrayList(filter(templatePack.getTemplateNames(), matcher));
    }

    private List getStaticTemplateNames(TemplatePack templatePack) {
        Predicate matcher = and(new TemplateMatcher(templatePack), not(new CelerioTemplateExampleMatcher()));
        for (TemplateType templateType : TemplateType.values()) {
            matcher = and(matcher, not(new VelocityNameMatcher(templateType)));
        }
        return newArrayList(filter(templatePack.getTemplateNames(), matcher));
    }

    private List getCelerioExampleTemplateNames(TemplatePack templatePack) {
        Predicate matcher = and(new TemplateMatcher(templatePack), new CelerioTemplateExampleMatcher());
        return newArrayList(filter(templatePack.getTemplateNames(), matcher));
    }

    public enum TemplateType {
        bootstrap("boot"), //
        project("p"), //
        entity("e"), //
        attribute("a"), //
        enumeration("enum"), //
        compositePrimaryKey("cpk");
        private String pattern;

        TemplateType(String pattern) {
            this.pattern = pattern;
        }

        public String getVelocityPattern() {
            return "." + pattern + ".vm";
        }
    }

    private class VelocityNameMatcher implements Predicate {
        private TemplateType type;

        public VelocityNameMatcher(TemplateType type) {
            this.type = type;
        }

        @Override
        public boolean apply(String input) {
            return input.indexOf(type.getVelocityPattern()) != -1;
        }
    }

    private class TemplateMatcher implements Predicate {
        private TemplatePack templatePack;

        public TemplateMatcher(TemplatePack templatePack) {
            this.templatePack = templatePack;
        }

        @Override
        public boolean apply(String templateName) {
            if (!config.getCelerio().getConfiguration().hasTemplate(templatePack.getName(), templateName)) {
                // log.debug("Skipping template '" + templateName + "'. Reason: requested in template pattern");
                return false;
            }
            return true;
        }
    }

    // celerio templates that should be copied as is...
    private class CelerioTemplateExampleMatcher implements Predicate {
        @Override
        public boolean apply(String relativePathAndTemplateName) {
            return relativePathAndTemplateName.contains("src\\main\\celerio-example") || relativePathAndTemplateName.startsWith("src/main/celerio-example");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy