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

com.legstar.codegen.CodeGenUtil Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2015 LegSem.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     LegSem - initial API and implementation
 ******************************************************************************/
package com.legstar.codegen;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

/**
 * Various utility methods which are mostly useful for code generation using
 * velocity templates.
 */
public final class CodeGenUtil {

    /** Generated code has reference to generation date following this format. */
    public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";

    /** Used to generate random serial version IDs. */
    private static Random mRandom = new Random();

    /** Suffix used for JAXB type variable names. */
    public static final String JAXB_TYPE_SUFFIX = "Type";

    /** Get the platform specific line separator. */
    public static final String CRLF = System.getProperty("line.separator");

    /** Logger. */
    private static final Log LOG = LogFactory.getLog(CodeGenUtil.class);

    /**
     * Defeats instantiation. Utility class.
     */
    private CodeGenUtil() {
    }

    /**
     * Check that a directory is valid.
     * 
     * @param dir the directory name to check
     * @param create true if directory should be created when not found
     * @param errorDirName name to refer to if an error occurs
     */
    public static void checkDirectory(final String dir, final boolean create,
            final String errorDirName) {
        try {
            checkDirectory(dir, create);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException(errorDirName + ": "
                    + e.getMessage());
        }
    }

    /**
     * Check that a directory is valid.
     * 
     * @param fdir the directory name to check
     * @param create true if directory should be created when not found
     * @param errorDirName name to refer to if an error occurs
     */
    public static void checkDirectory(final File fdir, final boolean create,
            final String errorDirName) {
        try {
            checkDirectory(fdir, create);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException(errorDirName + ": "
                    + e.getMessage());
        }
    }

    /**
     * Check that a directory is valid.
     * 
     * @param dir the directory name to check
     * @param create true if directory should be created when not found
     */
    public static void checkDirectory(final String dir, final boolean create) {

        if (dir == null || dir.length() == 0) {
            throw (new IllegalArgumentException(
                    "No directory name was specified"));
        }

        checkDirectory(new File(dir), create);
    }

    /**
     * Check that a directory is valid.
     * 
     * @param fdir the directory to check
     * @param create true if directory should be created when not found
     */
    public static void checkDirectory(final File fdir, final boolean create) {

        if (fdir == null) {
            throw (new IllegalArgumentException(
                    "No directory name was specified"));
        }

        if (!fdir.exists()) {
            if (!create) {
                throw (new IllegalArgumentException(fdir.getName()
                        + " does not exist"));
            } else {
                if (!fdir.mkdirs()) {
                    throw (new IllegalArgumentException(
                            "Could not create directory " + fdir.getName()));
                } else {
                    return;
                }
            }
        }
        if (!fdir.isDirectory()) {
            throw (new IllegalArgumentException(fdir.getName()
                    + " is not a directory"));
        }
        if (!fdir.canWrite()) {
            throw (new IllegalArgumentException("Directory " + fdir.getName()
                    + " is not writable"));
        }
    }

    /**
     * Retrieve a file. Given a directory name and a filename, this creates a
     * File according to the following rules:
     * 
    *
  • If the filename is absolute, the directory name is ignored
  • *
  • If the directory is not null, it is assumed to exist
  • *
  • If the directory is not null and the filename is not absolute, then * filename is appended to directory
  • *
* * @param dir parent directory * @param filename absolute or relative file name * @return a File */ public static File getFile(final String dir, final String filename) { File file = new File(filename); if (file.isAbsolute()) { return file; } if (dir == null || dir.length() == 0) { return new File(filename); } return new File(dir, filename); } /** * Retrieve a file. Given a directory and a filename, this creates a File * according to the following rules: *
    *
  • If the filename is absolute, the directory name is ignored
  • *
  • Otherwise, filename is appended to directory
  • *
* * @param fdir parent directory * @param filename absolute or relative file name * @return a File */ public static File getFile(final File fdir, final String filename) { File file = new File(filename); if (file.isAbsolute()) { return file; } return new File(fdir, filename); } /** * @deprecated use com.legstar.coxb.util.Utils#toClassName instead. Create a * valid Java class name from a given noun. * * @param noun the characters to turn into a java class name * @return the Java class name */ public static String classNormalize(final String noun) { String className = null; if (noun != null && noun.length() > 0) { className = noun.substring(0, 1).toUpperCase(); if (noun.length() > 1) { className += noun.substring(1, noun.length()); } } return className; } /** * Given a package name, this method returns the relative path location of * the java files. A package like seg1.seg2.seg3 becomes /seg1/seg2/seg3/ * * @param packageName the package name * @return the relative location of java files */ public static String relativeLocation(final String packageName) { if (packageName == null || packageName.length() == 0) { return ""; } String loc = packageName.replace('.', '/'); if (loc.charAt(0) != '/') { loc = '/' + loc; } if (loc.charAt(loc.length() - 1) != '/') { loc += '/'; } return loc; } /** * Given a root directory name and a package name, returns the location for * class files. Optionally the location can be physically created. * * @param rootDirName the root directory name. * @param packageName the package name or null if none * @param create true if directory should be created when not found * @return an existing location to store class files */ public static String classFilesLocation(final String rootDirName, final String packageName, final boolean create) { if (rootDirName == null || rootDirName.length() == 0) { throw (new IllegalArgumentException( "No root directory name was specified")); } String dir; if (packageName != null && packageName.length() > 0) { dir = rootDirName + '/' + CodeGenUtil.relativeLocation(packageName); } else { dir = rootDirName; } if (create) { CodeGenUtil.checkDirectory(dir, true); } return dir; } /** * Concatenates the path derived from a package name to a root directory. * * @param rootDir the root directory. Optionally the location can be * physically created. * @param packageName the package name * @param create true if directory should be created when not found * @return the file derived from concatenating the root directory with the * package path. */ public static File classFilesLocation(final File rootDir, final String packageName, final boolean create) { File dir = rootDir; if (packageName != null && packageName.length() > 0) { dir = new File(rootDir, CodeGenUtil.relativeLocation(packageName)); } if (create) { CodeGenUtil.checkDirectory(dir, true); } return dir; } /** * Setup Velocity so that it searches for templates in the classpath. *

* In order to work around issue 158 that arises when velocity dynamically * loaded classes are already in the context classloader parent, we * temporarily switch to a new context classloader that sees our plugin * classes and dependencies only. * * @throws CodeGenVelocityException if setup fails */ public static void initVelocity() throws CodeGenVelocityException { ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { Velocity.addProperty("resource.loader", "classpath"); Velocity.addProperty("classpath.resource.loader.description", "Velocity Classpath Resource Loader"); Velocity.addProperty("classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader." + "ClasspathResourceLoader"); Velocity.addProperty("classpath.resource.loader.cache", true); Thread.currentThread().setContextClassLoader( Velocity.class.getClassLoader()); Velocity.init(); } catch (Exception e) { throw new CodeGenVelocityException(e); } finally { Thread.currentThread().setContextClassLoader(loader); } } /** * A simple context to use by generation templates. * * @param generatorName generator name * @return a velocity context */ public static VelocityContext getContext(final String generatorName) { VelocityContext context = new VelocityContext(); context.put("formattedDate", now()); context.put("generatorName", generatorName); return context; } /** * Apply a velocity template taken from a code generation make xml. * * @param generatorName the generator name * @param templateName the velocity template to apply * @param modelName the model name * @param model the model providing data for velocity templates * @param parameters additional parameters to pass to template * @param targetFile the file to generate using default charset * @throws CodeGenMakeException if processing fails */ public static void processTemplate(final String generatorName, final String templateName, final String modelName, final Object model, final Map < String, Object > parameters, final File targetFile) throws CodeGenMakeException { processTemplate(generatorName, templateName, modelName, model, parameters, targetFile, null); } /** * Apply a velocity template taken from a code generation make xml. * * @param generatorName the generator name * @param templateName the velocity template to apply * @param modelName the model name * @param model the model providing data for velocity templates * @param parameters additional parameters to pass to template * @param targetFile the file to generate * @param targetCharsetName the target character set. null is interpreted as * the default encoding * @throws CodeGenMakeException if processing fails */ public static void processTemplate(final String generatorName, final String templateName, final String modelName, final Object model, final Map < String, Object > parameters, final File targetFile, final String targetCharsetName) throws CodeGenMakeException { if (LOG.isDebugEnabled()) { LOG.debug("Processing template"); LOG.debug("Template name = " + templateName); LOG.debug("Target file = " + targetFile); LOG.debug("Target charset name = " + targetCharsetName); if (parameters != null) { for (String key : parameters.keySet()) { Object value = parameters.get(key); LOG.debug("Parameter " + key + " = " + value); } } } VelocityContext context = CodeGenUtil.getContext(generatorName); context.put(modelName, model); context.put("serialVersionID", Long.toString(mRandom.nextLong()) + 'L'); if (parameters != null) { for (String key : parameters.keySet()) { context.put(key, parameters.get(key)); } } StringWriter w = new StringWriter(); try { Velocity.mergeTemplate(templateName, "UTF-8", context, w); Writer out = null; try { FileOutputStream fos = new FileOutputStream(targetFile); OutputStreamWriter osw; if (targetCharsetName == null) { osw = new OutputStreamWriter(fos); } else { osw = new OutputStreamWriter(fos, targetCharsetName); } out = new BufferedWriter(osw); out.write(w.toString()); } catch (IOException e) { throw new CodeGenMakeException(e); } finally { if (out != null) { out.close(); } } } catch (ResourceNotFoundException e) { throw new CodeGenMakeException(e); } catch (ParseErrorException e) { throw new CodeGenMakeException(e); } catch (MethodInvocationException e) { throw new CodeGenMakeException(e); } catch (Exception e) { throw new CodeGenMakeException(e); } } /** * Formats todays date and time. * * @return a formatted date */ public static String now() { Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW); return sdf.format(cal.getTime()); } /** * Checks that a URI is valid and HTTP scheme. * * @param httpUri the URI to check * @throws CodeGenMakeException if URI has wrong syntax */ public static void checkHttpURI(final String httpUri) throws CodeGenMakeException { try { if (httpUri == null || httpUri.length() == 0) { throw new CodeGenMakeException("You must specify a valid URI"); } URI uri = new URI(httpUri); if (uri.getScheme() == null || uri.getScheme().compareToIgnoreCase("http") != 0) { throw new CodeGenMakeException("URI " + uri + " must have http scheme"); } } catch (URISyntaxException e) { throw new CodeGenMakeException(e); } } /** * Checks that a character set is valid. * * @param charset the character set * @see java.nio.charset.Charset * @throws CodeGenMakeException if character set not supported */ public static void checkCharset(final String charset) throws CodeGenMakeException { if (charset == null || charset.length() == 0) { throw new CodeGenMakeException( "You must specify a valid character set"); } if (!Charset.isSupported(charset)) { throw new CodeGenMakeException("Character set " + charset + " is not supported"); } } /** * Field names are derived from property names by lower casing the first * character. * * @param propertyName the property name * @return a valid field name or null if property name is empty */ public static String fieldNameFromPropertyName(final String propertyName) { String fieldName = null; if (propertyName != null && propertyName.length() > 0) { fieldName = propertyName.substring(0, 1).toLowerCase(); if (propertyName.length() > 1) { fieldName += propertyName.substring(1, propertyName.length()); } } return fieldName; } /** * Property names are derived from field names by upper casing the first * character. * * @param fieldName the field name * @return a valid property name or null if field name is empty */ public static String propertyNameFromFieldName(final String fieldName) { String propertyName = null; if (fieldName != null && fieldName.length() > 0) { propertyName = fieldName.substring(0, 1).toUpperCase(); if (fieldName.length() > 1) { propertyName += fieldName.substring(1, fieldName.length()); } } return propertyName; } /** * Property names are derived from jaxb type names by stripping the type * suffix (if any). * * @param jaxbType the jaxb type name * @return a valid property name or null if jaxb type name is empty */ public static String propertyNameFromJaxbType(final String jaxbType) { String propertyName = null; if (jaxbType != null && jaxbType.length() > 0) { propertyName = jaxbType; if (propertyName.endsWith(JAXB_TYPE_SUFFIX)) { propertyName = propertyName.substring(0, propertyName.length() - JAXB_TYPE_SUFFIX.length()); } } return propertyName; } /** * Retrieve the IP address of the generation machine . * * @return the local machine IP address */ public static String getLocalIPAddress() { try { InetAddress addr = InetAddress.getLocalHost(); byte[] ipAddr = addr.getAddress(); String ipAddrStr = ""; for (int i = 0; i < ipAddr.length; i++) { if (i > 0) { ipAddrStr += "."; } ipAddrStr += ipAddr[i] & 0xFF; } return ipAddrStr; } catch (UnknownHostException e) { return ""; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy