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

org.jomc.tools.JomcTool Maven / Gradle / Ivy

There is a newer version: 1.10.1
Show newest version
/*
 *   Copyright (C) Christian Schulte , 2005-206
 *   All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 *
 *     o Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     o Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *
 *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *   $JOMC: JomcTool.java 5043 2015-05-27 07:03:39Z schulte $
 *
 */
package org.jomc.tools;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.text.DateFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level;
import javax.activation.MimeTypeParseException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.log.LogChute;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.runtime.resource.loader.URLResourceLoader;
import org.jomc.model.Argument;
import org.jomc.model.Dependency;
import org.jomc.model.Implementation;
import org.jomc.model.InheritanceModel;
import org.jomc.model.JavaIdentifier;
import org.jomc.model.JavaTypeName;
import org.jomc.model.Message;
import org.jomc.model.ModelObject;
import org.jomc.model.ModelObjectException;
import org.jomc.model.Modules;
import org.jomc.model.Multiplicity;
import org.jomc.model.Property;
import org.jomc.model.Specification;
import org.jomc.model.SpecificationReference;
import org.jomc.model.Text;
import org.jomc.model.Texts;
import org.jomc.model.modlet.ModelHelper;
import org.jomc.modlet.Model;

/**
 * Base tool class.
 *
 * @author Christian Schulte
 * @version $JOMC: JomcTool.java 5043 2015-05-27 07:03:39Z schulte $
 */
public class JomcTool
{

    /**
     * Listener interface.
     */
    public abstract static class Listener
    {

        /**
         * Creates a new {@code Listener} instance.
         */
        public Listener()
        {
            super();
        }

        /**
         * Gets called on logging.
         *
         * @param level The level of the event.
         * @param message The message of the event or {@code null}.
         * @param throwable The throwable of the event or {@code null}.
         *
         * @throws NullPointerException if {@code level} is {@code null}.
         */
        public void onLog( final Level level, final String message, final Throwable throwable )
        {
            if ( level == null )
            {
                throw new NullPointerException( "level" );
            }
        }

    }

    /**
     * Empty byte array.
     */
    private static final byte[] NO_BYTES =
    {
    };

    /**
     * The prefix of the template location.
     */
    private static final String TEMPLATE_PREFIX =
        JomcTool.class.getPackage().getName().replace( '.', '/' ) + "/templates/";

    /**
     * Constant for the default template profile.
     */
    private static final String DEFAULT_TEMPLATE_PROFILE = "jomc-java";

    /**
     * Constant for the name of the template profile property specifying a parent template profile name.
     *
     * @since 1.3
     */
    private static final String PARENT_TEMPLATE_PROFILE_PROPERTY_NAME = "parent-template-profile";

    /**
     * Constant for the name of the template profile property specifying the template encoding.
     *
     * @since 1.3
     */
    private static final String TEMPLATE_ENCODING_PROFILE_PROPERTY_NAME = "template-encoding";

    /**
     * The default encoding to use for reading templates.
     *
     * @since 1.3
     */
    private String defaultTemplateEncoding;

    /**
     * The default template profile.
     */
    private static volatile String defaultTemplateProfile;

    /**
     * The log level events are logged at by default.
     *
     * @see #getDefaultLogLevel()
     */
    private static final Level DEFAULT_LOG_LEVEL = Level.WARNING;

    /**
     * The default log level.
     */
    private static volatile Level defaultLogLevel;

    /**
     * The model of the instance.
     */
    private Model model;

    /**
     * The {@code VelocityEngine} of the instance.
     */
    private VelocityEngine velocityEngine;

    /**
     * Flag indicating the default {@code VelocityEngine}.
     *
     * @since 1.2.4
     */
    private boolean defaultVelocityEngine;

    /**
     * The location to search for templates in addition to searching the class path.
     *
     * @since 1.2
     */
    private URL templateLocation;

    /**
     * The encoding to use for reading files.
     */
    private String inputEncoding;

    /**
     * The encoding to use for writing files.
     */
    private String outputEncoding;

    /**
     * The template parameters.
     *
     * @since 1.2
     */
    private Map templateParameters;

    /**
     * The template profile of the instance.
     */
    private String templateProfile;

    /**
     * The indentation string of the instance.
     */
    private String indentation;

    /**
     * The line separator of the instance.
     */
    private String lineSeparator;

    /**
     * The listeners of the instance.
     */
    private List listeners;

    /**
     * The log level of the instance.
     */
    private Level logLevel;

    /**
     * The locale of the instance.
     *
     * @since 1.2
     */
    private Locale locale;

    /**
     * Cached indentation strings.
     */
    private volatile Reference> indentationCache;

    /**
     * Cached templates.
     *
     * @since 1.3
     */
    private volatile Reference> templateCache;

    /**
     * Cached template profile context properties.
     *
     * @since 1.3
     */
    private volatile Reference> templateProfileContextPropertiesCache;

    /**
     * Cached template profile properties.
     *
     * @since 1.3
     */
    private volatile Reference> templateProfilePropertiesCache;

    /**
     * Cached Java keywords.
     */
    private volatile Reference> javaKeywordsCache;

    /**
     * Creates a new {@code JomcTool} instance.
     */
    public JomcTool()
    {
        super();
    }

    /**
     * Creates a new {@code JomcTool} instance taking a {@code JomcTool} instance to initialize the new instance with.
     *
     * @param tool The instance to initialize the new instance with.
     *
     * @throws NullPointerException if {@code tool} is {@code null}.
     * @throws IOException if copying {@code tool} fails.
     */
    public JomcTool( final JomcTool tool ) throws IOException
    {
        this();

        if ( tool == null )
        {
            throw new NullPointerException( "tool" );
        }

        this.indentation = tool.indentation;
        this.inputEncoding = tool.inputEncoding;
        this.lineSeparator = tool.lineSeparator;
        this.listeners = tool.listeners != null ? new CopyOnWriteArrayList( tool.listeners ) : null;
        this.logLevel = tool.logLevel;
        this.model = tool.model != null ? tool.model.clone() : null;
        this.outputEncoding = tool.outputEncoding;
        this.defaultTemplateEncoding = tool.defaultTemplateEncoding;
        this.templateProfile = tool.templateProfile;
        this.velocityEngine = tool.velocityEngine;
        this.defaultVelocityEngine = tool.defaultVelocityEngine;
        this.locale = tool.locale;
        this.templateParameters =
            tool.templateParameters != null
                ? Collections.synchronizedMap( new HashMap( tool.templateParameters ) )
                : null;

        this.templateLocation =
            tool.templateLocation != null ? new URL( tool.templateLocation.toExternalForm() ) : null;

    }

