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

org.jomc.tools.modlet.ToolsModelProcessor 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: ToolsModelProcessor.java 5043 2015-05-27 07:03:39Z schulte $
 *
 */
package org.jomc.tools.modlet;

import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import org.jomc.model.Dependencies;
import org.jomc.model.Implementation;
import org.jomc.model.JavaTypeName;
import org.jomc.model.Messages;
import org.jomc.model.ModelObjectException;
import org.jomc.model.Module;
import org.jomc.model.Modules;
import org.jomc.model.Properties;
import org.jomc.model.Specification;
import org.jomc.model.Specifications;
import org.jomc.model.modlet.ModelHelper;
import org.jomc.modlet.Model;
import org.jomc.modlet.ModelContext;
import org.jomc.modlet.ModelException;
import org.jomc.modlet.ModelProcessor;
import org.jomc.tools.model.SourceFileType;
import org.jomc.tools.model.SourceFilesType;
import org.jomc.tools.model.SourceSectionType;
import org.jomc.tools.model.SourceSectionsType;
import static org.jomc.tools.modlet.ToolsModletConstants.ANNOTATIONS_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_HEAD_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_TAIL_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.DEFAULT_CONSTRUCTOR_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.DEFAULT_CONSTRUCTOR_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.DEPENDENCIES_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.DEPENDENCIES_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.DOCUMENTATION_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_ANNOTATIONS_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_DOCUMENTATION_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_LICENSE_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.LICENSE_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.MESSAGES_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.MESSAGES_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.PROPERTIES_SECTION_NAME;
import static org.jomc.tools.modlet.ToolsModletConstants.PROPERTIES_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_ANNOTATIONS_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_DOCUMENTATION_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_LICENSE_TEMPLATE;
import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_TEMPLATE;

/**
 * Object management and configuration tools {@code ModelProcessor} implementation.
 *
 * @author Christian Schulte
 * @version $JOMC: ToolsModelProcessor.java 5043 2015-05-27 07:03:39Z schulte $
 * @see ModelContext#processModel(org.jomc.modlet.Model)
 * @since 1.2
 */
public class ToolsModelProcessor implements ModelProcessor
{

    /**
     * Constant for the name of the model context attribute backing property {@code enabled}.
     *
     * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
     * @see ModelContext#getAttribute(java.lang.String)
     */
    public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.tools.modlet.ToolsModelProcessor.enabledAttribute";

    /**
     * Constant for the name of the system property controlling property {@code defaultEnabled}.
     *
     * @see #isDefaultEnabled()
     */
    private static final String DEFAULT_ENABLED_PROPERTY_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.defaultEnabled";

    /**
     * Default value of the flag indicating the processor is enabled by default.
     *
     * @see #isDefaultEnabled()
     */
    private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;

    /**
     * Flag indicating the processor is enabled by default.
     */
    private static volatile Boolean defaultEnabled;

    /**
     * Flag indicating the processor is enabled.
     */
    private Boolean enabled;

    /**
     * Constant for the name of the model context attribute backing property
     * {@code modelObjectClasspathResolutionEnabled}.
     *
     * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
     * @see ModelContext#getAttribute(java.lang.String)
     */
    public static final String MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.modelObjectClasspathResolutionEnabledAttribute";

    /**
     * Constant for the name of the system property controlling property
     * {@code defaultModelObjectClasspathResolutionEnabled}.
     *
     * @see #isDefaultModelObjectClasspathResolutionEnabled()
     */
    private static final String DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.defaultModelObjectClasspathResolutionEnabled";

    /**
     * Default value of the flag indicating model object class path resolution is enabled by default.
     *
     * @see #isDefaultModelObjectClasspathResolutionEnabled()
     */
    private static final Boolean DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED = Boolean.TRUE;

    /**
     * Flag indicating model object class path resolution is enabled by default.
     */
    private static volatile Boolean defaultModelObjectClasspathResolutionEnabled;

    /**
     * Flag indicating model object class path resolution is enabled.
     */
    private Boolean modelObjectClasspathResolutionEnabled;

    /**
     * Constant for the name of the model context attribute backing property {@code headComment}.
     *
     * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
     * @see ModelContext#getAttribute(java.lang.String)
     * @since 1.6
     */
    public static final String HEAD_COMMENT_ATTRIBUTE_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.headCommentAttribute";

