org.openlegacy.designtime.generators.GenerateUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.openlegacy.designtime.generators.GenerateUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2014 OpenLegacy Inc.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     OpenLegacy Inc. - initial API and implementation
 *******************************************************************************/
package org.openlegacy.designtime.generators;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.CharEncoding;
import org.apache.commons.lang.SystemUtils;
import org.openlegacy.designtime.terminal.model.ScreenEntityDesigntimeDefinition;
import org.openlegacy.exceptions.GenerationException;
import org.openlegacy.terminal.definitions.ScreenEntityDefinition;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Locale;

@Component
public class GenerateUtil {

    private File templatesDir;

    public void setTemplateDirectory(File templatesDir) {
        this.templatesDir = templatesDir;
    }

    public void generate(Object model, OutputStream out, String templateName) throws GenerationException {
        generate(model, out, templateName, "");
    }

    public static String generate(Object model, StringReader templateString) throws GenerationException {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            OutputStreamWriter output = new OutputStreamWriter(baos, CharEncoding.UTF_8);
            Template template = new Template("Template", templateString,
                    new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
            template.process(model, output);
            byte[] bytes = baos.toByteArray();
            return new String(bytes, "UTF-8");
        } catch (TemplateException e) {
            throw (new GenerationException(e));
        } catch (IOException e) {
            throw (new GenerationException(e));
        }
    }

    public static void replicateTemplate(File file, Object model, String placeHolderStart, String placeHolderEnd,
            String existingCodeplaceHolderStart, String existingCodePlaceHolderEnd) {
        try {
            StringBuilder fileContent = new StringBuilder(FileUtils.readFileToString(file));

            int placeHolderReplaceMarkerStart = fileContent.indexOf(existingCodeplaceHolderStart) - 1;
            int placeHolderReplaceMarkerEnd = fileContent.indexOf(existingCodePlaceHolderEnd)
                    + existingCodePlaceHolderEnd.length();

            if (placeHolderReplaceMarkerStart > 0 && placeHolderReplaceMarkerStart > 0) {
                fileContent.delete(placeHolderReplaceMarkerStart, placeHolderReplaceMarkerEnd);
            }

            int templateMarkerStart = fileContent.indexOf(placeHolderStart);
            int templateMarkerEnd = fileContent.indexOf(placeHolderEnd) - 2;

            if (templateMarkerStart < 0 || templateMarkerEnd < 0) {
                return;
            }
            // replace tokens within the place holder tag
            String definitionTemplate = fileContent.substring(templateMarkerStart + placeHolderStart.length(),
                    templateMarkerEnd);

            String definitionTemplateNew = generate(model, new StringReader(definitionTemplate));
            fileContent = fileContent.insert(templateMarkerStart,
                    MessageFormat.format("{0}{1}{2}{3}", existingCodeplaceHolderStart, definitionTemplateNew,
                            existingCodePlaceHolderEnd, SystemUtils.LINE_SEPARATOR));

            FileUtils.write(file, fileContent);

        } catch (IOException e) {
            throw (new GenerationException(e));
        }
    }

