alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.beans;

import java.lang.reflect.Modifier;
import java.beans.Introspector;
import java.util.ResourceBundle;
import java.text.MessageFormat;

import org.openide.util.NbBundle;
import org.openide.src.*;

/** Singleton with static methods for generating bodies of and
 * additional elements for bean patterns.
 * @author Petr Hrebejk
 */
class BeanPatternGenerator extends Object {
    private static final String THIS_QUALIFIER = "this."; // NOI18N
    /** Constant for one Tab */
    private static final String TAB = "  "; // NOI18N
    /** Constant for two Tabs */
    private static final String TABx2 = TAB + TAB;
    /** Constant for three Tabs */
    private static final String TABx3 = TABx2 + TAB;

    /**
     * Helper method; creates a suitable string for referencing an instance field.
     * @param base the base name to create the string from
     * @param adjustName 
     */
    static String createFieldName(String base, boolean adjustName, boolean paramClash) {
        if (!adjustName) {
            if (!paramClash)
                return base;
            else
                return new StringBuffer(THIS_QUALIFIER).append(base).toString();
        } else {
            String propertyStyle = PropertyActionSettings.getDefault().getPropStyle();
            return  new StringBuffer(propertyStyle).append(base).toString();
        }
    }

    /** Generates the body of the setter method of Property.
     * @param name Name of the property
     * @param type Type of the property
     * @param bound Is the property bound?
     * @param constrained Is the property constrained?
     * @param withSet Should be the set command of property private field generated.
     * @param withSupport Generate the firing of (Veto|Property)Change Events?
     * @param supportName Name of field containing PropertyChangeListeners.
     * @param vetoSupportName Name of field containing VetoableChangeListeners.
     * @return Sring containing the body of the setter method.
     */
    static String propertySetterBody(String name, Type type,
                                     boolean bound, boolean constrained,
                                     boolean withSet, boolean withSupport,
                                     String supportName, String vetoSupportName) {
         return propertySetterBody(name, type, bound, constrained, withSet, withSupport, supportName,
            vetoSupportName, true);
    }
    
    static String propertySetterBody(String name, Type type,
                                     boolean bound, boolean constrained,
                                     boolean withSet, boolean withSupport,
                                     String supportName, String vetoSupportName, boolean adjustName) {
        StringBuffer setterBody = new StringBuffer( 200 );
        String decoratedName = createFieldName(name, adjustName, true);
        
        setterBody.append( "\n" ); // NOI18N
        if ( withSupport ) {
            /* Generates body in the form:
               PropType oldPropName = this.propName;
               this.propName = propName;
               changes.firePropertyChange(propName, oldPropName, propName );
            */

            setterBody.append( TAB + type.toString() );
            setterBody.append( " old" ).append( Pattern.capitalizeFirstLetter( name ) ); // NOI18N
            setterBody.append( " = " ).append( decoratedName ).append( ";\n"); // NOI18N

            if ( constrained ) {
                setterBody.append( TAB + vetoSupportName ).append( ".fireVetoableChange(\"").append( name ).append( "\", " ); // NOI18N

                if ( type.isPrimitive() ) {
                    setterBody.append( "new ").append( getWrapperClassName( type )).append( " (" ); // NOI18N
                    setterBody.append( "old" ).append( Pattern.capitalizeFirstLetter( name ) ); // NOI18N
                    setterBody.append( "), " ); // NOI18N
                    setterBody.append( "new ").append( getWrapperClassName( type )).append( " (" ); // NOI18N
                    setterBody.append( name ).append( "));\n" ); // NOI18N
                }
                else {
                    setterBody.append( "old" ).append( Pattern.capitalizeFirstLetter( name ) ); // NOI18N
                    setterBody.append( ", " ).append( name ).append( ");\n" ); // NOI18N
                }
                if ( !bound ) {
                    setterBody.append( TAB ).append( decoratedName ); // NOI18N
                    setterBody.append( " = " ).append( name ).append( ";\n"); // NOI18N
                }
            }
            if ( bound ) {
                setterBody.append( TAB ).append( decoratedName ); // NOI18N
                setterBody.append( " = " ).append( name ).append( ";\n"); // NOI18N
                setterBody.append( TAB + supportName ).append( ".firePropertyChange (\"").append( name ).append( "\", " ); // NOI18N

                if ( type.isPrimitive() ) {
                    setterBody.append( "new ").append( getWrapperClassName( type )).append( " (" ); // NOI18N
                    setterBody.append( "old" ).append( Pattern.capitalizeFirstLetter( name ) ); // NOI18N
                    setterBody.append( "), " ); // NOI18N
                    setterBody.append( "new ").append( getWrapperClassName( type )).append( " (" ); // NOI18N
                    setterBody.append( name ).append( "));\n" ); // NOI18N
                }
                else {
                    setterBody.append( "old" ).append( Pattern.capitalizeFirstLetter( name ) ); // NOI18N
                    setterBody.append( ", " ).append( name ).append( ");\n" ); // NOI18N
                }
            }
        }
        else if ( withSet ) {
            /* Generates body in the form:
               this.propName = propName;
             */
            setterBody.append( TAB ).append( decoratedName ); // NOI18N
            setterBody.append( " = " ).append( name ).append( ";\n" ); // NOI18N
        }
        return setterBody.toString();
    }

    /** Generates the body of the setter method of IndexedProperty.
     * @param name Name of the property
     * @param indexedType Indexed type of the property
     * @param bound Is the property bound?
     * @param constrained Is the property constrained?
     * @param withSet Should be the set command of property private field generated.
     * @param withSupport Generate the firing of (Veto|Property)Change Events?
     * @param supportName Name of field containing PropertyChangeListeners.
     * @param vetoSupportName Name of field containing VetoableChangeListeners.
     * @return Sring containing the body of the setter method.
     */
    static String idxPropertySetterBody( String name, Type indexedType,
                                         boolean bound, boolean constrained,
                                         boolean withSet, boolean withSupport,
                                         String supportName,
                                         String vetoSupportName ) {
        return idxPropertySetterBody(name, indexedType, bound, constrained,
            withSet, withSupport, supportName, vetoSupportName, true);
    }
    
    static String idxPropertySetterBody( String name, Type indexedType,
                                         boolean bound, boolean constrained,
                                         boolean withSet, boolean withSupport,
                                         String supportName,
                                         String vetoSupportName, boolean adjustName ) {
        StringBuffer setterBody = new StringBuffer( 200 );
        String decoratedName = createFieldName(name, adjustName, true);
        setterBody.append( "\n" ); // NOI18N

        if ( withSupport && constrained ) {

            setterBody.append( TAB + indexedType.toString() );
            setterBody.append( " old" ).append( Pattern.capitalizeFirstLetter( name ) ); // NOI18N
            setterBody.append( " = " ).append( decoratedName ); // NOI18N
            setterBody.append( "[index];\n"); // NOI18N
        }

        if ( withSet || withSupport ) {
            /* Generates body in the form:
               this.propName = propName;
            */
            setterBody.append( TAB ).append( decoratedName ); // NOI18N
            setterBody.append( "[index] = " ).append( name ).append( ";\n" ); // NOI18N
        }

        if ( withSupport && constrained ) {
            setterBody.append( TAB + "try {\n" ); // NOI18N
            setterBody.append( TABx2 + vetoSupportName ).append( ".fireVetoableChange (\"").append( name ).append( "\", " ); // NOI18N
            setterBody.append( "null, null );\n" ); // NOI18N
            setterBody.append( TAB + "}\n" ); // NOI18N
            setterBody.append( TAB + "catch(java.beans.PropertyVetoException vetoException ) {\n" ); //NOI18N
            setterBody.append( TABx2 ).append( decoratedName ); // NOI18N
            setterBody.append( "[index] = old").append( Pattern.capitalizeFirstLetter( name ) ).append( ";\n" ) ; // NOI18N
            setterBody.append( TABx2 + "throw vetoException;\n" ); //NOI18N
            setterBody.append( TAB  + "}\n" ); //NOI18N
        }

        if ( withSupport && bound ) {
            setterBody.append( TAB + supportName ).append( ".firePropertyChange (\"").append( name ).append( "\", " ); // NOI18N
            setterBody.append( "null, null );\n" ); // NOI18N
        }

        return setterBody.toString();
    }
    
    static String propertyGetterBody( String name, boolean withReturn ) {
        return propertyGetterBody(name, withReturn, true);
    }

    /** Generates the body of the getter method of Property.
     * @param name Name of the property.
     * @param withReturn Should be the return command with property private field generated?
     * @return Sring containing the body of the getter method.
     */
    static String propertyGetterBody( String name, boolean withReturn, boolean adjustName ) {
        StringBuffer getterBody = new StringBuffer( 50 );
        String decorated = createFieldName(name, adjustName, false);
        getterBody.append( "\n"); // NOI18N
        if ( withReturn ) {
            /* Generates body in the form:
               return propName;
             */
            getterBody.append( TAB + "return " ); // NOI18N
            getterBody.append( decorated ).append( ";\n" ); // NOI18N
        }
        return getterBody.toString();
    }
    
    /** Generates the body of the getter method of IndexedProperty.
     * @param name Name of the property.
     * @param withReturn Should be the return command with property private field generated?
     * @return Sring containing the body of the getter method.
     */
    static String idxPropertyGetterBody( String name, boolean withReturn ) {
        return idxPropertyGetterBody(name, withReturn, true);
    }

    static String idxPropertyGetterBody( String name, boolean withReturn, boolean adjustName ) {
        StringBuffer getterBody = new StringBuffer( 50 );
        String decorated = createFieldName(name, adjustName, false);
        getterBody.append( "\n"); // NOI18N
        if ( withReturn ) {
            /* Generates body in the form:
               return propName;
             */
            getterBody.append( TAB + "return " ); // NOI18N
            getterBody.append( decorated ).append( "[index];\n" ); // NOI18N
        }
        return getterBody.toString();
    }


    /** Gets the PropertyChangeSupport field in Class. Tryes to find
     * a field of type PropertyChangeSupport. If such field doesn't
     * exist creates a new one with name propertyChangeSupport.
     * @param ce Class to operate on.
     * @throws SourceException If the modification of the source is impossible.
     * @return Name of foun or newly created PropertyChangeSupport field.
     */
    static String supportField(ClassElement ce) throws SourceException {
        String supportName = null;
        Identifier supportId = Identifier.create( "java.beans.PropertyChangeSupport" ); // NOI18N
        FieldElement[] fields = ce.getFields();

        for( int i = 0; i < fields.length; i++ ) {      // Try to find suitable field
            if ( fields[i].getType().isClass() &&
                    fields[i].getType().getClassName().compareTo( supportId, false ) ) {
                supportName = fields[i].getName().getName();
                break;
            }
        }

        if ( supportName == null ) { // Field not found we create new
            supportName = "propertyChangeSupport"; // NOI18N
            FieldElement supportField = new FieldElement();
            supportField.setName( Identifier.create( supportName ) );
            supportField.setType( Type.createClass( supportId ) );
            supportField.setModifiers( Modifier.PRIVATE );
            supportField.setInitValue( " new java.beans.PropertyChangeSupport (this)" ); // NOI18N
            supportField.getJavaDoc().setRawText( PatternNode.getString( "COMMENT_PropertyChangeSupport" ) );
            ce.addField( supportField );
        }

        return supportName;
    }

    /** Gets the VetoableChangeSupport field in Class. Tryes to find
     * a field of type VetoableChangeSupport. If such field doesn't
     * exist creates a new one with name vetoableChangeSupport.
     * @param ce Class to operate on.
     * @throws SourceException If the modification of the source is impossible.
     * @return Name of foun or newly created vetoableChangeSupport field.
     */  
    static String vetoSupportField( ClassElement ce ) throws SourceException {
        String vetoSupportName = null;
        Identifier vetoSupportId = Identifier.create( "java.beans.VetoableChangeSupport" ); // NOI18N
        FieldElement[] fields = ce.getFields();

        for( int i = 0; i < fields.length; i++ ) {      // Try to find suitable field
            if ( fields[i].getType().isClass() &&
                    fields[i].getType().getClassName().compareTo( vetoSupportId, false ) ) {
                vetoSupportName = fields[i].getName().getName();
                break;
            }
        }

        if ( vetoSupportName == null ) { // Field not found we create new
            vetoSupportName = "vetoableChangeSupport"; // NOI18N
            FieldElement supportField = new FieldElement();
            supportField.setName( Identifier.create( vetoSupportName ) );
            supportField.setType( Type.createClass( vetoSupportId ) );
            supportField.setModifiers( Modifier.PRIVATE );
            supportField.setInitValue( " new java.beans.VetoableChangeSupport (this)" ); // NOI18N
            supportField.getJavaDoc().setRawText( PatternNode.getString( "COMMENT_VetoableChangeSupport" ) );
            ce.addField( supportField );
        }

        return vetoSupportName;
    }

    /** If in the class don't exists methods for adding/removing PropertyChangeListeners
     * for given field adds them.
     * @param classElement Class to operate on.
     * @param supportName The PropertyChangeSupport field the methods will be generated for.
     * @throws SourceException If the modification of the source is impossible.
     */
    static void supportListenerMethods( ClassElement classElement, String supportName )
    throws SourceException {

        Identifier addMethodId = Identifier.create( "addPropertyChangeListener" ); // NOI18N
        MethodElement addMethod = null;
        Identifier removeMethodId = Identifier.create( "removePropertyChangeListener" ); // NOI18N
        MethodElement removeMethod = null;
        Identifier listenerTypeId = Identifier.create( "java.beans.PropertyChangeListener" ); // NOI18N
        Type listenerType = Type.createClass( listenerTypeId );

        addMethod = classElement.getMethod( addMethodId, new Type[] { listenerType }  );
        if ( addMethod == null ) {
            addMethod = new MethodElement();
            addMethod.setName( addMethodId );
            addMethod.setReturn( Type.VOID );
            addMethod.setModifiers( Modifier.PUBLIC );
            addMethod.setParameters( ( new MethodParameter[] { new MethodParameter( "l", listenerType, false ) } )); // NOI18N

            StringBuffer body = new StringBuffer( 80 );
            body.append( "\n" ).append( TAB + supportName ); // NOI18N
            body.append( ".addPropertyChangeListener (l);\n" ); // NOI18N
            addMethod.setBody( body.toString() );

            /*
            String comment = MessageFormat.format( PatternNode.getString( "COMMENT_AddPropertyChangeListener" ), 
                                                   new Object[] { listenerType.getClassName().getName() } );
            */                                          
            addMethod.getJavaDoc().setRawText( PatternNode.getString( "COMMENT_AddPropertyChangeListener" ) );


            classElement.addMethod( addMethod );
        }

        removeMethod = classElement.getMethod( removeMethodId, new Type[] { listenerType }  );
        if ( removeMethod == null ) {
            removeMethod = new MethodElement();
            removeMethod.setName( removeMethodId );
            removeMethod.setReturn( Type.VOID );
            removeMethod.setModifiers( Modifier.PUBLIC );
            removeMethod.setParameters( ( new MethodParameter[] { new MethodParameter( "l", listenerType, false ) } )); // NOI18N

            StringBuffer body = new StringBuffer( 80 );
            body.append( "\n" ).append( TAB + supportName ); // NOI18N
            body.append( ".removePropertyChangeListener (l);\n" ); // NOI18N
            removeMethod.setBody( body.toString() );
            removeMethod.getJavaDoc().setRawText( PatternNode.getString( "COMMENT_RemovePropertyChangeListener" ) );
            classElement.addMethod( removeMethod );
        }
    }


    /** If in the class don't exists methods for adding/removing VetoableChangeListeners
     * for given field adds them.
     * @param classElement Class to operate on.
     * @param supportName The vetoableChangeSupport field the methods will be generated for.
     * @throws SourceException If the modification of the source is impossible.
     */
    static void vetoSupportListenerMethods( ClassElement classElement, String supportName )
    throws SourceException {

        Identifier addMethodId = Identifier.create( "addVetoableChangeListener" ); // NOI18N
        MethodElement addMethod = null;
        Identifier removeMethodId = Identifier.create( "removeVetoableChangeListener" ); // NOI18N
        MethodElement removeMethod = null;
        Identifier listenerTypeId = Identifier.create( "java.beans.VetoableChangeListener" ); // NOI18N
        Type listenerType = Type.createClass( listenerTypeId );

        addMethod = classElement.getMethod( addMethodId, new Type[] { listenerType }  );
        if ( addMethod == null ) {
            addMethod = new MethodElement();
            addMethod.setName( addMethodId );
            addMethod.setReturn( Type.VOID );
            addMethod.setModifiers( Modifier.PUBLIC );
            addMethod.setParameters( ( new MethodParameter[] { new MethodParameter( "l", listenerType, false ) } )); // NOI18N

            StringBuffer body = new StringBuffer( 80 );
            body.append( "\n" ).append( TAB + supportName ); // NOI18N
            body.append( ".addVetoableChangeListener (l);\n" ); // NOI18N
            addMethod.setBody( body.toString() );
            addMethod.getJavaDoc().setRawText( PatternNode.getString( "COMMENT_AddVetoableChangeListener" ) );
            classElement.addMethod( addMethod );
        }

        removeMethod = classElement.getMethod( removeMethodId, new Type[] { listenerType }  );
        if ( removeMethod == null ) {
            removeMethod = new MethodElement();
            removeMethod.setName( removeMethodId );
            removeMethod.setReturn( Type.VOID );
            removeMethod.setModifiers( Modifier.PUBLIC );
            removeMethod.setParameters( ( new MethodParameter[] { new MethodParameter( "l", listenerType, false ) } )); // NOI18N

            StringBuffer body = new StringBuffer( 80 );
            body.append( "\n" ).append( TAB + supportName ); // NOI18N
            body.append( ".removeVetoableChangeListener (l);\n" ); // NOI18N
            removeMethod.setBody( body.toString() );
            removeMethod.getJavaDoc().setRawText( PatternNode.getString( "COMMENT_RemoveVetoableChangeListener" ) );
            classElement.addMethod( removeMethod );
        }
    }

    /** Ensures that the listeners array list exists. Used for generating
     * multicast event source support implemented by java.util.ArrayList.
     * Searches the source for suitable field. If the field does not exists
     * creates new one.
     * @param ce Class to operate on.
     * @param type Type of the Event Listener.
     * @throws SourceException If the modification of the source is impossible.
     * @return Name of found or newly created field.
     */
    static String listenersArrayListField( ClassElement ce, Type type ) throws SourceException {

        String fieldName = null;
        String fieldNameToFind = Introspector.decapitalize( type.getClassName().getName() ) + "List"; // NOI18N

        Identifier fieldTypeId = Identifier.create( "java.util.ArrayList" ); // NOI18N
        FieldElement[] fields = ce.getFields();

        for( int i = 0; i < fields.length; i++ ) {      // Try to find suitable field
            if ( fields[i].getType().isClass() &&
                    fields[i].getType().getClassName().compareTo( fieldTypeId, false ) &&
                    fields[i].getName().getName().equals( fieldNameToFind ) ) {
                fieldName = fields[i].getName().getName();
                break;
            }
        }

        if ( fieldName == null ) { // Field not found we create new
            fieldName = fieldNameToFind;
            FieldElement field = new FieldElement();
            field.setName( Identifier.create( fieldName ) );
            field.setType( Type.createClass( fieldTypeId ) );
            field.setModifiers( Modifier.PRIVATE | Modifier.TRANSIENT );
            String comment = MessageFormat.format( PatternNode.getString( "COMMENT_ListenerArrayList" ),
                                                   new Object[] { type.getClassName().getName() } );
            field.getJavaDoc().setRawText( comment );

            ce.addField( field );
        }

        return fieldName;
    }

    /** Ensure the listenersList  exists. Used for generating
     * multicast event source support implemented by javax.swing.event.EventListenerList.
     * Searches the source for suitable field. If the field does not exists
     * creates new one.
     * @param ce Class to operate on.
     * @param type Type of the Event Listener.
     * @throws SourceException If the modification of the source is impossible.
     * @return Name of found or newly created field.
     */
    static String eventListenerListField( ClassElement ce, Type type ) throws SourceException {

        String fieldName = null;

        Identifier fieldTypeId = Identifier.create( "javax.swing.event.EventListenerList" ); // NOI18N
        FieldElement[] fields = ce.getFields();

        for( int i = 0; i < fields.length; i++ ) {      // Try to find suitable field
            if ( fields[i].getType().isClass() &&
                    fields[i].getType().getClassName().compareTo( fieldTypeId, false ) ) {
                fieldName = fields[i].getName().getName();
                break;
            }
        }

        if ( fieldName == null ) { // Field not found we create new
            fieldName = "listenerList"; // NOI18N
            FieldElement field = new FieldElement();
            field.setName( Identifier.create( fieldName ) );
            field.setType( Type.createClass( fieldTypeId ) );
            field.setModifiers( Modifier.PRIVATE );
            field.setInitValue( " null" ); // NOI18N
            String comment = MessageFormat.format( PatternNode.getString( "COMMENT_EventListenerList" ),
                                                   new Object[] { type.getClassName().getName() } );
            field.getJavaDoc().setRawText( comment );

            ce.addField( field );
        }

        return fieldName;
    }

    /** Ensure that listener field for unicast exists. Used for generating
     * unicast event source support.
     * Searches the source for suitable field. If the field does not exists
     * creates new one.
     * @param ce Class to operate on.
     * @param type Type of the Event Listener.
     * @throws SourceException If the modification of the source is impossible.
     */
    static void unicastListenerField( ClassElement ce, Type type ) throws SourceException {

        String fieldName = null;
        String fieldNameToFind = Introspector.decapitalize( type.getClassName().getName() );
        if ( fieldNameToFind.equals( type.getClassName().getName() ) ) {
            fieldNameToFind = new String( "listener" + fieldNameToFind  ); // NOI18N
        }

        FieldElement[] fields = ce.getFields();

        for( int i = 0; i < fields.length; i++ ) {      // Try to find suitable field
            if ( fields[i].getType().isClass() &&
                    fields[i].getType().getClassName().compareTo( type.getClassName(), false ) &&
                    fields[i].getName().getName().equals( fieldNameToFind ) ) {
                fieldName = fields[i].getName().getName();
                break;
            }
        }

        if ( fieldName == null ) { // Field not found we create new
            fieldName = fieldNameToFind;
            FieldElement field = new FieldElement();
            field.setName( Identifier.create( fieldName ) );
            field.setType( type );
            field.setModifiers( Modifier.PRIVATE  | Modifier.TRANSIENT );
            field.setInitValue( " null" ); // NOI18N
            String comment = MessageFormat.format( PatternNode.getString( "COMMENT_UnicastEventListener" ),
                                                   new Object[] { type.getClassName().getName() } );
            field.getJavaDoc().setRawText( comment );
            ce.addField( field );
        }
    }

    static String mcAddBody( Type type, int implementation, String listenerList ) {

        String fieldName = Introspector.decapitalize( type.getClassName().getName() ) + "List"; // NOI18N

        StringBuffer body = new StringBuffer( 50 );

        if ( listenerList == null )
            listenerList = "listenerList"; // NOI18N

        body.append( "\n"); // NOI18N

        if ( implementation == 1 ) {
            body.append( TAB + "if (" ).append( fieldName ).append( " == null ) {\n" ); // NOI18N
            body.append( TABx2 ).append( fieldName ).append( " = new java.util.ArrayList ();\n" ); // NOI18N
            body.append( TAB ).append( "}\n" ); // NOI18N
            body.append( TAB + fieldName ).append( ".add (listener);\n" ); // NOI18N
        }
        else if ( implementation == 2 ) {
            body.append( TAB + "if (" ).append( listenerList ).append( " == null ) {\n" ); // NOI18N
            body.append( TABx2 ).append( listenerList ).append( " = new javax.swing.event.EventListenerList();\n" ); // NOI18N
            body.append( TAB ).append( "}\n" ); // NOI18N
            body.append( TAB + listenerList ).append( ".add (" ); // NOI18N
            body.append( type.toString()).append( ".class, listener);\n" ); // NOI18N
        }

        return body.toString();
    }

    static String mcRemoveBody( Type type, int implementation, String listenerList ) {

        String fieldName = Introspector.decapitalize( type.getClassName().getName() ) + "List"; // NOI18N

        if ( listenerList == null )
            listenerList = "listenerList"; // NOI18N

        StringBuffer body = new StringBuffer( 50 );
        body.append( "\n"); // NOI18N

        if ( implementation == 1 ) {
            body.append( TAB + "if (" ).append( fieldName ).append( " != null ) {\n" ); // NOI18N
            body.append( TABx2 + fieldName ).append( ".remove (listener);\n" ); // NOI18N
            body.append( TAB ).append( "}\n" ); // NOI18N
        }
        else if ( implementation == 2 ) {
            body.append( TAB + listenerList ).append( ".remove (" ); // NOI18N
            body.append( type.toString()).append( ".class, listener);\n" ); // NOI18N
        }

        return body.toString();
    }

    static String ucAddBody( Type type, int implementation ) {

        String fieldName = Introspector.decapitalize( type.getClassName().getName() );
        if ( fieldName.equals( type.getClassName().getName() ) ) {
            fieldName = new String( "listener" + fieldName  ); // NOI18N
        }

        StringBuffer body = new StringBuffer( 50 );

        body.append( "\n"); // NOI18N

        if ( implementation == 1 ) {
            body.append( TAB + "if (").append( fieldName ).append( " != null) {\n" ); // NOI18N
            body.append( TABx2 + "throw new java.util.TooManyListenersException ();\n" ); // NOI18N
            body.append( TAB + "}\n" ); // NOI18N
            body.append( TAB + fieldName ).append( " = listener;\n" ); // NOI18N
        }

        return body.toString();
    }

    static String ucRemoveBody( Type type, int implementation ) {

        String fieldName = Introspector.decapitalize( type.getClassName().getName() );
        if ( fieldName.equals( type.getClassName().getName() ) ) {
            fieldName = new String( "listener" + fieldName  ); // NOI18N
        }

        StringBuffer body = new StringBuffer( 50 );
        body.append( "\n"); // NOI18N

        if ( implementation == 1 ) {
            body.append( TAB + fieldName ).append( " = null;\n" ); // NOI18N
        }

        return body.toString();
    }


    static void fireMethod( ClassElement classElement, Type type,
                            MethodElement method, int implementation,
                            String listenerList,
                            boolean passEvent )
    throws SourceException {

        if ( listenerList == null )
            listenerList = "listenerList"; // NOI18N

        Identifier methodId = Identifier.create(
                                  "fire" + // NOI18N
                                  Pattern.capitalizeFirstLetter( type.getClassName().getName() ) +
                                  Pattern.capitalizeFirstLetter( method.getName().getName() ) );

        MethodElement newMethod = null;

        Type eventType = null;
        MethodParameter params[] = method.getParameters();
        if ( params.length > 0 )
            eventType = params[0].getType();
        else
            eventType = Type.createClass( Identifier.create( "java.util.EventObject" ) ); // NOI18N

        ClassElement eventClass = ClassElement.forName( eventType.toString(), PatternAnalyser.fileObjectForElement( classElement ) );


        //addMethod = classElement.getMethod( addMethodId, new Type[] { listenerType }  );

        //if ( addMethod == null ) {
        newMethod = new MethodElement();
        newMethod.setName( methodId );
        newMethod.setReturn( Type.VOID );
        newMethod.setModifiers( Modifier.PRIVATE );

        MethodParameter[] newMethodParams = generateFireParameters( eventType, eventClass, passEvent );
        newMethod.setParameters( newMethodParams );

        StringBuffer body = new StringBuffer( 80 );
        body.append( "\n" ); // NOI18N

        if ( implementation == 1 ) {
            String fieldName = Introspector.decapitalize( type.getClassName().getName() ) + "List"; // NOI18N

            body.append( TAB + "java.util.ArrayList list;\n" ); // NOI18N

            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( TAB + eventType.toString() ).append( " e = new "); // NOI18N
                body.append( eventType.toString() ).append( " (" ); // NOI18N
                body.append( fireParameterstoString( newMethodParams ) );
                body.append(");\n"); // NOI18N
            }
            body.append( TAB + "synchronized (this) {\n" ); // NOI18N
            body.append( TABx2 + "if (" + fieldName + " == null) return;\n" ); // NOI18N
            body.append( TABx2 + "list = (java.util.ArrayList)" ); // NOI18N
            body.append( fieldName ).append( ".clone ();\n" + TAB +"}\n" ); // NOI18N
            body.append( TAB + "for (int i = 0; i < list.size (); i++) {\n" ); // NOI18N
            body.append( TABx2 + "((" ).append( type.toString() ); // NOI18N
            body.append( ")list.get (i)).").append( method.getName() ); // NOI18N
            body.append(" ("); // NOI18N
            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( "e" ); // NOI18N
            }
            else {
                body.append( fireParameterstoString( newMethodParams ) ); // the event parameter
            }
            body.append( ");\n" + TAB + "}\n" ); // NOI18N
        }
        else if ( implementation == 2 ) {
            String fooEvent = "theEvent"; // NOI18N
            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( TAB + eventType.toString() ).append( " e = null;\n "); // NOI18N
            }
            body.append( TAB + "if (" + listenerList + " == null) return;\n"); // NOI18N
            body.append( TAB + "Object[] listeners = ").append(listenerList).append(".getListenerList ();\n" ); // NOI18N
            body.append( TAB + "for (int i = listeners.length-2; i>=0; i-=2) {\n"); // NOI18N
            body.append( TABx2 + "if (listeners[i]==" ).append( type.toString()).append( ".class) {\n" ); // NOI18N
            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( TABx3 + "if (e == null)\n" ); // NOI18N
                body.append( TABx2 + TABx2 + "e = new ").append( eventType.toString() ).append( " (" ); // NOI18N
                body.append( fireParameterstoString( newMethodParams ) );
                body.append( ");\n" ); // NOI18N
            }
            body.append( TABx3 + "((").append(type.toString()).append(")listeners[i+1]).").append(method.getName()); // NOI18N
            body.append(" ("); // NOI18N
            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( "e" ); // the created event // NOI18N
            }
            else {
                body.append( fireParameterstoString( newMethodParams ) ); // the event parameter
            }
            body.append( ");\n" + TABx2 + "}\n" + TAB + "}\n"); // NOI18N
        }

        newMethod.setBody( body.toString() );

        StringBuffer comment = new StringBuffer ( PatternNode.getString( "COMMENT_FireMethodMC" ) );
        if ( !usesConstructorParameters( eventClass, passEvent ) ) {
            comment.append( "\n@param event The event to be fired\n" ); // NOI18N
        }
        else {
            comment.append( fireParametersComment( newMethodParams, eventType.getClassName().getName() ) );
        }
        newMethod.getJavaDoc().setRawText( comment.toString() );

        classElement.addMethod( newMethod );
        //}
    }

    static void unicastFireMethod( ClassElement classElement, Type type,
                                   MethodElement method, int implementation,
                                   boolean passEvent )
    throws SourceException {

        Identifier methodId = Identifier.create(
                                  "fire" + // NOI18N
                                  Pattern.capitalizeFirstLetter( type.getClassName().getName() ) +
                                  Pattern.capitalizeFirstLetter( method.getName().getName() ) );

        MethodElement newMethod = null;

        Type eventType = null;
        MethodParameter params[] = method.getParameters();
        if ( params.length > 0 )
            eventType = params[0].getType();
        else
            eventType = Type.createClass( Identifier.create( "java.util.EventObject" ) ); // NOI18N

        ClassElement eventClass = ClassElement.forName( eventType.toString(), PatternAnalyser.fileObjectForElement( classElement ) );

        //addMethod = classElement.getMethod( addMethodId, new Type[] { listenerType }  );

        //if ( addMethod == null ) {
        newMethod = new MethodElement();
        newMethod.setName( methodId );
        newMethod.setReturn( Type.VOID );
        newMethod.setModifiers( Modifier.PRIVATE );

        MethodParameter[] newMethodParams = generateFireParameters( eventType, eventClass, passEvent );
        newMethod.setParameters( newMethodParams );

        StringBuffer body = new StringBuffer( 80 );
        body.append( "\n" ); // NOI18N

        if ( implementation == 1 ) {
            String fieldName = Introspector.decapitalize( type.getClassName().getName() );
            if ( fieldName.equals( type.getClassName().getName() ) ) {
                fieldName = new String( "listener" + fieldName  ); // NOI18N
            }
            
            body.append(TAB + "if (" + fieldName + " == null) return;\n"); // NOI18N

            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( TAB + eventType.toString() ).append( " e = new "); // NOI18N
                body.append( eventType.toString() ).append( " (" ); // NOI18N
                body.append( fireParameterstoString( newMethodParams ) );
                body.append(");\n"); // NOI18N
            }

            body.append( TAB + fieldName ).append( "." ).append( method.getName() ); // NOI18N
            body.append(" ("); // NOI18N
            if ( usesConstructorParameters( eventClass, passEvent ) ) {
                body.append( "e" ); // NOI18N
            }
            else {
                body.append( fireParameterstoString( newMethodParams ) ); // the event parameter
            }
            body.append( ");\n" ); // NOI18N
        }

        newMethod.setBody( body.toString() );

        StringBuffer comment = new StringBuffer ( PatternNode.getString( "COMMENT_FireMethodUC" ) );
        if ( !usesConstructorParameters( eventClass, passEvent ) ) {
            comment.append( "\n@param event The event to be fired\n" ); // NOI18N
        }
        else {
            comment.append( fireParametersComment( newMethodParams, eventType.getClassName().getName() ) ); // the event parameter
        }
        newMethod.getJavaDoc().setRawText( comment.toString() );

        classElement.addMethod( newMethod );
        //}
    }



    static boolean usesConstructorParameters( ClassElement eventClass, boolean passEvent ) {

        if ( passEvent || eventClass == null || eventClass.getConstructors().length > 1 )
            return false;
        else
            return true;
    }


    static MethodParameter[] generateFireParameters( Type eventType, ClassElement eventClass, boolean passEvent ) {


        if ( !usesConstructorParameters( eventClass, passEvent ) ) {
            return new MethodParameter[]
                   { new MethodParameter( "event", getFQNType(eventType), false ) }; // NOI18N
        }
        else {
            ConstructorElement constructor = eventClass.getConstructors()[0];
            MethodParameter[] params = constructor.getParameters();
            MethodParameter[] result = new MethodParameter[ params.length ];
            for ( int i = 0; i < params.length; i++ ) {
                result[i] = new MethodParameter( "param" + (i + 1), getFQNType(params[i].getType()), false  ); // NOI18N
            }
            return result;
        }

    }

    static String fireParameterstoString( MethodParameter[]  params ) {

        StringBuffer buffer = new StringBuffer( 60 );

        for( int i = 0; i < params.length; i++ ) {
            buffer.append( params[i].getName() );
            if ( i < params.length -1 )
                buffer.append( ", " ); // NOI18N
        }
        return buffer.toString();
    }

    static String fireParametersComment( MethodParameter[]  params, String evntType ) {

        StringBuffer buffer = new StringBuffer( 60 );

        for( int i = 0; i < params.length; i++ ) {
            buffer.append( "\n@param ").append( params[i].getName() ); // NOI18N
            buffer.append( " Parameter #" ).append( i + 1 ).append( " of the " ); // NOI18N
            buffer.append( evntType ).append( " constructor." ); // NOI18N
        }
        buffer.append( "\n" ); // NOI18N

        return buffer.toString();
    }

    // UTILITY METHODS ----------------------------------------------------------

    /** For primitive {@link org.openide.src.Type type} finds class for wrapping it into object.
     * E.g. Type.BOOLEAN -> Boolean
     * @param type Primitive type.
     * @return Class which wraps the primitive type.
     */
    public static String getWrapperClassName(Type type) {
        if ( type.isClass() )
            return type.getClassName().getName();
        else if ( type == Type.BOOLEAN )
            return "Boolean"; // NOI18N
        else if ( type == Type.BYTE )
            return "Byte"; // NOI18N
        else if ( type == Type.DOUBLE )
            return "Double"; // NOI18N
        else if ( type == Type.FLOAT )
            return "Float"; // NOI18N
        else if ( type == Type.CHAR )
            return "Character"; // NOI18N
        else if ( type == Type.INT )
            return "Integer"; // NOI18N
        else if ( type == Type.LONG )
            return "Long"; // NOI18N
        else if ( type == Type.SHORT )
            return "Short"; // NOI18N
        else
            return "Object"; // NOI18N
    }

    private static Type getFQNType(Type t) {
        if (t.isArray())
            return Type.createArray(getFQNType(t.getElementType()));
        if (t.isClass()) {
            Identifier id=t.getClassName();
            String fqnName=id.getFullName();
            
            if (fqnName==id.getSourceName())
                return t;
            return Type.createClass(Identifier.create(fqnName));
        }
        return t;
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.