    /**
     * Constant for the name of the system property controlling property {@code defaultHeadComment}.
     *
     * @see #getDefaultHeadComment()
     * @since 1.6
     */
    private static final String DEFAULT_HEAD_COMMENT_PROPERTY_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.defaultHeadComment";

    /**
     * Default head comment the processor is applying by default.
     *
     * @see #getDefaultHeadComment()
     * @since 1.6
     */
    private static final String DEFAULT_HEAD_COMMENT = "//";

    /**
     * Head comment the processor is applying by default.
     *
     * @since 1.6
     */
    private static volatile String defaultHeadComment;

    /**
     * Head comment the processor is applying.
     *
     * @since 1.6
     */
    private String headComment;

    /**
     * Constant for the name of the model context attribute backing property {@code tailComment}.
     *
     * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
     * @see ModelContext#getAttribute(java.lang.String)
     * @since 1.6
     */
    public static final String TAIL_COMMENT_ATTRIBUTE_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.tailCommentAttribute";

    /**
     * Constant for the name of the system property controlling property {@code defaultTailComment}.
     *
     * @see #getDefaultTailComment()
     * @since 1.6
     */
    private static final String DEFAULT_TAIL_COMMENT_PROPERTY_NAME =
        "org.jomc.tools.modlet.ToolsModelProcessor.defaultTailComment";

    /**
     * Default tail comment the processor is applying by default.
     *
     * @see #getDefaultTailComment()
     * @since 1.6
     */
    private static final String DEFAULT_TAIL_COMMENT = null;

    /**
     * Tail comment the processor is applying by default.
     *
     * @since 1.6
     */
    private static volatile String defaultTailComment;

    /**
     * Tail comment the processor is applying.
     *
     * @since 1.6
     */
    private String tailComment;

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