    /**
     * 
     * @param model
     * @param out
     * @param templateName
     * @param templatePrefix
     *            allows to work with template with prefix if exists. e.g: MenuScreenEntityMvcPage.jspx.template /
     *            ScreenEntityMvcPage.jspx.template for generating a different page type for Menu screens
     * @throws GenerationException
     * @throws IOException
     */
    public void generate(Object model, OutputStream out, String templateName, String templatePrefix)
            throws GenerationException {

        try {

            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            if (isUseCustomTemplates()) {
                configuration.setDirectoryForTemplateLoading(templatesDir);
            } else {
                configuration.setClassForTemplateLoading(GenerateUtil.class, "/");
            }
            configuration.setWhitespaceStripping(true);
            configuration.setEncoding(Locale.getDefault(), CharEncoding.UTF_8);

            Template template = null;
            try {
                if (isUseCustomTemplates()) {
                    template = findTemplate(templateName, templatePrefix, configuration);
                }
            } catch (FileNotFoundException e) {
                // OK
            }
            // pick default template if couldn't find custom template
            if (template == null) {
                URL resource = GenerateUtil.class
                        .getResource(MessageFormat.format("/{0}{1}", templatePrefix, templateName));
                configuration.setClassForTemplateLoading(GenerateUtil.class, "/");
                if (resource != null) {
                    template = configuration.getTemplate(templatePrefix + templateName);
                } else {
                    if (templatePrefix.contains("/")) {
                        templateName = templatePrefix.substring(0, templatePrefix.lastIndexOf("/")) + "/"
                                + templateName;
                    }
                    template = configuration.getTemplate(templateName, CharEncoding.UTF_8);
                }
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            OutputStreamWriter output = new OutputStreamWriter(baos, CharEncoding.UTF_8);
            template.process(model, output);

            // only write the file if it has content (sometimes using empty template)
            byte[] bytes = baos.toByteArray();
            if (bytes.length > 0) {
                out.write(bytes);
            }
        } catch (TemplateException e) {
            throw (new GenerationException(e));
        } catch (IOException e) {
            throw (new GenerationException(e));
        }
    }

    private boolean isUseCustomTemplates() {
        return templatesDir != null && templatesDir.exists();
    }

    private Template findTemplate(String templateName, String templatePrefix, Configuration configuration)
            throws IOException {
        Template template = null;
        if (isUseCustomTemplates()) {
            File templateFile = new File(templatesDir,
                    MessageFormat.format("/{0}{1}", templatePrefix, templateName));
            if (templateFile.exists()) {
                template = configuration.getTemplate(templatePrefix + templateName);
            } else {
                if (templatePrefix.contains("/")) {
                    templateName = templatePrefix.substring(0, templatePrefix.lastIndexOf("/")) + "/"
                            + templateName;
                }
                template = configuration.getTemplate(templateName);
            }
        } else {
            URL resource = GenerateUtil.class
                    .getResource(MessageFormat.format("/{0}{1}", templatePrefix, templateName));
            if (resource != null) {
                template = configuration.getTemplate(templatePrefix + templateName);
            } else {
                template = configuration.getTemplate(templateName);
            }
        }
        return template;
    }

    public static void setPackageName(Collection<ScreenEntityDefinition> screenDefinitions, String packageName) {
        for (ScreenEntityDefinition screenEntityDefinition : screenDefinitions) {
            ((ScreenEntityDesigntimeDefinition) screenEntityDefinition).setPackageName(packageName);
        }

    }

    /**
     * 
     * @param javaFile
     * @param baos
     * @param pojoCodeModel
     * @param parentClassName
     * @return true when file changed
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static boolean writeAspectToFile(File javaFile, java.io.ByteArrayOutputStream baos,
            PojoCodeModel pojoCodeModel, String parentClassName) throws FileNotFoundException, IOException {
        if (pojoCodeModel != null && pojoCodeModel.isRelevant()) {
            File outputFolder = javaFile.getParentFile().getAbsoluteFile();
            String formattedClassName = pojoCodeModel.getFormattedClassName();
            // append the parentClassName to aspect file name if it's not the parent class is not the generated one
            String classFileName = !formattedClassName.equals(parentClassName)
                    ? (parentClassName + formattedClassName)
                    : formattedClassName;
            File outputFile = new File(outputFolder, classFileName + "_Aspect.aj");
            byte[] outputBytes = baos.toByteArray();
            if (outputFile.exists()) {
                byte[] currentFileContent = FileUtils.readFileToByteArray(outputFile);
                if (Arrays.equals(outputBytes, currentFileContent)) {
                    return false;
                }
            }
            FileOutputStream fos = new FileOutputStream(outputFile);
            fos.write(outputBytes);
            fos.close();
        }
        return true;
    }
}