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

org.nuiton.eugene.AbstractMetaTransformer Maven / Gradle / Ivy

/*
 * #%L
 * EUGene :: EUGene Core
 * %%
 * Copyright (C) 2004 - 2017 Code Lutin, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.eugene;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.models.Model;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Abstract meta transformer which contains some templates to apply to an
 * incoming model.
 *
 * Using the {@link #getExcludeTemplates()} to restrict use of some templates.
 *
 * Created: 20 déc. 2009
 *
 * @param  type of  Model
 * @author Tony Chemit - [email protected]
 * @since 2.0.0
 */
public abstract class AbstractMetaTransformer extends AbstractGenerator {

    private static final Log log = LogFactory.getLog(AbstractMetaTransformer.class);

    /**
     * Transformers to apply before using templates.
     *
     * It will replace each time the input model by the generated output model.
     *
     * @since 2.3
     */
    protected Class>[] transformerTypes;

    /**
     * Templates to apply to the model.
     *
     * @since 2.3, replace the old transformers field.
     */
    protected Class>[] templateTypes;

    protected AbstractMetaTransformer() {
    }

    /**
     * @param templateTypes templates to apply on model
     * @deprecated since 2.3, prefer use the default constructor, the invoke
     * setters {@link #setTemplateTypes(Class[])} and
     * {@link #setTransformerTypes(Class[])}.
     */
    @Deprecated
    public AbstractMetaTransformer(
            Class>... templateTypes) {
        this.templateTypes = templateTypes;
    }

    /**
     * Validates the incoming given {@code model}.
     *
     * Note : If model is not valid, then nothing will be apply on the model
     * (no transformer nor templates) in the {@link #applyTemplate(Model, File)}.
     *
     * @param model the incoming model to validate
     * @return {@code true} if model is valid, {@code false} otherwise.
     */
    protected abstract boolean validateModel(M model);

    public Class>[] getTransformerTypes() {
        return transformerTypes;
    }

    public Class>[] getTemplateTypes() {
        return templateTypes;
    }

    public void setTransformerTypes(Class>... transformerTypes) {
        this.transformerTypes = transformerTypes;
    }

    public void setTemplateTypes(Class>... templateTypes) {
        this.templateTypes = templateTypes;
    }

    @Override
    public void applyTemplate(M model, File destDir) throws IOException {

        boolean isValid = validateModel(model);
        if (!isValid) {

            // Can not generate is model is not valid
            return;
        }

        // obtain transformers instances
        List> transformers =
                getInstances(getTransformerTypes());

        // transforme model to obtain the final model used by templates
        M currentModel = applyTransformers(model, transformers);

        // obtains templates instances
        List> templates = getInstances(getTemplateTypes());

        // apply templates to model
        applyTemplates(currentModel, templates, destDir);
    }

    /**
     * given an incoming {@code model}, chain transformations of the mode
     * using the given {@code transformers}.
     *
     * Will aplly the transformers in the order given by the list, using as
     * incoming model to a transformer the last (or incoming for the first transformer)
     * model.
     *
     * @param model        incoming model to transform
     * @param transformers list of transformers to apply to the model
     * @return the final transformed model
     * @since 2.3
     */
    protected M applyTransformers(M model, List> transformers) {
        M currentModel = model;
        for (Transformer template : transformers) {
            if (log.isDebugEnabled()) {
                log.debug("call transformer : " +
                          template.getClass().getSimpleName());
            }
            // transform from the current model
            template.transform(currentModel);

            // current model become the transformed model
            currentModel = template.getOutputModel();
        }
        return currentModel;
    }

    /**
     * Generates to the given {@code destination directory} using the given
     * templates on the incoming given {@code model}.
     *
     * @param model     the incoming model to be used by templates
     * @param templates templates to apply the incoming model
     * @param destDir   the destination directory where to generate
     * @throws IOException if any IO errors while generating files
     * @since 2.3
     */
    protected void applyTemplates(M model, List> templates, File destDir) throws IOException {
        for (Template template : templates) {
            if (log.isDebugEnabled()) {
                log.debug("call template : " +
                          template.getClass().getSimpleName());
            }
            template.applyTemplate(model, destDir);
        }
    }

    protected > List getInstances(Class[] types) {
        List result = new ArrayList<>();
        if (types != null) {
            for (Class generatorClass : types) {
                T generator;
                if (getExcludeTemplates().contains(generatorClass.getName())) {

                    // exclude generator
                    if (log.isInfoEnabled()) {
                        log.info("exclude generator " + generatorClass);
                    }
                    continue;
                }

                // instanciate the template
                try {
                    generator = generatorClass.newInstance();

                    // init template
                    generator.setConfiguration(getConfiguration());

                    if (generator instanceof AbstractGenerator) {
                        ((AbstractGenerator) generator).setParent(this);
                    }
//                if (generator instanceof Transformer) {
//                    generator.setProperties(properties);
//                }

                    // will use it
                    result.add(generator);
                } catch (Exception e) {

                    if (log.isErrorEnabled()) {
                        log.error("Could not instanciate template " +
                                  generatorClass, e);
                    }
                    throw new RuntimeException(e);
                }
            }
        }
        return result;
    }

    /**
     * @return the instances of templates to apply to the model.
     * @deprecated since 2.3, prefer use the {@link #getInstances(Class[])}
     */
    @Deprecated
    protected List> getTemplates() {
        List> result = new ArrayList<>();
        for (Class> generatorClass : templateTypes) {
            Template generator;
            if (getExcludeTemplates().contains(generatorClass.getName())) {
                // exclude generator
                if (log.isInfoEnabled()) {
                    log.info("exclude generator " + generatorClass);
                }
                continue;
            }
            try {
                generator = generatorClass.newInstance();

                // init template

                generator.setConfiguration(getConfiguration());

                if (generator instanceof AbstractGenerator) {
                    ((AbstractGenerator) generator).setParent(this);
                }
//                if (generator instanceof Transformer) {
//                    generator.setProperties(properties);
//                }

                // will use it
                result.add(generator);
            } catch (Exception e) {
                // should never happens
                if (log.isErrorEnabled()) {
                    log.error("An error occurs when generating persistence", e);
                }
                throw new RuntimeException(e);
            }
        }
        return result;
    }

    /**
     * @return the template types to apply
     * @deprecated since 2.3, use the method {@link #getTemplateTypes()} instead.
     */
    @Deprecated
    public Class>[] getTransformers() {
        return templateTypes;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy