|
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;
}
}
|