    /**
     * Gets a flag indicating the processor is enabled by default.
     * 

* The default enabled flag is controlled by system property * {@code org.jomc.tools.modlet.ToolsModelProcessor.defaultEnabled} holding a value indicating the processor is * enabled by default. If that property is not set, the {@code true} default is returned. *

* * @return {@code true}, if the processor is enabled by default; {@code false}, if the processor is disabled by * default. * * @see #setDefaultEnabled(java.lang.Boolean) */ public static boolean isDefaultEnabled() { if ( defaultEnabled == null ) { defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_ENABLED ) ) ); } return defaultEnabled; } /** * Sets the flag indicating the processor is enabled by default. * * @param value The new value of the flag indicating the processor is enabled by default or {@code null}. * * @see #isDefaultEnabled() */ public static void setDefaultEnabled( final Boolean value ) { defaultEnabled = value; } /** * Gets a flag indicating the processor is enabled. * * @return {@code true}, if the processor is enabled; {@code false}, if the processor is disabled. * * @see #isDefaultEnabled() * @see #setEnabled(java.lang.Boolean) */ public final boolean isEnabled() { if ( this.enabled == null ) { this.enabled = isDefaultEnabled(); } return this.enabled; } /** * Sets the flag indicating the processor is enabled. * * @param value The new value of the flag indicating the processor is enabled or {@code null}. * * @see #isEnabled() */ public final void setEnabled( final Boolean value ) { this.enabled = value; } /** * Gets a flag indicating model object class path resolution is enabled by default. *

* The model object class path resolution default enabled flag is controlled by system property * {@code org.jomc.tools.modlet.ToolsModelProcessor.defaultModelObjectClasspathResolutionEnabled} holding a value * indicating model object class path resolution is enabled by default. If that property is not set, the * {@code true} default is returned. *

* * @return {@code true}, if model object class path resolution is enabled by default; {@code false}, if model object * class path resolution is disabled by default. * * @see #setDefaultModelObjectClasspathResolutionEnabled(java.lang.Boolean) */ public static boolean isDefaultModelObjectClasspathResolutionEnabled() { if ( defaultModelObjectClasspathResolutionEnabled == null ) { defaultModelObjectClasspathResolutionEnabled = Boolean.valueOf( System.getProperty( DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME, Boolean.toString( DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED ) ) ); } return defaultModelObjectClasspathResolutionEnabled; } /** * Sets the flag indicating model object class path resolution is enabled by default. * * @param value The new value of the flag indicating model object class path resolution is enabled by default or * {@code null}. * * @see #isDefaultModelObjectClasspathResolutionEnabled() */ public static void setDefaultModelObjectClasspathResolutionEnabled( final Boolean value ) { defaultModelObjectClasspathResolutionEnabled = value; } /** * Gets a flag indicating model object class path resolution is enabled. * * @return {@code true}, if model object class path resolution is enabled; {@code false}, if model object class path * resolution is disabled. * * @see #isDefaultModelObjectClasspathResolutionEnabled() * @see #setModelObjectClasspathResolutionEnabled(java.lang.Boolean) */ public final boolean isModelObjectClasspathResolutionEnabled() { if ( this.modelObjectClasspathResolutionEnabled == null ) { this.modelObjectClasspathResolutionEnabled = isDefaultModelObjectClasspathResolutionEnabled(); } return this.modelObjectClasspathResolutionEnabled; } /** * Sets the flag indicating model object class path resolution is is enabled. * * @param value The new value of the flag indicating model object class path resolution is enabled or {@code null}. * * @see #isModelObjectClasspathResolutionEnabled() */ public final void setModelObjectClasspathResolutionEnabled( final Boolean value ) { this.modelObjectClasspathResolutionEnabled = value; } /** * Gets the head comment the processor is applying by default. *

* The default head comment is controlled by system property * {@code org.jomc.tools.modlet.ToolsModelProcessor.defaultHeadComment} holding the head comment the processor is * applying by default. If that property is not set, the {@code //} default is returned. *

* * @return The head comment the processor is applying by default or {@code null}. * * @see #setDefaultHeadComment(java.lang.String) * @since 1.6 */ public static String getDefaultHeadComment() { if ( defaultHeadComment == null ) { defaultHeadComment = System.getProperty( DEFAULT_HEAD_COMMENT_PROPERTY_NAME, DEFAULT_HEAD_COMMENT ); } return defaultHeadComment; } /** * Sets the head comment the processor is applying by default. * * @param value The new head comment the processor is applying by default or {@code null}. * * @see #getDefaultHeadComment() * @since 1.6 */ public static void setDefaultHeadComment( final String value ) { defaultHeadComment = value; } /** * Gets the head comment the processor is applying. * * @return The head comment the processor is applying or {@code null}. * * @see #getDefaultHeadComment() * @see #setDefaultHeadComment(java.lang.String) * @since 1.6 */ public final String getHeadComment() { if ( this.headComment == null ) { this.headComment = getDefaultHeadComment(); } return this.headComment; } /** * Sets the head comment the processor is applying. * * @param value The new head comment the processor is applying or {@code null}. * * @see #getHeadComment() * @since 1.6 */ public final void setHeadComment( final String value ) { this.headComment = value; } /** * Gets the tail comment the processor is applying by default. *

* The default tail comment is controlled by system property * {@code org.jomc.tools.modlet.ToolsModelProcessor.defaultTailComment} holding the tail comment the processor is * applying by default. If that property is not set, the {@code null} default is returned. *

* * @return The tail comment the processor is applying by default or {@code null}. * * @see #setDefaultTailComment(java.lang.String) * @since 1.6 */ public static String getDefaultTailComment() { if ( defaultTailComment == null ) { defaultTailComment = System.getProperty( DEFAULT_TAIL_COMMENT_PROPERTY_NAME, DEFAULT_TAIL_COMMENT ); } return defaultTailComment; } /** * Sets the tail comment the processor is applying by default. * * @param value The new tail comment the processor is applying by default or {@code null}. * * @see #getDefaultTailComment() * @since 1.6 */ public static void setDefaultTailComment( final String value ) { defaultTailComment = value; } /** * Gets the tail comment the processor is applying. * * @return The tail comment the processor is applying or {@code null}. * * @see #getDefaultTailComment() * @see #setDefaultTailComment(java.lang.String) * @since 1.6 */ public final String getTailComment() { if ( this.tailComment == null ) { this.tailComment = getDefaultTailComment(); } return this.tailComment; } /** * Sets the tail comment the processor is applying. * * @param value The new tail comment the processor is applying or {@code null}. * * @see #getTailComment() * @since 1.6 */ public final void setTailComment( final String value ) { this.tailComment = value; } /** * {@inheritDoc} * * @see #isEnabled() * @see #isModelObjectClasspathResolutionEnabled() * @see #getHeadComment() * @see #getTailComment() * @see #ENABLED_ATTRIBUTE_NAME * @see #MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME * @see #HEAD_COMMENT_ATTRIBUTE_NAME * @see #TAIL_COMMENT_ATTRIBUTE_NAME */ public Model processModel( final ModelContext context, final Model model ) throws ModelException { if ( context == null ) { throw new NullPointerException( "context" ); } if ( model == null ) { throw new NullPointerException( "model" ); } Model processed = model; boolean contextEnabled = this.isEnabled(); if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean ) { contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME ); } boolean contextModelObjectClasspathResolutionEnabled = this.isModelObjectClasspathResolutionEnabled(); if ( contextModelObjectClasspathResolutionEnabled == DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED && context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME ) instanceof Boolean ) { contextModelObjectClasspathResolutionEnabled = (Boolean) context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME ); } if ( contextEnabled ) { processed = model.clone(); final Modules modules = ModelHelper.getModules( processed ); if ( modules != null ) { Module classpathModule = null; if ( contextModelObjectClasspathResolutionEnabled ) { classpathModule = modules.getClasspathModule( Modules.getDefaultClasspathModuleName(), context.getClassLoader() ); if ( classpathModule != null && modules.getModule( Modules.getDefaultClasspathModuleName() ) == null ) { modules.getModule().add( classpathModule ); } else { classpathModule = null; } } if ( modules.getSpecifications() != null ) { for ( int i = 0, s0 = modules.getSpecifications().getSpecification().size(); i < s0; i++ ) { final Specification specification = modules.getSpecifications().getSpecification().get( i ); final SourceFileType sourceFileType = specification.getAnyObject( SourceFileType.class ); final SourceFilesType sourceFilesType = specification.getAnyObject( SourceFilesType.class ); if ( sourceFileType != null ) { if ( sourceFileType.getLocation() == null && specification.getClazz() != null ) { // As of 1.2, the 'location' attribute got updated from 'required' to 'optional'. sourceFileType.setLocation( new StringBuilder( specification.getClazz().length() + 5 ). append( specification.getClazz().replace( '.', '/' ) ).append( ".java" ). toString() ); } if ( sourceFileType.getHeadComment() == null ) { // As of 1.2, the 'head-comment' and 'tail-comment' attributes got introduced. sourceFileType.setHeadComment( "//" ); } } if ( sourceFilesType != null ) { this.applyDefaults( context, modules, specification, sourceFilesType ); } } } if ( modules.getImplementations() != null ) { for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ ) { final Implementation implementation = modules.getImplementations().getImplementation().get( i ); final SourceFileType sourceFileType = implementation.getAnyObject( SourceFileType.class ); final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class ); if ( sourceFileType != null ) { if ( sourceFileType.getLocation() == null && implementation.getClazz() != null ) { // As of 1.2, the 'location' attribute got updated from 'required' to 'optional'. sourceFileType.setLocation( new StringBuilder( implementation.getClazz().length() + 5 ). append( implementation.getClazz().replace( '.', '/' ) ).append( ".java" ). toString() ); } if ( sourceFileType.getHeadComment() == null ) { // As of 1.2, the 'head-comment' and 'tail-comment' attributes got introduced. sourceFileType.setHeadComment( "//" ); } } if ( sourceFilesType != null ) { this.applyDefaults( context, modules, implementation, sourceFilesType ); } } } if ( classpathModule != null ) { modules.getModule().remove( classpathModule ); } } } else if ( context.isLoggable( Level.FINER ) ) { context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(), model.getIdentifier() ), null ); } return processed; } /** * Gets the default source code file location for a given specification. *

* If the specification provides a Java type name, this method returns a Java source code file location based on * that Java type name. *

* * @param context The context to get the default location with. * @param modules The model to get the default location with. * @param specification The specification to get the default location for. * * @return The default location for {@code specification} or {@code null}. * * @throws NullPointerException if {@code context}, {@code modules} or {@code specification} is {@code null}. * * @see SourceFileType#getLocation() * @see Specification#getJavaTypeName() * @since 1.6 */ protected String getDefaultSourceFileLocation( final ModelContext context, final Modules modules, final Specification specification ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( specification == null ) { throw new NullPointerException( "specification" ); } String location = null; try { if ( specification.getJavaTypeName() != null ) { location = specification.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java"; } } catch ( final ModelObjectException e ) { context.log( Level.WARNING, getMessage( e ), null ); } return location; } /** * Gets the default source code file location for a given implementation. *

* If the implementation provides a Java type name, this method returns a Java source code file location based on * that Java type name. *

* * @param context The context to get the default location with. * @param modules The model to get the default location with. * @param implementation The implementation to get the default location for. * * @return The default location for {@code implementation} or {@code null}. * * @throws NullPointerException if {@code context}, {@code modules} or {@code implementation} is {@code null}. * * @see SourceFileType#getLocation() * @see Implementation#getJavaTypeName() * @since 1.6 */ protected String getDefaultSourceFileLocation( final ModelContext context, final Modules modules, final Implementation implementation ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( implementation == null ) { throw new NullPointerException( "implementation" ); } String location = null; try { if ( implementation.getJavaTypeName() != null ) { location = implementation.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java"; } } catch ( final ModelObjectException e ) { context.log( Level.WARNING, getMessage( e ), null ); } return location; } /** * Gets the default source section name for a given specification. *

* If the specification provides a Java type name, this method returns a section name based on that Java type * name. *

* * @param context The context to get the default section name with. * @param modules The model to get the default section name with. * @param specification The specification to get the default section name for. * * @return The default source section name for {@code specification} or {@code null}. * * @throws NullPointerException if {@code context}, {@code modules} or {@code specification} is {@code null}. * * @see SourceSectionType#getName() * @see Specification#getJavaTypeName() * @since 1.6 */ protected String getDefaultSourceSectionName( final ModelContext context, final Modules modules, final Specification specification ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( specification == null ) { throw new NullPointerException( "specification" ); } String sectionName = null; try { final JavaTypeName javaTypeName = specification.getJavaTypeName(); if ( javaTypeName != null ) { sectionName = javaTypeName.getName( false ); } } catch ( final ModelObjectException e ) { context.log( Level.WARNING, getMessage( e ), null ); } return sectionName; } /** * Gets the default source section name for a given implementation. *

* If the implementation provides a Java type name, this method returns a section name based that Java type * name. *

* * @param context The context to get the default section name with. * @param modules The model to get the default section name with. * @param implementation The implementation to get the default section name for. * * @return The default source section name for {@code implementation} or {@code null}. * * @throws NullPointerException if {@code context}, {@code modules} or {@code implementation} is {@code null}. * * @see SourceSectionType#getName() * @see Implementation#getJavaTypeName() * @since 1.6 */ protected String getDefaultSourceSectionName( final ModelContext context, final Modules modules, final Implementation implementation ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( implementation == null ) { throw new NullPointerException( "implementation" ); } String sectionName = null; try { final JavaTypeName javaTypeName = implementation.getJavaTypeName(); if ( javaTypeName != null ) { sectionName = javaTypeName.getName( false ); } } catch ( final ModelObjectException e ) { context.log( Level.WARNING, getMessage( e ), null ); } return sectionName; } /** * Updates any optional attributes to default values. * * @param context The context to apply defaults with. * @param modules The model to to apply defaults with. * @param specification The specification corresponding to {@code sourceFilesType}. * @param sourceFilesType The model to update. * * @throws NullPointerException if {@code context}, {@code modules}, {@code specification} or * {@code sourceFilesType} is {@code null}. */ private void applyDefaults( final ModelContext context, final Modules modules, final Specification specification, final SourceFilesType sourceFilesType ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( specification == null ) { throw new NullPointerException( "specification" ); } if ( sourceFilesType == null ) { throw new NullPointerException( "sourceFilesType" ); } String contextHeadComment = this.getHeadComment(); if ( ( DEFAULT_HEAD_COMMENT != null ? DEFAULT_HEAD_COMMENT.equals( contextHeadComment ) : contextHeadComment == null ) && context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ) instanceof String ) { contextHeadComment = (String) context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ); } if ( contextHeadComment != null && contextHeadComment.length() == 0 ) { contextHeadComment = null; } String contextTailComment = this.getTailComment(); if ( ( DEFAULT_TAIL_COMMENT != null ? DEFAULT_TAIL_COMMENT.equals( contextTailComment ) : contextTailComment == null ) && context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ) instanceof String ) { contextTailComment = (String) context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ); } if ( contextTailComment != null && contextTailComment.length() == 0 ) { contextTailComment = null; } for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ ) { final SourceFileType s = sourceFilesType.getSourceFile().get( i ); if ( s.getTemplate() == null ) { s.setTemplate( SPECIFICATION_TEMPLATE ); } if ( s.getLocation() == null ) { s.setLocation( this.getDefaultSourceFileLocation( context, modules, specification ) ); } if ( s.getHeadComment() == null ) { s.setHeadComment( contextHeadComment ); } if ( s.getTailComment() == null ) { s.setTailComment( contextTailComment ); } this.applyDefaults( context, modules, specification, s.getSourceSections() ); } } /** * Updates any optional attributes to default values. * * @param context The context to apply defaults with. * @param modules The model to to apply defaults with. * @param specification The specification corresponding to {@code sourceSectionsType}. * @param sourceSectionsType The model to update or {@code null}. * * @throws NullPointerException if {@code context}, {@code modules} or {@code specification} is {@code null}. */ private void applyDefaults( final ModelContext context, final Modules modules, final Specification specification, final SourceSectionsType sourceSectionsType ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( specification == null ) { throw new NullPointerException( "specification" ); } try { if ( sourceSectionsType != null ) { for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ ) { final SourceSectionType s = sourceSectionsType.getSourceSection().get( i ); if ( LICENSE_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( true ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( SPECIFICATION_LICENSE_TEMPLATE ); } } if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) ) { if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE ); } } if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( true ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE ); } } final String sectionName = this.getDefaultSourceSectionName( context, modules, specification ); if ( sectionName != null && sectionName.equals( s.getName() ) ) { if ( !isFieldSet( s, "editable" ) ) { s.setEditable( true ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } } this.applyDefaults( context, modules, specification, s.getSourceSections() ); } } } catch ( final NoSuchFieldException e ) { throw new AssertionError( e ); } } /** * Updates any optional attributes to default values. * * @param context The context to apply defaults with. * @param modules The model to to apply defaults with. * @param implementation The implementation corresponding to {@code sourceFilesType}. * @param sourceFilesType The model to update. * * @throws NullPointerException if {@code context}, {@code modules}, {@code implementation} or * {@code sourceFilesType} is {@code null}. */ private void applyDefaults( final ModelContext context, final Modules modules, final Implementation implementation, final SourceFilesType sourceFilesType ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( implementation == null ) { throw new NullPointerException( "implementation" ); } if ( sourceFilesType == null ) { throw new NullPointerException( "sourceFilesType" ); } String contextHeadComment = this.getHeadComment(); if ( ( DEFAULT_HEAD_COMMENT != null ? DEFAULT_HEAD_COMMENT.equals( contextHeadComment ) : contextHeadComment == null ) && context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ) instanceof String ) { contextHeadComment = (String) context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ); } if ( contextHeadComment != null && contextHeadComment.length() == 0 ) { contextHeadComment = null; } String contextTailComment = this.getTailComment(); if ( ( DEFAULT_TAIL_COMMENT != null ? DEFAULT_TAIL_COMMENT.equals( contextTailComment ) : contextTailComment == null ) && context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ) instanceof String ) { contextTailComment = (String) context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ); } if ( contextTailComment != null && contextTailComment.length() == 0 ) { contextTailComment = null; } for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ ) { final SourceFileType s = sourceFilesType.getSourceFile().get( i ); if ( s.getTemplate() == null ) { s.setTemplate( IMPLEMENTATION_TEMPLATE ); } if ( s.getLocation() == null ) { s.setLocation( this.getDefaultSourceFileLocation( context, modules, implementation ) ); } if ( s.getHeadComment() == null ) { s.setHeadComment( contextHeadComment ); } if ( s.getTailComment() == null ) { s.setTailComment( contextTailComment ); } this.applyDefaults( context, modules, implementation, s.getSourceSections() ); } } /** * Updates any optional attributes to default values. * * @param context The context to apply defaults with. * @param modules The model to to apply defaults with. * @param implementation The implementation corresponding to {@code sourceSectionsType}. * @param sourceSectionsType The model to update or {@code null}. * * @throws NullPointerException if {@code context}, {@code modules} or {@code implementation} is {@code null}. */ private void applyDefaults( final ModelContext context, final Modules modules, final Implementation implementation, final SourceSectionsType sourceSectionsType ) { if ( context == null ) { throw new NullPointerException( "context" ); } if ( modules == null ) { throw new NullPointerException( "modules" ); } if ( implementation == null ) { throw new NullPointerException( "implementation" ); } final Specifications specifications = modules.getSpecifications( implementation.getIdentifier() ); final Dependencies dependencies = modules.getDependencies( implementation.getIdentifier() ); final Messages messages = modules.getMessages( implementation.getIdentifier() ); final Properties properties = modules.getProperties( implementation.getIdentifier() ); try { if ( sourceSectionsType != null ) { for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ ) { final SourceSectionType s = sourceSectionsType.getSourceSection().get( i ); if ( LICENSE_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( true ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( IMPLEMENTATION_LICENSE_TEMPLATE ); } } if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) ) { if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE ); } } if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( true ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE ); } } if ( CONSTRUCTORS_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( CONSTRUCTORS_HEAD_TEMPLATE ); } if ( s.getTailTemplate() == null ) { s.setTailTemplate( CONSTRUCTORS_TAIL_TEMPLATE ); } if ( !isFieldSet( s, "optional" ) ) { s.setOptional( specifications == null || ( specifications.getSpecification().isEmpty() && specifications.getReference().isEmpty() ) ); } } if ( DEFAULT_CONSTRUCTOR_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "editable" ) ) { s.setEditable( true ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 2 ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( DEFAULT_CONSTRUCTOR_TEMPLATE ); } } if ( DEPENDENCIES_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( dependencies == null || dependencies.getDependency().isEmpty() ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( DEPENDENCIES_TEMPLATE ); } } if ( PROPERTIES_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( properties == null || properties.getProperty().isEmpty() ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( PROPERTIES_TEMPLATE ); } } if ( MESSAGES_SECTION_NAME.equals( s.getName() ) ) { if ( !isFieldSet( s, "optional" ) ) { s.setOptional( messages == null || messages.getMessage().isEmpty() ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } if ( s.getHeadTemplate() == null ) { s.setHeadTemplate( MESSAGES_TEMPLATE ); } } if ( specifications != null ) { for ( final Specification specification : specifications.getSpecification() ) { final String sectionName = this.getDefaultSourceSectionName( context, modules, specification ); if ( sectionName != null && sectionName.equals( s.getName() ) ) { if ( !isFieldSet( s, "editable" ) ) { s.setEditable( true ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } } } } final String sectionName = this.getDefaultSourceSectionName( context, modules, implementation ); if ( sectionName != null && sectionName.equals( s.getName() ) ) { if ( !isFieldSet( s, "editable" ) ) { s.setEditable( true ); } if ( !isFieldSet( s, "indentationLevel" ) ) { s.setIndentationLevel( 1 ); } } this.applyDefaults( context, modules, implementation, s.getSourceSections() ); } } } catch ( final NoSuchFieldException e ) { throw new AssertionError( e ); } } private static boolean isFieldSet( final Object object, final String fieldName ) throws NoSuchFieldException { final Field field = object.getClass().getDeclaredField( fieldName ); final boolean accessible = field.isAccessible(); try { field.setAccessible( true ); return field.get( object ) != null; } catch ( final IllegalAccessException e ) { throw new AssertionError( e ); } finally { field.setAccessible( accessible ); } } private static String getMessage( final Throwable t ) { return t != null ? t.getMessage() != null && t.getMessage().trim().length() > 0 ? t.getMessage() : getMessage( t.getCause() ) : null; } private static String getMessage( final String key, final Object... args ) { return MessageFormat.format( ResourceBundle.getBundle( ToolsModelProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy