import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; /** * Provides methods to generate source code for a method. Inherits from * {@link CodeBuffer} to implement code body generation. * */ public class MethodBuilder extends CodeBuffer { public MethodBuilder addModifier( Modifier modifier ) { modifiers.add( modifier ) ; return this ; } public MethodBuilder addParameter( String name, String type ) { parameters.put( name, new TypedName( name, type ) ) ; return this ; } public MethodBuilder addThrowable( String name ) { throwables.add( name ) ; return this ; } public CodeBuffer clear() { super.clear() ; methodReturn = null ; modifiers.clear() ; parameters.clear() ; throwables.clear() ; return this ; } public String getSignature() { StringBuffer buffer = new StringBuffer( methodReturn.getName() ) ; buffer.append( '(' ) ; if ( parameters.size() > 0 ) { Iterator p = parameters.values().iterator() ; buffer.append( ( ( TypedName ) p.next() ) . getType() ) ; while ( p.hasNext() ) { TypedName parameter = ( TypedName ) p.next() ; buffer.append( ',' ).append( parameter.getType() ) ; } } buffer.append( ')' ) ; return buffer.toString() ; } public MethodBuilder removeModifier( Modifier modifier ) { modifiers.remove( modifier ) ; return this ; } public MethodBuilder removeParameter( String name ) { parameters.remove( name ) ; return this ; } public MethodBuilder removeThrowable( String name ) { throwables.remove( name ) ; return this ; } /** * Specifies a name for a constructor method. This is equivalent to * <code>setReturn(name,name)</code>. * */ public MethodBuilder setConstructor( String name ) { return setReturn( name, name ) ; } /** * Sets the method name and return type for this method. If the name * is the same as the return type, then the method is a constructor. * */ public MethodBuilder setReturn( String name, String type ) { methodReturn = new TypedName( name, type ) ; return this ; } public String toString() { // Begin method declaration with modifiers and return information: // CodeBuffer buffer = new CodeBuffer() ; for ( Iterator p = modifiers.iterator() ; p.hasNext() ; ) buffer.append( p.next().toString() ) ; buffer.append( methodReturn.toString() ) ; // Build a phrase for the parameter list: // StringBuffer phrase = new StringBuffer() ; phrase.append( '(' ) ; if ( parameters.size() > 0 ) { Iterator p = parameters.values().iterator() ; phrase.append( p.next().toString() ) ; while ( p.hasNext() ) phrase.append( ", " ).append( p.next().toString() ) ; } phrase.append( ')' ) ; // For long lines, each phrase starts on its own line: // if ( buffer.lineLength() + phrase.length() > LINE_LIMIT ) buffer.endLine() ; buffer.append( phrase.toString() ) ; // Build a phrase for "throws" clause, if any "throws" present: // if ( throwables.size() > 0 ) { phrase.setLength( 0 ) ; phrase.append( "throws " ) ; Iterator p = throwables.iterator() ; phrase.append( p.next().toString() ) ; while ( p.hasNext() ) phrase.append( ", " ).append( p.next().toString() ) ; if ( buffer.lineLength() + phrase.length() > LINE_LIMIT ) buffer.endLine() ; buffer.append( phrase.toString() ) ; } buffer.append( "{" ).endLine() ; buffer.indent() ; buffer.appendLines( super.toString() ) ; buffer.endLine() ; buffer.outdent() ; buffer.append( "}" ) ; return buffer.toString() ; } //-------------------------------------------------------------------// // Private state information: //-------------------------------------------------------------------// private TypedName methodReturn ; final private Set modifiers = new TreeSet() ; final private Map parameters = new LinkedHashMap() ; final private Set throwables = new TreeSet() ; final private static class TypedName implements Comparable { TypedName( String name, String type ) { this.name = name.trim() ; this.type = type.trim() ; this.key = this.name + ':' + this.type ; } final public int compareTo( Object that ) { return key.compareTo( ( ( TypedName ) that ) . key ) ; } final public boolean equals( Object that ) { return key.equals( ( ( TypedName ) that ) . key ) ; } final public String getName() { return name ; } final public String getType() { return type ; } final public int hashCode() { return key.hashCode() ; } final public String toString() { return ! name.equals( type ) ? type + ' ' + name : name ; } final private String key ; final private String name ; final private String type ; } }