    /**
     * Gets the list of registered listeners.
     * 

* This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make * to the returned list will be present inside the object. This is why there is no {@code set} method for the * listeners property. *

* * @return The list of registered listeners. * * @see #log(java.util.logging.Level, java.lang.String, java.lang.Throwable) */ public List getListeners() { if ( this.listeners == null ) { this.listeners = new CopyOnWriteArrayList(); } return this.listeners; } /** * Gets the default log level events are logged at. *

* The default log level is controlled by system property {@code org.jomc.tools.JomcTool.defaultLogLevel} holding * the log level to log events at by default. If that property is not set, the {@code WARNING} default is * returned. *

* * @return The log level events are logged at by default. * * @see #getLogLevel() * @see Level#parse(java.lang.String) */ public static Level getDefaultLogLevel() { if ( defaultLogLevel == null ) { defaultLogLevel = Level.parse( System.getProperty( "org.jomc.tools.JomcTool.defaultLogLevel", DEFAULT_LOG_LEVEL.getName() ) ); } return defaultLogLevel; } /** * Sets the default log level events are logged at. * * @param value The new default level events are logged at or {@code null}. * * @see #getDefaultLogLevel() */ public static void setDefaultLogLevel( final Level value ) { defaultLogLevel = value; } /** * Gets the log level of the instance. * * @return The log level of the instance. * * @see #getDefaultLogLevel() * @see #setLogLevel(java.util.logging.Level) * @see #isLoggable(java.util.logging.Level) */ public final Level getLogLevel() { if ( this.logLevel == null ) { this.logLevel = getDefaultLogLevel(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultLogLevelInfo", this.logLevel.getLocalizedName() ), null ); } } return this.logLevel; } /** * Sets the log level of the instance. * * @param value The new log level of the instance or {@code null}. * * @see #getLogLevel() * @see #isLoggable(java.util.logging.Level) */ public final void setLogLevel( final Level value ) { this.logLevel = value; } /** * Checks if a message at a given level is provided to the listeners of the instance. * * @param level The level to test. * * @return {@code true}, if messages at {@code level} are provided to the listeners of the instance; * {@code false}, if messages at {@code level} are not provided to the listeners of the instance. * * @throws NullPointerException if {@code level} is {@code null}. * * @see #getLogLevel() * @see #setLogLevel(java.util.logging.Level) * @see #log(java.util.logging.Level, java.lang.String, java.lang.Throwable) */ public boolean isLoggable( final Level level ) { if ( level == null ) { throw new NullPointerException( "level" ); } return level.intValue() >= this.getLogLevel().intValue(); } /** * Gets the Java package name of a specification. * * @param specification The specification to get the Java package name of. * * @return The Java package name of {@code specification} or {@code null}, if the specification does not reference a * type. * * @throws NullPointerException if {@code specification} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Specification#getJavaTypeName() * @see JavaTypeName#getPackageName() * * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaPackageName( final Specification specification ) throws ModelObjectException { if ( specification == null ) { throw new NullPointerException( "specification" ); } final JavaTypeName javaTypeName = specification.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getPackageName() : null; } /** * Gets the Java type name of a specification. * * @param specification The specification to get the Java type name of. * @param qualified {@code true}, to return the fully qualified type name (with package name prepended); * {@code false}, to return the short type name (without package name prepended). * * @return The Java type name of the type referenced by the specification or {@code null}, if the specification does * not reference a type. * * @throws NullPointerException if {@code specification} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Specification#getJavaTypeName() * @see JavaTypeName#getName(boolean) * * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaTypeName( final Specification specification, final boolean qualified ) throws ModelObjectException { if ( specification == null ) { throw new NullPointerException( "specification" ); } final JavaTypeName javaTypeName = specification.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getName( qualified ) : null; } /** * Gets the Java class path location of a specification. * * @param specification The specification to return the Java class path location of. * * @return The Java class path location of {@code specification} or {@code null}, if the specification does not * reference a type. * * @throws NullPointerException if {@code specification} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Specification#getJavaTypeName() * @see JavaTypeName#getQualifiedName() * * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaClasspathLocation( final Specification specification ) throws ModelObjectException { if ( specification == null ) { throw new NullPointerException( "specification" ); } final JavaTypeName javaTypeName = specification.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getQualifiedName().replace( '.', '/' ) : null; } /** * Gets the Java package name of a specification reference. * * @param reference The specification reference to get the Java package name of. * * @return The Java package name of {@code reference} or {@code null}, if the referenced specification is not found * or does not reference a type. * * @throws NullPointerException if {@code reference} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Modules#getSpecification(java.lang.String) * @see Specification#getJavaTypeName() * @see JavaTypeName#getPackageName() * * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaPackageName( final SpecificationReference reference ) throws ModelObjectException { if ( reference == null ) { throw new NullPointerException( "reference" ); } Specification s = null; String javaPackageName = null; if ( this.getModules() != null && ( s = this.getModules().getSpecification( reference.getIdentifier() ) ) != null ) { final JavaTypeName javaTypeName = s.getJavaTypeName(); javaPackageName = javaTypeName != null ? javaTypeName.getPackageName() : null; } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "specificationNotFound", reference.getIdentifier() ), null ); } return javaPackageName; } /** * Gets the name of a Java type of a given specification reference. * * @param reference The specification reference to get a Java type name of. * @param qualified {@code true}, to return the fully qualified type name (with package name prepended); * {@code false}, to return the short type name (without package name prepended). * * @return The Java type name of {@code reference} or {@code null}, if the referenced specification is not found * or does not reference a type. * * @throws NullPointerException if {@code reference} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Modules#getSpecification(java.lang.String) * @see Specification#getJavaTypeName() * @see JavaTypeName#getName(boolean) * * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaTypeName( final SpecificationReference reference, final boolean qualified ) throws ModelObjectException { if ( reference == null ) { throw new NullPointerException( "reference" ); } Specification s = null; String typeName = null; if ( this.getModules() != null && ( s = this.getModules().getSpecification( reference.getIdentifier() ) ) != null ) { final JavaTypeName javaTypeName = s.getJavaTypeName(); typeName = javaTypeName != null ? javaTypeName.getName( qualified ) : null; } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "specificationNotFound", reference.getIdentifier() ), null ); } return typeName; } /** * Gets the Java package name of an implementation. * * @param implementation The implementation to get the Java package name of. * * @return The Java package name of {@code implementation} or {@code null}, if the implementation does not reference * a type. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Implementation#getJavaTypeName() * @see JavaTypeName#getPackageName() * * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaPackageName( final Implementation implementation ) throws ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } final JavaTypeName javaTypeName = implementation.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getPackageName() : null; } /** * Gets the Java type name of an implementation. * * @param implementation The implementation to get the Java type name of. * @param qualified {@code true}, to return the fully qualified type name (with package name prepended); * {@code false}, to return the short type name (without package name prepended). * * @return The Java type name of the type referenced by the implementation or {@code null}, if the implementation * does not reference a type. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Implementation#getJavaTypeName() * @see JavaTypeName#getName(boolean) * * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaTypeName( final Implementation implementation, final boolean qualified ) throws ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } final JavaTypeName javaTypeName = implementation.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getName( qualified ) : null; } /** * Gets the Java class path location of an implementation. * * @param implementation The implementation to return the Java class path location of. * * @return The Java class path location of {@code implementation} or {@code null}, if the implementation does not * reference a type. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Implementation#getJavaTypeName() * @see JavaTypeName#getQualifiedName() * * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaClasspathLocation( final Implementation implementation ) throws ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } final JavaTypeName javaTypeName = implementation.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getQualifiedName().replace( '.', '/' ) : null; } /** * Gets a list of names of all Java types an implementation implements. * * @param implementation The implementation to get names of all implemented Java types of. * @param qualified {@code true}, to return the fully qualified type names (with package name prepended); * {@code false}, to return the short type names (without package name prepended). * * @return An unmodifiable list of names of all Java types implemented by {@code implementation}. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws ModelObjectException if compiling the name of a referenced type to a {@code JavaTypeName} fails. * * @deprecated As of JOMC 1.2, replaced by method {@link #getImplementedJavaTypeNames(org.jomc.model.Implementation, boolean)}. * This method will be removed in version 2.0. */ @Deprecated public List getJavaInterfaceNames( final Implementation implementation, final boolean qualified ) throws ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } return this.getImplementedJavaTypeNames( implementation, qualified ); } /** * Gets a list of names of all Java types an implementation implements. * * @param implementation The implementation to get names of all implemented Java types of. * @param qualified {@code true}, to return the fully qualified type names (with package name prepended); * {@code false}, to return the short type names (without package name prepended). * * @return An unmodifiable list of names of all Java types implemented by {@code implementation}. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Modules#getImplementedJavaTypeNames(java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public List getImplementedJavaTypeNames( final Implementation implementation, final boolean qualified ) throws ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } List col = null; if ( this.getModules() != null ) { final List javaTypeNames = this.getModules().getImplementedJavaTypeNames( implementation.getIdentifier() ); if ( javaTypeNames != null ) { col = new ArrayList( javaTypeNames.size() ); for ( int i = 0, s0 = javaTypeNames.size(); i < s0; i++ ) { if ( !col.contains( javaTypeNames.get( i ).getName( qualified ) ) ) { col.add( javaTypeNames.get( i ).getName( qualified ) ); } } } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null ); } return Collections.unmodifiableList( col != null ? col : Collections.emptyList() ); } /** * Gets the Java type name of an argument. * * @param argument The argument to get the Java type name of. * * @return The Java type name of the type referenced by the argument or {@code null}, if the argument does not * reference a type. * * @throws NullPointerException if {@code argument} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Argument#getJavaTypeName() * @see JavaTypeName#getName(boolean) * * @deprecated As of JOMC 1.4, please use method {@link Argument#getJavaTypeName()}. This method will be removed in * JOMC 2.0. */ @Deprecated public String getJavaTypeName( final Argument argument ) throws ModelObjectException { if ( argument == null ) { throw new NullPointerException( "argument" ); } final JavaTypeName javaTypeName = argument.getJavaTypeName(); return javaTypeName != null ? javaTypeName.getName( true ) : null; } /** * Gets a Java method parameter name of an argument. * * @param argument The argument to get the Java method parameter name of. * * @return The Java method parameter name of {@code argument}. * * @throws NullPointerException if {@code argument} is {@code null}. * @throws ModelObjectException if compiling the name of the argument to a {@code JavaIdentifier} fails. * * @see Argument#getJavaVariableName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Argument#getJavaVariableName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaMethodParameterName( final Argument argument ) throws ModelObjectException { if ( argument == null ) { throw new NullPointerException( "argument" ); } return this.getJavaMethodParameterName( argument.getName() ); } /** * Gets the Java type name of a property. * * @param property The property to get the Java type name of. * @param boxify {@code true}, to return the name of the Java wrapper class when the type is a Java primitive type; * {@code false}, to return the exact binary name (unboxed name) of the Java type. * * @return The Java type name of the type referenced by the property or {@code null}, if the property does not * reference a type. * * @throws NullPointerException if {@code property} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Property#getJavaTypeName() * @see JavaTypeName#getBoxedName() * @see JavaTypeName#getName(boolean) * * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaTypeName()}. This method will be removed in * JOMC 2.0. */ @Deprecated public String getJavaTypeName( final Property property, final boolean boxify ) throws ModelObjectException { if ( property == null ) { throw new NullPointerException( "property" ); } JavaTypeName javaTypeName = property.getJavaTypeName(); if ( javaTypeName != null ) { if ( boxify && javaTypeName.isPrimitive() ) { javaTypeName = javaTypeName.getBoxedName(); } return javaTypeName.getName( true ); } return null; } /** * Gets a flag indicating the type of a given property is a Java primitive. * * @param property The property to query. * * @return {@code true}, if the Java type referenced by the property is primitive or {@code false}, if the property * does not reference a type or if the Java type referenced by the property is not primitive. * * @throws NullPointerException if {@code property} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Property#getJavaTypeName() * @see JavaTypeName#isPrimitive() * * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaTypeName()}. This method will be removed in * JOMC 2.0. */ @Deprecated public boolean isJavaPrimitiveType( final Property property ) throws ModelObjectException { if ( property == null ) { throw new NullPointerException( "property" ); } final JavaTypeName javaTypeName = property.getJavaTypeName(); return javaTypeName != null && javaTypeName.isPrimitive(); } /** * Gets the name of a Java getter method of a given property. * * @param property The property to get a Java getter method name of. * * @return The Java getter method name of {@code property}. * * @throws NullPointerException if {@code property} is {@code null}. * @throws ModelObjectException if compiling the name of the property to a {@code JavaIdentifier} fails. * * @see Property#getJavaGetterMethodName() * * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaGetterMethodName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaGetterMethodName( final Property property ) throws ModelObjectException { if ( property == null ) { throw new NullPointerException( "property" ); } String prefix = "get"; final String javaTypeName = this.getJavaTypeName( property, true ); if ( Boolean.class.getName().equals( javaTypeName ) ) { prefix = "is"; } return prefix + this.getJavaIdentifier( property.getName(), true ); } /** * Gets the name of a Java setter method of a given property. * * @param property The property to get a Java setter method name of. * * @return The Java setter method name of {@code property}. * * @throws NullPointerException if {@code property} is {@code null}. * @throws ModelObjectException if compiling the name of the property to a {@code JavaIdentifier} fails. * * @see Property#getJavaSetterMethodName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaSetterMethodName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaSetterMethodName( final Property property ) throws ModelObjectException { if ( property == null ) { throw new NullPointerException( "property" ); } return "set" + this.getJavaIdentifier( property.getName(), true ); } /** * Gets a Java method parameter name of a property. * * @param property The property to get the Java method parameter name of. * * @return The Java method parameter name of {@code property}. * * @throws NullPointerException if {@code property} is {@code null}. * @throws ModelObjectException if copmiling the name of the property to a {@code JavaIdentifier} fails. * * @see Property#getJavaVariableName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaVariableName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaMethodParameterName( final Property property ) throws ModelObjectException { if ( property == null ) { throw new NullPointerException( "property" ); } return this.getJavaMethodParameterName( property.getName() ); } /** * Gets a Java field name of a property. * * @param property The property to get the Java field name of. * * @return The Java field name of {@code property}. * * @throws NullPointerException if {@code property} is {@code null}. * @throws ModelObjectException if compiling the name of the property to a {@code JavaIdentifier} fails. * * @see Property#getJavaVariableName() * * @since 1.3 * * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaVariableName()}. This method will be removed * in JOMC 2.0. */ @Deprecated public String getJavaFieldName( final Property property ) throws ModelObjectException { if ( property == null ) { throw new NullPointerException( "property" ); } return this.getJavaFieldName( property.getName() ); } /** * Gets the name of a Java type of a given dependency. * * @param dependency The dependency to get a dependency Java type name of. * * @return The Java type name of the dependency or {@code null}, if the referenced specification is not found or * does not reference a type. * * @throws NullPointerException if {@code dependency} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @deprecated As of JOMC 1.4, please use method {@link Modules#getDependencyJavaTypeName(java.lang.String, java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public String getJavaTypeName( final Dependency dependency ) throws ModelObjectException { if ( dependency == null ) { throw new NullPointerException( "dependency" ); } Specification s = null; StringBuilder typeName = null; String javaTypeName = null; try { if ( this.getModules() != null && ( s = this.getModules().getSpecification( dependency.getIdentifier() ) ) != null ) { if ( s.getClazz() != null ) { typeName = new StringBuilder( s.getClazz().length() ); typeName.append( this.getJavaTypeName( s, true ) ); if ( s.getMultiplicity() == Multiplicity.MANY && dependency.getImplementationName() == null ) { typeName.append( "[]" ); } javaTypeName = JavaTypeName.parse( typeName.toString() ).getName( true ); } } else if ( this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "specificationNotFound", dependency.getIdentifier() ), null ); } return javaTypeName; } catch ( final ParseException e ) { throw new ModelObjectException( getMessage( "dependencyJavaTypeNameParseException", typeName, getMessage( e ) ), e ); } } /** * Gets the name of a Java getter method of a given dependency. * * @param dependency The dependency to get a Java getter method name of. * * @return The Java getter method name of {@code dependency}. * * @throws NullPointerException if {@code dependency} is {@code null}. * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. * * @see Dependency#getJavaGetterMethodName() * * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaGetterMethodName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaGetterMethodName( final Dependency dependency ) throws ModelObjectException { if ( dependency == null ) { throw new NullPointerException( "dependency" ); } return "get" + this.getJavaIdentifier( dependency.getName(), true ); } /** * Gets the name of a Java setter method of a given dependency. * * @param dependency The dependency to get a Java setter method name of. * * @return The Java setter method name of {@code dependency}. * * @throws NullPointerException if {@code dependency} is {@code null}. * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. * * @see Dependency#getJavaSetterMethodName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaSetterMethodName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaSetterMethodName( final Dependency dependency ) throws ModelObjectException { if ( dependency == null ) { throw new NullPointerException( "dependency" ); } return "set" + this.getJavaIdentifier( dependency.getName(), true ); } /** * Gets a Java method parameter name of a dependency. * * @param dependency The dependency to get the Java method parameter name of. * * @return The Java method parameter name of {@code dependency}. * * @throws NullPointerException if {@code dependency} is {@code null}. * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. * * @see Dependency#getJavaVariableName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaVariableName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaMethodParameterName( final Dependency dependency ) throws ModelObjectException { if ( dependency == null ) { throw new NullPointerException( "dependency" ); } return this.getJavaMethodParameterName( dependency.getName() ); } /** * Gets a Java field name of a dependency. * * @param dependency The dependency to get the Java field name of. * * @return The Java field name of {@code dependency}. * * @throws NullPointerException if {@code dependency} is {@code null}. * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. * * @see Dependency#getJavaVariableName() * * @since 1.3 * * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaVariableName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaFieldName( final Dependency dependency ) throws ModelObjectException { if ( dependency == null ) { throw new NullPointerException( "dependency" ); } return this.getJavaFieldName( dependency.getName() ); } /** * Gets the name of a Java getter method of a given message. * * @param message The message to get a Java getter method name of. * * @return The Java getter method name of {@code message}. * * @throws NullPointerException if {@code message} is {@code null}. * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. * * @see Message#getJavaGetterMethodName() * * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaGetterMethodName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaGetterMethodName( final Message message ) throws ModelObjectException { if ( message == null ) { throw new NullPointerException( "message" ); } return "get" + this.getJavaIdentifier( message.getName(), true ); } /** * Gets the name of a Java setter method of a given message. * * @param message The message to get a Java setter method name of. * * @return The Java setter method name of {@code message}. * * @throws NullPointerException if {@code message} is {@code null}. * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. * * @see Message#getJavaSetterMethodName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaSetterMethodName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaSetterMethodName( final Message message ) throws ModelObjectException { if ( message == null ) { throw new NullPointerException( "message" ); } return "set" + this.getJavaIdentifier( message.getName(), true ); } /** * Gets a Java method parameter name of a message. * * @param message The message to get the Java method parameter name of. * * @return The Java method parameter name of {@code message}. * * @throws NullPointerException if {@code message} is {@code null}. * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. * * @see Message#getJavaVariableName() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaVariableName()}. This method will be removed * in JOMC 2.0. */ @Deprecated public String getJavaMethodParameterName( final Message message ) throws ModelObjectException { if ( message == null ) { throw new NullPointerException( "message" ); } return this.getJavaMethodParameterName( message.getName() ); } /** * Gets a Java field name of a message. * * @param message The message to get the Java field name of. * * @return The Java field name of {@code message}. * * @throws NullPointerException if {@code message} is {@code null}. * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. * * @see Message#getJavaVariableName() * * @since 1.3 * * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaVariableName()}. This method will be removed * in JOMC 2.0. */ @Deprecated public String getJavaFieldName( final Message message ) throws ModelObjectException { if ( message == null ) { throw new NullPointerException( "message" ); } return this.getJavaFieldName( message.getName() ); } /** * Gets the Java modifier name of a dependency of a given implementation. * * @param implementation The implementation declaring the dependency to get a Java modifier name of. * @param dependency The dependency to get a Java modifier name of. * * @return The Java modifier name of {@code dependency} of {@code implementation}. * * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}. * * @deprecated As of JOMC 1.4, please use method {@link Modules#getDependencyJavaModifierName(java.lang.String, java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public String getJavaModifierName( final Implementation implementation, final Dependency dependency ) { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } if ( dependency == null ) { throw new NullPointerException( "dependency" ); } String modifierName = "private"; if ( this.getModules() != null ) { modifierName = this.getModules().getDependencyJavaModifierName( implementation.getIdentifier(), dependency.getName() ); if ( modifierName == null ) { modifierName = "private"; } } return modifierName; } /** * Gets the Java modifier name of a message of a given implementation. * * @param implementation The implementation declaring the message to get a Java modifier name of. * @param message The message to get a Java modifier name of. * * @return The Java modifier name of {@code message} of {@code implementation}. * * @throws NullPointerException if {@code implementation} or {@code message} is {@code null}. * * @deprecated As of JOMC 1.4, please use method {@link Modules#getMessageJavaModifierName(java.lang.String, java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public String getJavaModifierName( final Implementation implementation, final Message message ) { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } if ( message == null ) { throw new NullPointerException( "message" ); } String modifierName = "private"; if ( this.getModules() != null ) { modifierName = this.getModules().getMessageJavaModifierName( implementation.getIdentifier(), message.getName() ); if ( modifierName == null ) { modifierName = "private"; } } return modifierName; } /** * Gets the Java modifier name of a property of a given implementation. * * @param implementation The implementation declaring the property to get a Java modifier name of. * @param property The property to get a Java modifier name of. * * @return The Java modifier name of {@code property} of {@code implementation}. * * @throws NullPointerException if {@code implementation} or {@code property} is {@code null}. * * @deprecated As of JOMC 1.4, please use method {@link Modules#getPropertyJavaModifierName(java.lang.String, java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public String getJavaModifierName( final Implementation implementation, final Property property ) { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } if ( property == null ) { throw new NullPointerException( "property" ); } String modifierName = "private"; if ( this.getModules() != null ) { modifierName = this.getModules().getPropertyJavaModifierName( implementation.getIdentifier(), property.getName() ); if ( modifierName == null ) { modifierName = "private"; } } return modifierName; } /** * Formats a text to a Javadoc comment. * * @param text The text to format to a Javadoc comment. * @param indentationLevel The indentation level of the comment. * @param linePrefix The text to prepend lines with. * * @return {@code text} formatted to a Javadoc comment. * * @throws NullPointerException if {@code text} or {@code linePrefix} is {@code null}. * @throws IllegalArgumentException if {@code indentationLevel} is negative. * @throws ModelObjectException if compiling the type of the text to a {@code MimeType} fails. * * @deprecated As of JOMC 1.4, please use method {@link Text#getJavadocComment(java.lang.String, java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public String getJavadocComment( final Text text, final int indentationLevel, final String linePrefix ) throws ModelObjectException { if ( text == null ) { throw new NullPointerException( "text" ); } if ( linePrefix == null ) { throw new NullPointerException( "linePrefix" ); } if ( indentationLevel < 0 ) { throw new IllegalArgumentException( Integer.toString( indentationLevel ) ); } BufferedReader reader = null; boolean suppressExceptionOnClose = true; try { String javadoc = ""; if ( text.getValue() != null ) { final String indent = this.getIndentation( indentationLevel ); reader = new BufferedReader( new StringReader( text.getValue() ) ); final StringBuilder builder = new StringBuilder( text.getValue().length() ); String line; while ( ( line = reader.readLine() ) != null ) { builder.append( this.getLineSeparator() ).append( indent ).append( linePrefix ). append( line.replaceAll( "\\/\\*\\*", "/*" ).replaceAll( "\\*/", "/" ) ); } if ( builder.length() > 0 ) { javadoc = builder.substring( this.getLineSeparator().length() + indent.length() + linePrefix.length() ); if ( !text.getMimeType().match( "text/html" ) ) { javadoc = StringEscapeUtils.escapeHtml( javadoc ); } } } suppressExceptionOnClose = false; return javadoc; } catch ( final MimeTypeParseException e ) { throw new AssertionError( e ); } catch ( final IOException e ) { throw new AssertionError( e ); } finally { try { if ( reader != null ) { reader.close(); } } catch ( final IOException e ) { if ( suppressExceptionOnClose ) { this.log( Level.SEVERE, getMessage( e ), e ); } else { throw new AssertionError( e ); } } } } /** * Formats a text from a list of texts to a Javadoc comment. * * @param texts The list of texts to format to a Javadoc comment. * @param indentationLevel The indentation level of the comment. * @param linePrefix The text to prepend lines with. * * @return The text corresponding to the locale of the instance from the list of texts formatted to a Javadoc * comment. * * @throws NullPointerException if {@code texts} or {@code linePrefix} is {@code null}. * @throws IllegalArgumentException if {@code indentationLevel} is negative. * @throws ModelObjectException if compiling a referenced type to a {@code MimeType} fails. * * @see #getLocale() * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link Text#getJavadocComment(java.lang.String, java.lang.String)}. * This method will be removed in JOMC 2.0. */ @Deprecated public String getJavadocComment( final Texts texts, final int indentationLevel, final String linePrefix ) throws ModelObjectException { if ( texts == null ) { throw new NullPointerException( "texts" ); } if ( linePrefix == null ) { throw new NullPointerException( "linePrefix" ); } if ( indentationLevel < 0 ) { throw new IllegalArgumentException( Integer.toString( indentationLevel ) ); } return this.getJavadocComment( texts.getText( this.getLocale().getLanguage() ), indentationLevel, linePrefix ); } /** * Formats a string to a Java string with unicode escapes. * * @param str The string to format to a Java string or {@code null}. * * @return {@code str} formatted to a Java string or {@code null}. * * @see StringEscapeUtils#escapeJava(java.lang.String) */ public String getJavaString( final String str ) { return StringEscapeUtils.escapeJava( str ); } /** * Formats a string to a Java class path location. * * @param str The string to format or {@code null}. * @param absolute {@code true} to return an absolute class path location; {@code false} to return a relative * class path location. * * @return {@code str} formatted to a Java class path location. * * @since 1.3 * * @deprecated As of JOMC 1.4, please use {@link JavaTypeName#getQualifiedName()}. This method will be removed in * JOMC 2.0. */ @Deprecated public String getJavaClasspathLocation( final String str, final boolean absolute ) { String classpathLocation = null; if ( str != null ) { classpathLocation = str.replace( '.', '/' ); if ( absolute ) { classpathLocation = "/" + classpathLocation; } } return classpathLocation; } /** * Formats a string to a Java identifier. * * @param str The string to format or {@code null}. * @param capitalize {@code true}, to return an identifier with the first character upper cased; {@code false}, to * return an identifier with the first character lower cased. * * @return {@code str} formatted to a Java identifier or {@code null}. * * @since 1.2 * * @deprecated As of JOMC 1.4, please use method {@link #toJavaVariableName(java.lang.String)}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaIdentifier( final String str, final boolean capitalize ) { String identifier = null; if ( str != null ) { final int len = str.length(); final StringBuilder builder = new StringBuilder( len ); boolean uc = capitalize; for ( int i = 0; i < len; i++ ) { final char c = str.charAt( i ); final String charString = Character.toString( c ); if ( builder.length() > 0 ) { if ( Character.isJavaIdentifierPart( c ) ) { builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString ); uc = false; } else { uc = true; } } else { if ( Character.isJavaIdentifierStart( c ) ) { builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString.toLowerCase( this.getLocale() ) ); uc = false; } else { uc = capitalize; } } } identifier = builder.toString(); if ( identifier.length() <= 0 && this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "invalidJavaIdentifier", str ), null ); } } return identifier; } /** * Formats a string to a Java method parameter name. * * @param str The string to format or {@code null}. * * @return {@code str} formatted to a Java method parameter name or {@code null}. * * @since 1.3 * * @deprecated As of JOMC 1.4, please use method {@link #toJavaVariableName(java.lang.String)}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaMethodParameterName( final String str ) { String methodParameterName = null; if ( str != null ) { final int len = str.length(); final StringBuilder builder = new StringBuilder( len ); boolean uc = false; for ( int i = 0; i < len; i++ ) { final char c = str.charAt( i ); final String charString = Character.toString( c ); if ( builder.length() > 0 ) { if ( Character.isJavaIdentifierPart( c ) ) { builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString ); uc = false; } else { uc = true; } } else if ( Character.isJavaIdentifierStart( c ) ) { builder.append( charString.toLowerCase( this.getLocale() ) ); } } methodParameterName = builder.toString(); if ( methodParameterName.length() <= 0 && this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "invalidJavaMethodParameterName", str ), null ); } if ( this.getJavaKeywords().contains( methodParameterName ) ) { methodParameterName = "_" + methodParameterName; } } return methodParameterName; } /** * Formats a string to a Java field name. * * @param str The string to format or {@code null}. * * @return {@code str} formatted to a Java field name or {@code null}. * * @since 1.3 * * @deprecated As of JOMC 1.4, please use method {@link #toJavaVariableName(java.lang.String)}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaFieldName( final String str ) { String fieldName = null; if ( str != null ) { final int len = str.length(); final StringBuilder builder = new StringBuilder( len ); boolean uc = false; for ( int i = 0; i < len; i++ ) { final char c = str.charAt( i ); final String charString = Character.toString( c ); if ( builder.length() > 0 ) { if ( Character.isJavaIdentifierPart( c ) ) { builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString ); uc = false; } else { uc = true; } } else if ( Character.isJavaIdentifierStart( c ) ) { builder.append( charString.toLowerCase( this.getLocale() ) ); } } fieldName = builder.toString(); if ( fieldName.length() <= 0 && this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "invalidJavaFieldName", str ), null ); } if ( this.getJavaKeywords().contains( fieldName ) ) { fieldName = "_" + fieldName; } } return fieldName; } /** * Formats a string to a Java constant name. * * @param str The string to format or {@code null}. * * @return {@code str} formatted to a Java constant name or {@code null}. * * @since 1.3 * * @deprecated As of JOMC 1.4, please use method {@link #toJavaConstantName(java.lang.String)}. This method will be * removed in JOMC 2.0. */ @Deprecated public String getJavaConstantName( final String str ) { String name = null; if ( str != null ) { final int len = str.length(); final StringBuilder builder = new StringBuilder( len ); boolean separator = false; for ( int i = 0; i < len; i++ ) { final char c = str.charAt( i ); if ( builder.length() > 0 ? Character.isJavaIdentifierPart( c ) : Character.isJavaIdentifierStart( c ) ) { if ( builder.length() > 0 ) { if ( !separator ) { final char previous = builder.charAt( builder.length() - 1 ); separator = Character.isLowerCase( previous ) && Character.isUpperCase( c ); } if ( separator ) { builder.append( '_' ); } } builder.append( c ); separator = false; } else { separator = true; } } name = builder.toString().toUpperCase( this.getLocale() ); if ( name.length() <= 0 && this.isLoggable( Level.WARNING ) ) { this.log( Level.WARNING, getMessage( "invalidJavaConstantName", str ), null ); } } return name; } /** * Compiles a string to a Java constant name. * * @param str The string to compile or {@code null}. * * @return {@code str} compiled to a {@code JavaIdentifier} or {@code null}, if {@code str} is {@code null}. * * @throws ParseException if compiling {@code str} to a {@code JavaIdentifier} fails. * * @since 1.3 * * @see JavaIdentifier#normalize(java.lang.String, org.jomc.model.JavaIdentifier.NormalizationMode) * @see org.jomc.model.JavaIdentifier.NormalizationMode#CONSTANT_NAME_CONVENTION */ public JavaIdentifier toJavaConstantName( final String str ) throws ParseException { JavaIdentifier constantName = null; if ( str != null ) { constantName = JavaIdentifier.normalize( str, JavaIdentifier.NormalizationMode.CONSTANT_NAME_CONVENTION ); } return constantName; } /** * Compiles a string to a Java method name. * * @param str The string to compile or {@code null}. * * @return {@code str} compiled to a {@code JavaIdentifier} or {@code null}, if {@code str} is {@code null}. * * @throws ParseException if compiling {@code str} to a {@code JavaIdentifier} fails. * * @since 1.4 * * @see JavaIdentifier#normalize(java.lang.String, org.jomc.model.JavaIdentifier.NormalizationMode) * @see org.jomc.model.JavaIdentifier.NormalizationMode#METHOD_NAME_CONVENTION */ public JavaIdentifier toJavaMethodName( final String str ) throws ParseException { JavaIdentifier variableName = null; if ( str != null ) { variableName = JavaIdentifier.normalize( str, JavaIdentifier.NormalizationMode.METHOD_NAME_CONVENTION ); } return variableName; } /** * Compiles a string to a Java variable name. * * @param str The string to compile or {@code null}. * * @return {@code str} compiled to a {@code JavaIdentifier} or {@code null}, if {@code str} is {@code null}. * * @throws ParseException if compiling {@code str} to a {@code JavaIdentifier} fails. * * @since 1.4 * * @see JavaIdentifier#normalize(java.lang.String, org.jomc.model.JavaIdentifier.NormalizationMode) * @see org.jomc.model.JavaIdentifier.NormalizationMode#VARIABLE_NAME_CONVENTION */ public JavaIdentifier toJavaVariableName( final String str ) throws ParseException { JavaIdentifier variableName = null; if ( str != null ) { variableName = JavaIdentifier.normalize( str, JavaIdentifier.NormalizationMode.VARIABLE_NAME_CONVENTION ); } return variableName; } /** * Gets a flag indicating the type referenced by a given specification is located in an unnamed Java package. * * @param specification The specification to query. * * @return {@code true}, if the type referenced by {@code specification} is located in an unnamed Java package; * {@code false}, if the specification does not reference a type or if the referenced type is not located in an * unnamed Java package. * * @throws NullPointerException if {@code specification} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Specification#getJavaTypeName() * @see JavaTypeName#isUnnamedPackage() * * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public boolean isJavaDefaultPackage( final Specification specification ) throws ModelObjectException { if ( specification == null ) { throw new NullPointerException( "specification" ); } final JavaTypeName javaTypeName = specification.getJavaTypeName(); return javaTypeName != null && javaTypeName.isUnnamedPackage(); } /** * Gets a flag indicating the type referenced by a given implementation is located in an unnamed Java package. * * @param implementation The implementation to query. * * @return {@code true}, if the type referenced by {@code implementation} is located in an unnamed Java package; * {@code false}, if the implementation does not reference a type or if the referenced type is not located in an * unnamed Java package. * * @throws NullPointerException if {@code implementation} is {@code null}. * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. * * @see Implementation#getJavaTypeName() * @see JavaTypeName#isUnnamedPackage() * * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be * removed in JOMC 2.0. */ @Deprecated public boolean isJavaDefaultPackage( final Implementation implementation ) throws ModelObjectException { if ( implementation == null ) { throw new NullPointerException( "implementation" ); } final JavaTypeName javaTypeName = implementation.getJavaTypeName(); return javaTypeName != null && javaTypeName.isUnnamedPackage(); } /** * Formats a string to a HTML string with HTML entities. * * @param str The string to format to a HTML string with HTML entities or {@code null}. * * @return {@code str} formatted to a HTML string with HTML entities or {@code null}. * * @since 1.2 */ public String getHtmlString( final String str ) { return str != null ? str.replace( "&", "&" ).replace( "<", "<" ).replace( ">", ">" ). replace( "\"", """ ).replace( "*", "∗" ) : null; } /** * Formats a string to a XML string with XML entities. * * @param str The string to format to a XML string with XML entities or {@code null}. * * @return {@code str} formatted to a XML string with XML entities or {@code null}. * * @see StringEscapeUtils#escapeXml(java.lang.String) * * @since 1.2 */ public String getXmlString( final String str ) { return StringEscapeUtils.escapeXml( str ); } /** * Formats a string to a JavaScript string applying JavaScript string rules. * * @param str The string to format to a JavaScript string by applying JavaScript string rules or {@code null}. * * @return {@code str} formatted to a JavaScript string with JavaScript string rules applied or {@code null}. * * @see StringEscapeUtils#escapeJavaScript(java.lang.String) * * @since 1.2 */ public String getJavaScriptString( final String str ) { return StringEscapeUtils.escapeJavaScript( str ); } /** * Formats a string to a SQL string. * * @param str The string to format to a SQL string or {@code null}. * * @return {@code str} formatted to a SQL string or {@code null}. * * @see StringEscapeUtils#escapeSql(java.lang.String) * * @since 1.2 */ public String getSqlString( final String str ) { return StringEscapeUtils.escapeSql( str ); } /** * Formats a string to a CSV string. * * @param str The string to format to a CSV string or {@code null}. * * @return {@code str} formatted to a CSV string or {@code null}. * * @see StringEscapeUtils#escapeCsv(java.lang.String) * * @since 1.2 */ public String getCsvString( final String str ) { return StringEscapeUtils.escapeCsv( str ); } /** * Formats a {@code Boolean} to a string. * * @param b The {@code Boolean} to format to a string or {@code null}. * * @return {@code b} formatted to a string. * * @see #getLocale() * * @since 1.2 */ public String getBooleanString( final Boolean b ) { final MessageFormat messageFormat = new MessageFormat( ResourceBundle.getBundle( JomcTool.class.getName().replace( '.', '/' ), this.getLocale() ). getString( b ? "booleanStringTrue" : "booleanStringFalse" ), this.getLocale() ); return messageFormat.format( null ); } /** * Gets the display language of a given language code. * * @param language The language code to get the display language of. * * @return The display language of {@code language}. * * @throws NullPointerException if {@code language} is {@code null}. */ public String getDisplayLanguage( final String language ) { if ( language == null ) { throw new NullPointerException( "language" ); } final Locale l = new Locale( language ); return l.getDisplayLanguage( l ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date of {@code calendar} formatted using a short format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#SHORT */ public String getShortDate( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getDateInstance( DateFormat.SHORT, this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date of {@code calendar} formatted using a medium format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#MEDIUM * * @since 1.2 */ public String getMediumDate( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getDateInstance( DateFormat.MEDIUM, this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date of {@code calendar} formatted using a long format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#LONG */ public String getLongDate( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getDateInstance( DateFormat.LONG, this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date of {@code calendar} formatted using an ISO-8601 format style. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see SimpleDateFormat yyyy-DDD * * @since 1.2 */ public String getIsoDate( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return new SimpleDateFormat( "yyyy-DDD", this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The time of {@code calendar} formatted using a short format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#SHORT */ public String getShortTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getTimeInstance( DateFormat.SHORT, this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The time of {@code calendar} formatted using a medium format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#MEDIUM * * @since 1.2 */ public String getMediumTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getTimeInstance( DateFormat.MEDIUM, this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The time of {@code calendar} formatted using a long format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#LONG */ public String getLongTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getTimeInstance( DateFormat.LONG, this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The time of {@code calendar} formatted using an ISO-8601 format style. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see SimpleDateFormat HH:mm * * @since 1.2 */ public String getIsoTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return new SimpleDateFormat( "HH:mm", this.getLocale() ).format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date and time of {@code calendar} formatted using a short format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#SHORT */ public String getShortDateTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, this.getLocale() ). format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date and time of {@code calendar} formatted using a medium format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#MEDIUM * * @since 1.2 */ public String getMediumDateTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getDateTimeInstance( DateFormat.MEDIUM, DateFormat.MEDIUM, this.getLocale() ). format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date and time of {@code calendar} formatted using a long format style pattern. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see DateFormat#LONG */ public String getLongDateTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } return DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG, this.getLocale() ). format( calendar.getTime() ); } /** * Formats a calendar instance to a string. * * @param calendar The calendar to format to a string. * * @return The date and time of {@code calendar} formatted using a ISO-8601 format style. * * @throws NullPointerException if {@code calendar} is {@code null}. * * @see SimpleDateFormat yyyy-MM-dd'T'HH:mm:ssZ * * @since 1.2 */ public String getIsoDateTime( final Calendar calendar ) { if ( calendar == null ) { throw new NullPointerException( "calendar" ); } // JDK: As of JDK 7, "yyyy-MM-dd'T'HH:mm:ssXXX". return new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ", this.getLocale() ).format( calendar.getTime() ); } /** * Gets a string describing the range of years for given calendars. * * @param start The start of the range. * @param end The end of the range. * * @return Formatted range of the years of {@code start} and {@code end} (e.g. {@code "start - end"}). * * @throws NullPointerException if {@code start} or {@code end} is {@code null}. */ public String getYears( final Calendar start, final Calendar end ) { if ( start == null ) { throw new NullPointerException( "start" ); } if ( end == null ) { throw new NullPointerException( "end" ); } final Format yearFormat = new SimpleDateFormat( "yyyy", this.getLocale() ); final int s = start.get( Calendar.YEAR ); final int e = end.get( Calendar.YEAR ); final StringBuilder years = new StringBuilder(); if ( s != e ) { if ( s < e ) { years.append( yearFormat.format( start.getTime() ) ).append( " - " ). append( yearFormat.format( end.getTime() ) ); } else { years.append( yearFormat.format( end.getTime() ) ).append( " - " ). append( yearFormat.format( start.getTime() ) ); } } else { years.append( yearFormat.format( start.getTime() ) ); } return years.toString(); } /** * Gets the model of the instance. * * @return The model of the instance. * * @see #getModules() * @see #setModel(org.jomc.modlet.Model) */ public final Model getModel() { if ( this.model == null ) { this.model = new Model(); this.model.setIdentifier( ModelObject.MODEL_PUBLIC_ID ); } return this.model; } /** * Sets the model of the instance. * * @param value The new model of the instance or {@code null}. * * @see #getModel() */ public final void setModel( final Model value ) { this.model = value; } /** * Gets the modules of the model of the instance. * * @return The modules of the model of the instance or {@code null}, if no modules are found. * * @see #getModel() * @see #setModel(org.jomc.modlet.Model) */ public final Modules getModules() { return ModelHelper.getModules( this.getModel() ); } /** * Gets the {@code VelocityEngine} of the instance. * * @return The {@code VelocityEngine} of the instance. * * @throws IOException if initializing a new velocity engine fails. * * @see #setVelocityEngine(org.apache.velocity.app.VelocityEngine) */ public final VelocityEngine getVelocityEngine() throws IOException { if ( this.velocityEngine == null ) { /** * {@code LogChute} logging to the listeners of the tool. */ class JomcLogChute implements LogChute { JomcLogChute() { super(); } public void init( final RuntimeServices runtimeServices ) throws Exception { } public void log( final int level, final String message ) { this.log( level, message, null ); } public void log( final int level, final String message, final Throwable throwable ) { JomcTool.this.log( Level.FINEST, message, throwable ); } public boolean isLevelEnabled( final int level ) { return isLoggable( Level.FINEST ); } } final VelocityEngine engine = new VelocityEngine(); engine.setProperty( RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE.toString() ); engine.setProperty( RuntimeConstants.VM_ARGUMENTS_STRICT, Boolean.TRUE.toString() ); engine.setProperty( RuntimeConstants.STRICT_MATH, Boolean.TRUE.toString() ); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new JomcLogChute() ); engine.setProperty( RuntimeConstants.RESOURCE_LOADER, "class" ); engine.setProperty( "class.resource.loader.class", ClasspathResourceLoader.class.getName() ); engine.setProperty( "class.resource.loader.cache", Boolean.TRUE.toString() ); if ( this.getTemplateLocation() != null ) { engine.setProperty( RuntimeConstants.RESOURCE_LOADER, "class,url" ); engine.setProperty( "url.resource.loader.class", URLResourceLoader.class.getName() ); engine.setProperty( "url.resource.loader.cache", Boolean.TRUE.toString() ); engine.setProperty( "url.resource.loader.root", this.getTemplateLocation().toExternalForm() ); engine.setProperty( "url.resource.loader.timeout", Integer.toString( 60000 ) ); } this.velocityEngine = engine; this.defaultVelocityEngine = true; } return this.velocityEngine; } /** * Sets the {@code VelocityEngine} of the instance. * * @param value The new {@code VelocityEngine} of the instance or {@code null}. * * @see #getVelocityEngine() */ public final void setVelocityEngine( final VelocityEngine value ) { this.velocityEngine = value; this.defaultVelocityEngine = false; } /** * Gets a new velocity context used for merging templates. * * @return A new velocity context used for merging templates. * * @throws IOException if creating a new context instance fails. * * @see #getTemplateParameters() */ public VelocityContext getVelocityContext() throws IOException { final Calendar now = Calendar.getInstance(); final VelocityContext ctx = new VelocityContext( new HashMap( this.getTemplateParameters() ) ); this.mergeTemplateProfileContextProperties( this.getTemplateProfile(), this.getLocale().getLanguage(), ctx ); this.mergeTemplateProfileContextProperties( this.getTemplateProfile(), null, ctx ); final Model clonedModel = this.getModel().clone(); final Modules clonedModules = ModelHelper.getModules( clonedModel ); assert clonedModules != null : "Unexpected missing modules for model '" + clonedModel.getIdentifier() + "'."; ctx.put( "model", clonedModel ); ctx.put( "modules", clonedModules ); ctx.put( "imodel", new InheritanceModel( clonedModules ) ); ctx.put( "tool", this ); ctx.put( "toolName", this.getClass().getName() ); ctx.put( "toolVersion", getMessage( "projectVersion" ) ); ctx.put( "toolUrl", getMessage( "projectUrl" ) ); ctx.put( "calendar", now.getTime() ); // JDK: As of JDK 7, "yyyy-MM-dd'T'HH:mm:ss.SSSXXX". ctx.put( "now", new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ", this.getLocale() ).format( now.getTime() ) ); ctx.put( "year", new SimpleDateFormat( "yyyy", this.getLocale() ).format( now.getTime() ) ); ctx.put( "month", new SimpleDateFormat( "MM", this.getLocale() ).format( now.getTime() ) ); ctx.put( "day", new SimpleDateFormat( "dd", this.getLocale() ).format( now.getTime() ) ); ctx.put( "hour", new SimpleDateFormat( "HH", this.getLocale() ).format( now.getTime() ) ); ctx.put( "minute", new SimpleDateFormat( "mm", this.getLocale() ).format( now.getTime() ) ); ctx.put( "second", new SimpleDateFormat( "ss", this.getLocale() ).format( now.getTime() ) ); ctx.put( "timezone", new SimpleDateFormat( "Z", this.getLocale() ).format( now.getTime() ) ); ctx.put( "shortDate", this.getShortDate( now ) ); ctx.put( "mediumDate", this.getMediumDate( now ) ); ctx.put( "longDate", this.getLongDate( now ) ); ctx.put( "isoDate", this.getIsoDate( now ) ); ctx.put( "shortTime", this.getShortTime( now ) ); ctx.put( "mediumTime", this.getMediumTime( now ) ); ctx.put( "longTime", this.getLongTime( now ) ); ctx.put( "isoTime", this.getIsoTime( now ) ); ctx.put( "shortDateTime", this.getShortDateTime( now ) ); ctx.put( "mediumDateTime", this.getMediumDateTime( now ) ); ctx.put( "longDateTime", this.getLongDateTime( now ) ); ctx.put( "isoDateTime", this.getIsoDateTime( now ) ); return ctx; } /** * Gets the template parameters of the instance. *

* This accessor method returns a reference to the live map, not a snapshot. Therefore any modification you make * to the returned map will be present inside the object. This is why there is no {@code set} method for the * template parameters property. *

* * @return The template parameters of the instance. * * @see #getVelocityContext() * * @since 1.2 */ public final Map getTemplateParameters() { if ( this.templateParameters == null ) { this.templateParameters = Collections.synchronizedMap( new HashMap() ); } return this.templateParameters; } /** * Gets the location to search for templates in addition to searching the class path. * * @return The location to search for templates in addition to searching the class path or {@code null}. * * @see #setTemplateLocation(java.net.URL) * * @since 1.2 */ public final URL getTemplateLocation() { return this.templateLocation; } /** * Sets the location to search for templates in addition to searching the class path. * * @param value The new location to search for templates in addition to searching the class path or {@code null}. * * @see #getTemplateLocation() * * @since 1.2 */ public final void setTemplateLocation( final URL value ) { this.templateLocation = value; this.templateProfileContextPropertiesCache = null; this.templateProfilePropertiesCache = null; if ( this.defaultVelocityEngine ) { this.setVelocityEngine( null ); } } /** * Gets the encoding to use for reading templates. * * @return The encoding to use for reading templates. * * @see #setTemplateEncoding(java.lang.String) * * @deprecated As of JOMC 1.3, replaced by method {@link #getDefaultTemplateEncoding()}. This method will be removed * in JOMC 2.0. */ @Deprecated public final String getTemplateEncoding() { return this.getDefaultTemplateEncoding(); } /** * Sets the encoding to use for reading templates. * * @param value The new encoding to use for reading templates or {@code null}. * * @see #getTemplateEncoding() * * @deprecated As of JOMC 1.3, replaced by method {@link #setDefaultTemplateEncoding(java.lang.String)}. This method * will be removed in JOMC 2.0. */ @Deprecated public final void setTemplateEncoding( final String value ) { this.setDefaultTemplateEncoding( value ); } /** * Gets the default encoding used for reading templates. * * @return The default encoding used for reading templates. * * @see #setDefaultTemplateEncoding(java.lang.String) * * @since 1.3 */ public final String getDefaultTemplateEncoding() { if ( this.defaultTemplateEncoding == null ) { this.defaultTemplateEncoding = getMessage( "buildSourceEncoding" ); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultTemplateEncoding", this.defaultTemplateEncoding ), null ); } } return this.defaultTemplateEncoding; } /** * Sets the default encoding to use for reading templates. * * @param value The new default encoding to use for reading templates or {@code null}. * * @see #getDefaultTemplateEncoding() * * @since 1.3 */ public final void setDefaultTemplateEncoding( final String value ) { this.defaultTemplateEncoding = value; this.templateCache = null; } /** * Gets the template encoding of a given template profile. * * @param tp The template profile to get the template encoding of. * * @return The template encoding of the template profile identified by {@code tp} or the default template encoding * if no such encoding is defined. * * @throws NullPointerException if {@code tp} is {@code null}. * * @see #getDefaultTemplateEncoding() * * @since 1.3 */ public final String getTemplateEncoding( final String tp ) { if ( tp == null ) { throw new NullPointerException( "tp" ); } String te = null; try { te = this.getTemplateProfileProperties( tp ).getProperty( TEMPLATE_ENCODING_PROFILE_PROPERTY_NAME ); } catch ( final IOException e ) { if ( this.isLoggable( Level.SEVERE ) ) { this.log( Level.SEVERE, getMessage( e ), e ); } } return te != null ? te : this.getDefaultTemplateEncoding(); } /** * Gets the encoding to use for reading files. * * @return The encoding to use for reading files. * * @see #setInputEncoding(java.lang.String) */ public final String getInputEncoding() { if ( this.inputEncoding == null ) { this.inputEncoding = new InputStreamReader( new ByteArrayInputStream( NO_BYTES ) ).getEncoding(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultInputEncoding", this.inputEncoding ), null ); } } return this.inputEncoding; } /** * Sets the encoding to use for reading files. * * @param value The new encoding to use for reading files or {@code null}. * * @see #getInputEncoding() */ public final void setInputEncoding( final String value ) { this.inputEncoding = value; } /** * Gets the encoding to use for writing files. * * @return The encoding to use for writing files. * * @see #setOutputEncoding(java.lang.String) */ public final String getOutputEncoding() { if ( this.outputEncoding == null ) { this.outputEncoding = new OutputStreamWriter( new ByteArrayOutputStream() ).getEncoding(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultOutputEncoding", this.outputEncoding ), null ); } } return this.outputEncoding; } /** * Sets the encoding to use for writing files. * * @param value The encoding to use for writing files or {@code null}. * * @see #getOutputEncoding() */ public final void setOutputEncoding( final String value ) { this.outputEncoding = value; } /** * Gets the default template profile. *

* The default template profile is the implicit parent profile of any template profile not specifying a parent * template profile. *

* * @return The default template profile. * * @see #setDefaultTemplateProfile(java.lang.String) * * @deprecated The {@code static} modifier of this method and support to setup the default template profile using * a system property will be removed in version 2.0. */ @Deprecated public static String getDefaultTemplateProfile() { if ( defaultTemplateProfile == null ) { defaultTemplateProfile = System.getProperty( "org.jomc.tools.JomcTool.defaultTemplateProfile", DEFAULT_TEMPLATE_PROFILE ); } return defaultTemplateProfile; } /** * Sets the default template profile. * * @param value The new default template profile or {@code null}. * * @see #getDefaultTemplateProfile() * * @deprecated The {@code static} modifier of this method will be removed in version 2.0. */ @Deprecated public static void setDefaultTemplateProfile( final String value ) { defaultTemplateProfile = value; } /** * Gets the template profile of the instance. * * @return The template profile of the instance. * * @see #getDefaultTemplateProfile() * @see #setTemplateProfile(java.lang.String) */ public final String getTemplateProfile() { if ( this.templateProfile == null ) { this.templateProfile = getDefaultTemplateProfile(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultTemplateProfile", this.templateProfile ), null ); } } return this.templateProfile; } /** * Sets the template profile of the instance. * * @param value The new template profile of the instance or {@code null}. * * @see #getTemplateProfile() */ public final void setTemplateProfile( final String value ) { this.templateProfile = value; } /** * Gets the parent template profile of a given template profile. * * @param tp The template profile to get the parent template profile of. * * @return The parent template profile of the template profile identified by {@code tp}; the default template * profile, if no such parent template profile is defined; {@code null}, if {@code tp} denotes the default template * profile. * * @throws NullPointerException if {@code tp} is {@code null}. * * @see #getDefaultTemplateProfile() * * @since 1.3 */ public final String getParentTemplateProfile( final String tp ) { if ( tp == null ) { throw new NullPointerException( "tp" ); } String parentTemplateProfile = null; try { parentTemplateProfile = this.getTemplateProfileProperties( tp ).getProperty( PARENT_TEMPLATE_PROFILE_PROPERTY_NAME ); } catch ( final IOException e ) { if ( this.isLoggable( Level.SEVERE ) ) { this.log( Level.SEVERE, getMessage( e ), e ); } } return parentTemplateProfile != null ? parentTemplateProfile : tp.equals( this.getDefaultTemplateProfile() ) ? null : this.getDefaultTemplateProfile(); } /** * Gets the indentation string of the instance. * * @return The indentation string of the instance. * * @see #setIndentation(java.lang.String) */ public final String getIndentation() { if ( this.indentation == null ) { this.indentation = " "; if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultIndentation", StringEscapeUtils.escapeJava( this.indentation ) ), null ); } } return this.indentation; } /** * Gets an indentation string for a given indentation level. * * @param level The indentation level to get an indentation string for. * * @return The indentation string for {@code level}. * * @throws IllegalArgumentException if {@code level} is negative. * * @see #getIndentation() */ public final String getIndentation( final int level ) { if ( level < 0 ) { throw new IllegalArgumentException( Integer.toString( level ) ); } Map map = this.indentationCache == null ? null : this.indentationCache.get(); if ( map == null ) { map = new ConcurrentHashMap( 8 ); this.indentationCache = new SoftReference>( map ); } final String key = this.getIndentation() + "|" + level; String idt = map.get( key ); if ( idt == null ) { final StringBuilder b = new StringBuilder( this.getIndentation().length() * level ); for ( int i = level; i > 0; i-- ) { b.append( this.getIndentation() ); } idt = b.toString(); map.put( key, idt ); } return idt; } /** * Sets the indentation string of the instance. * * @param value The new indentation string of the instance or {@code null}. * * @see #getIndentation() */ public final void setIndentation( final String value ) { this.indentation = value; } /** * Gets the line separator of the instance. * * @return The line separator of the instance. * * @see #setLineSeparator(java.lang.String) */ public final String getLineSeparator() { if ( this.lineSeparator == null ) { this.lineSeparator = System.getProperty( "line.separator", "\n" ); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultLineSeparator", StringEscapeUtils.escapeJava( this.lineSeparator ) ), null ); } } return this.lineSeparator; } /** * Sets the line separator of the instance. * * @param value The new line separator of the instance or {@code null}. * * @see #getLineSeparator() */ public final void setLineSeparator( final String value ) { this.lineSeparator = value; } /** * Gets the locale of the instance. * * @return The locale of the instance. * * @see #setLocale(java.util.Locale) * * @since 1.2 */ public final Locale getLocale() { if ( this.locale == null ) { this.locale = Locale.ENGLISH; if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "defaultLocale", this.locale ), null ); } } return this.locale; } /** * Sets the locale of the instance. * * @param value The new locale of the instance or {@code null}. * * @see #getLocale() * * @since 1.2 */ public final void setLocale( final Locale value ) { this.locale = value; } /** * Gets a velocity template for a given name. *

* This method searches templates at the following locations recursively in the shown order stopping whenever * a matching template is found. *

    *
  1. org/jomc/tools/templates/{@link #getTemplateProfile() profile}/{@link #getLocale() language}/templateName
  2. *
  3. org/jomc/tools/templates/{@link #getParentTemplateProfile(java.lang.String) parent profile}/{@link #getLocale() language}/templateName
  4. *
  5. org/jomc/tools/templates/{@link #getTemplateProfile() profile}/templateName
  6. *
  7. org/jomc/tools/templates/{@link #getParentTemplateProfile(java.lang.String) parent profile}/{@link #getLocale() language}/templateName
  8. *

* * @param templateName The name of the template to get. * * @return The template matching {@code templateName}. * * @throws NullPointerException if {@code templateName} is {@code null}. * @throws FileNotFoundException if no such template is found. * @throws IOException if getting the template fails. * * @see #getTemplateProfile() * @see #getParentTemplateProfile(java.lang.String) * @see #getLocale() * @see #getTemplateEncoding(java.lang.String) * @see #getVelocityEngine() */ public Template getVelocityTemplate( final String templateName ) throws FileNotFoundException, IOException { if ( templateName == null ) { throw new NullPointerException( "templateName" ); } return this.getVelocityTemplate( this.getTemplateProfile(), templateName ); } /** * Notifies registered listeners. * * @param level The level of the event. * @param message The message of the event or {@code null}. * @param throwable The throwable of the event or {@code null}. * * @throws NullPointerException if {@code level} is {@code null}. * * @see #getListeners() * @see #isLoggable(java.util.logging.Level) */ public void log( final Level level, final String message, final Throwable throwable ) { if ( level == null ) { throw new NullPointerException( "level" ); } if ( this.isLoggable( level ) ) { for ( int i = this.getListeners().size() - 1; i >= 0; i-- ) { this.getListeners().get( i ).onLog( level, message, throwable ); } } } private Template findVelocityTemplate( final String location, final String encoding ) throws IOException { try { return this.getVelocityEngine().getTemplate( location, encoding ); } catch ( final ResourceNotFoundException e ) { if ( this.isLoggable( Level.FINER ) ) { this.log( Level.FINER, getMessage( "templateNotFound", location ), null ); } return null; } catch ( final ParseErrorException e ) { String m = getMessage( e ); m = m == null ? "" : " " + m; // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "invalidTemplate", location, m ) ).initCause( e ); } catch ( final VelocityException e ) { String m = getMessage( e ); m = m == null ? "" : " " + m; // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "velocityException", location, m ) ).initCause( e ); } } private java.util.Properties getTemplateProfileContextProperties( final String profileName, final String language ) throws IOException { Map map = this.templateProfileContextPropertiesCache == null ? null : this.templateProfileContextPropertiesCache.get(); if ( map == null ) { map = new ConcurrentHashMap(); this.templateProfileContextPropertiesCache = new SoftReference>( map ); } final String key = profileName + "|" + language; java.util.Properties profileProperties = map.get( key ); boolean suppressExceptionOnClose = true; if ( profileProperties == null ) { InputStream in = null; URL url = null; profileProperties = new java.util.Properties(); final String resourceName = TEMPLATE_PREFIX + profileName + ( language == null ? "" : "/" + language ) + "/context.properties"; try { url = this.getClass().getResource( "/" + resourceName ); if ( url != null ) { in = url.openStream(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "contextPropertiesFound", url.toExternalForm() ), null ); } profileProperties.load( in ); } else if ( this.getTemplateLocation() != null ) { if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "contextPropertiesNotFound", resourceName ), null ); } url = new URL( this.getTemplateLocation(), resourceName ); in = url.openStream(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "contextPropertiesFound", url.toExternalForm() ), null ); } profileProperties.load( in ); } else if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "contextPropertiesNotFound", resourceName ), null ); } suppressExceptionOnClose = false; } catch ( final FileNotFoundException e ) { if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "contextPropertiesNotFound", url.toExternalForm() ), null ); } } finally { map.put( key, profileProperties ); try { if ( in != null ) { in.close(); } } catch ( final IOException e ) { if ( suppressExceptionOnClose ) { this.log( Level.SEVERE, getMessage( e ), e ); } else { throw e; } } } } return profileProperties; } private void mergeTemplateProfileContextProperties( final String profileName, final String language, final VelocityContext velocityContext ) throws IOException { if ( profileName != null ) { final java.util.Properties templateProfileProperties = this.getTemplateProfileContextProperties( profileName, language ); for ( final Enumeration e = templateProfileProperties.propertyNames(); e.hasMoreElements(); ) { final String name = e.nextElement().toString(); final String value = templateProfileProperties.getProperty( name ); final String[] values = value.split( "\\|" ); if ( !velocityContext.containsKey( name ) ) { final String className = values[0]; try { if ( values.length > 1 ) { final Class valueClass = Class.forName( className ); velocityContext.put( name, valueClass.getConstructor( String.class ).newInstance( values[1] ) ); } else if ( value.contains( "|" ) ) { velocityContext.put( name, Class.forName( values[0] ).newInstance() ); } else { velocityContext.put( name, value ); } } catch ( final InstantiationException ex ) { // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). initCause( ex ); } catch ( final IllegalAccessException ex ) { // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). initCause( ex ); } catch ( final InvocationTargetException ex ) { // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). initCause( ex ); } catch ( final NoSuchMethodException ex ) { // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). initCause( ex ); } catch ( final ClassNotFoundException ex ) { // JDK: As of JDK 6, "new IOException( message, cause )". throw (IOException) new IOException( getMessage( "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). initCause( ex ); } } } this.mergeTemplateProfileContextProperties( this.getParentTemplateProfile( profileName ), language, velocityContext ); } } private java.util.Properties getTemplateProfileProperties( final String profileName ) throws IOException { Map map = this.templateProfilePropertiesCache == null ? null : this.templateProfilePropertiesCache.get(); if ( map == null ) { map = new ConcurrentHashMap(); this.templateProfilePropertiesCache = new SoftReference>( map ); } java.util.Properties profileProperties = map.get( profileName ); boolean suppressExceptionOnClose = true; if ( profileProperties == null ) { InputStream in = null; profileProperties = new java.util.Properties(); final String resourceName = TEMPLATE_PREFIX + profileName + "/profile.properties"; URL url = null; try { url = this.getClass().getResource( "/" + resourceName ); if ( url != null ) { in = url.openStream(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "templateProfilePropertiesFound", url.toExternalForm() ), null ); } profileProperties.load( in ); } else if ( this.getTemplateLocation() != null ) { if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "templateProfilePropertiesNotFound", resourceName ), null ); } url = new URL( this.getTemplateLocation(), resourceName ); in = url.openStream(); if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "templateProfilePropertiesFound", url.toExternalForm() ), null ); } profileProperties.load( in ); } else if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "templateProfilePropertiesNotFound", resourceName ), null ); } suppressExceptionOnClose = false; } catch ( final FileNotFoundException e ) { if ( this.isLoggable( Level.CONFIG ) ) { this.log( Level.CONFIG, getMessage( "templateProfilePropertiesNotFound", url.toExternalForm() ), null ); } } finally { map.put( profileName, profileProperties ); try { if ( in != null ) { in.close(); } } catch ( final IOException e ) { if ( suppressExceptionOnClose ) { this.log( Level.SEVERE, getMessage( e ), e ); } else { throw e; } } } } return profileProperties; } private Set getJavaKeywords() { Reader in = null; Set set = this.javaKeywordsCache == null ? null : this.javaKeywordsCache.get(); try { if ( set == null ) { in = new InputStreamReader( this.getClass().getResourceAsStream( "/" + this.getClass().getPackage().getName().replace( ".", "/" ) + "/JavaKeywords.txt" ), "UTF-8" ); set = new CopyOnWriteArraySet( IOUtils.readLines( in ) ); this.javaKeywordsCache = new SoftReference>( set ); } } catch ( final IOException e ) { throw new IllegalStateException( getMessage( e ), e ); } finally { try { if ( in != null ) { in.close(); } } catch ( final IOException e ) { throw new IllegalStateException( getMessage( e ), e ); } } return set; } private Template getVelocityTemplate( final String tp, final String tn ) throws IOException { Template template = null; if ( tp != null ) { final String key = this.getLocale() + "|" + this.getTemplateProfile() + "|" + this.getDefaultTemplateProfile() + "|" + tn; Map map = this.templateCache == null ? null : this.templateCache.get(); if ( map == null ) { map = new ConcurrentHashMap( 32 ); this.templateCache = new SoftReference>( map ); } TemplateData templateData = map.get( key ); if ( templateData == null ) { templateData = new TemplateData(); if ( !StringUtils.EMPTY.equals( this.getLocale().getLanguage() ) ) { templateData.location = TEMPLATE_PREFIX + tp + "/" + this.getLocale().getLanguage() + "/" + tn; templateData.template = this.findVelocityTemplate( templateData.location, this.getTemplateEncoding( tp ) ); } if ( templateData.template == null ) { templateData.location = TEMPLATE_PREFIX + tp + "/" + tn; templateData.template = this.findVelocityTemplate( templateData.location, this.getTemplateEncoding( tp ) ); } if ( templateData.template == null ) { template = this.getVelocityTemplate( this.getParentTemplateProfile( tp ), tn ); if ( template == null ) { map.put( key, new TemplateData() ); throw new FileNotFoundException( getMessage( "noSuchTemplate", tn ) ); } } else { if ( this.isLoggable( Level.FINER ) ) { this.log( Level.FINER, getMessage( "templateInfo", tn, templateData.location ), null ); } template = templateData.template; map.put( key, templateData ); } } else if ( templateData.template == null ) { throw new FileNotFoundException( getMessage( "noSuchTemplate", tn ) ); } else { if ( this.isLoggable( Level.FINER ) ) { this.log( Level.FINER, getMessage( "templateInfo", tn, templateData.location ), null ); } template = templateData.template; } } return template; } private static String getMessage( final String key, final Object... arguments ) { return MessageFormat.format( ResourceBundle.getBundle( JomcTool.class.getName().replace( '.', '/' ) ).getString( key ), arguments ); } private static String getMessage( final Throwable t ) { return t != null ? t.getMessage() != null && t.getMessage().trim().length() > 0 ? t.getMessage() : getMessage( t.getCause() ) : null; } /** * @since 1.3 */ private static class TemplateData { private String location; private Template template; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy