output.java
Class CodeBuilder

java.lang.Object
  extended by output.java.CodeBuilder
All Implemented Interfaces:
Builders.Builder<String>

public final class CodeBuilder
extends Object
implements Builders.Builder<String>

An object for building source code, analogous to StringBuilder for building strings or the various builders in Builders for bulding collections.


Field Summary
 State initialState
          The initial state with which this code builder was constructed.
 
Constructor Summary
CodeBuilder()
          Default constructor.
CodeBuilder(State initialState)
          Construct a code builder to be embedded in another.
 
Method Summary
 CodeBuilder addImport(String target)
          Add an import statement to the top level.
 CodeBuilder addImport(String fmt, Object... args)
          Call addImport(String.format(fmt, args)).
 CodeBuilder addPackageStatement(String pkgName)
          Add a package declaration.
 CodeBuilder addPackageStatement(String fmt, Object... args)
          Call addPackageStatement(String.format(fmt, args)).
 CodeBuilder addStaticImport(String target)
          Add a static import statement to the top level.
 CodeBuilder addStaticImport(String fmt, Object... args)
          Call addStaticImport(String.format(fmt, args)).
 CodeBuilder append(CodeBuilder builder)
          Absorb the contents of another code builder.
 CodeBuilder append(String code)
          Add to the code being built.
 CodeBuilder append(String fmt, Object... args)
          Call append(String.format(fmt, args)).
 CodeBuilder appendComment(String comment)
          Add a one-line-style comment to the code being built.
 CodeBuilder appendComment(String fmt, Object... args)
          Call appendComment(String.format(fmt, args)).
 CodeBuilder beginBlock(String header)
          Begin building some kind of code block within a method.
 CodeBuilder beginBlock(String fmt, Object... args)
          Call beginBlock(String.format(fmt, args)).
 CodeBuilder beginClass(String decl)
          Begin building a class (or interface or enum).
 CodeBuilder beginClass(String fmt, Object... args)
          Call beginClass(String.format(fmt, args)).
 CodeBuilder beginComment()
          Begin building a multi-line comment.
 CodeBuilder beginJavaDoc()
          Begin building a JavaDoc comment.
 CodeBuilder beginMethod(String decl)
          Begin building a method (or constructor).
 CodeBuilder beginMethod(String fmt, Object... args)
          Call beginMethod(String.format(fmt, args)).
 CodeBuilder beginStaticBlock()
          Begin building a static block for a class.
 CodeBuilder chainBlock(String betweenBraces)
          Finish building a code block, but begin another immediately.
 CodeBuilder chainBlock(String fmt, Object... args)
          Call chainBlock(String.format(fmt, args)).
 String finish()
          Return the code generated by the builder.
 CodeBuilder finishBlock()
          Finish building a code block.
 CodeBuilder finishBlock(String afterBrace)
          Finish building a code block requiring further code after the closing brace.
 CodeBuilder finishBlock(String fmt, Object... args)
          Call finishBlock(String.format(fmt, args)).
 CodeBuilder finishClass()
          Finish building a class (or interface or enum).
 CodeBuilder finishComment()
          Finish building a multi-line comment.
 CodeBuilder finishMethod()
          Finish building a method (or constructor).
 CodeBuilder finishStaticBlock()
          Finish building a static block for a class.
 CodeBuilder format(String fmt, Object... args)
          Add to the code being built, using String.format(String, Object[]).
 State getState()
          Get the current state of the code builder.
 String toString()
          Return the code generated by the builder so far.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

initialState

public final State initialState
The initial state with which this code builder was constructed. By default, a code builder builds an entire compilation unit; this corresponds to an initial state of State.TOPLEVEL.

See Also:
State
Constructor Detail

CodeBuilder

public CodeBuilder()
Default constructor. Sets up the code builder to build an entire compilation unit (i.e. .java file).


CodeBuilder

public CodeBuilder(State initialState)
Construct a code builder to be embedded in another. For instance, if you want to add a method to a class without passing the code builder for the class, you can have the other method construct its own with the initial state State.CLASS.

Parameters:
initialState - The initial state for this code builder.
See Also:
State
Method Detail

getState

public State getState()
Get the current state of the code builder. This corresponds to the type of the innermost scope still being built - in other words, this is where the next line passed to append(String) will go.

Returns:
The current state.

addImport

public CodeBuilder addImport(String target)
Add an import statement to the top level. This will work even if this builder is not building the top level (that is, initialState is not State.TOPLEVEL), so long as it is passed directly to the append(CodeBuilder) method of a top-level code builder (or a builder that is so passed, and so forth).

Parameters:
target - The name of the package to import. The same as would be found in the statement "import stuff.package;", but without the "import" or the semicolon. The name can end in an asterisk, just as in the import statement.
Returns:
this, for chaining.

addImport

public CodeBuilder addImport(String fmt,
                             Object... args)
Call addImport(String.format(fmt, args)).

See Also:
addImport(String)

addStaticImport

public CodeBuilder addStaticImport(String target)
Add a static import statement to the top level.

Parameters:
target - The identifier of the class member to import.
Returns:
this, for chaining.
See Also:
addImport(String)

addStaticImport

public CodeBuilder addStaticImport(String fmt,
                                   Object... args)
Call addStaticImport(String.format(fmt, args)).

See Also:
addStaticImport(String)

addPackageStatement

public CodeBuilder addPackageStatement(String pkgName)
Add a package declaration. Can only be used in the State.TOPLEVEL state, and only once.

Parameters:
pkgName - The name of the package to declare.
Returns:
this, for chaining.

addPackageStatement

public CodeBuilder addPackageStatement(String fmt,
                                       Object... args)
Call addPackageStatement(String.format(fmt, args)).

See Also:
addPackageStatement(String)

append

public CodeBuilder append(String code)
Add to the code being built.

Parameters:
code - The code to add. Must include the semicolon if the code is a statement; however, a newline will be added automatically. (If the code spans more than one line, the line breaks will be respected.) The newline will be omitted if code is empty (for a blank line use append("\n")).
Returns:
this, for chaining.

append

public CodeBuilder append(String fmt,
                          Object... args)
Call append(String.format(fmt, args)).

See Also:
append(String)

append

public CodeBuilder append(CodeBuilder builder)
Absorb the contents of another code builder. This code builder must be complete - that is, all enclosed scopes must be finished and the builder at its initial state. Furthermore, this initial state must be the same as this builder's current state.

Parameters:
builder - The builder with the code to append.
Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state does not match the initial state of the other builder or it is not complete.

format

public CodeBuilder format(String fmt,
                          Object... args)
Add to the code being built, using String.format(String, Object[]). builder.format(fmt, arg1, arg2) is shorthand for builder.append(String.format(fmt, arg1, arg2)) and does the same thing.

Parameters:
fmt - The format string.
args - The arguments referred to in the format string.
Returns:
this, for chaining.
See Also:
String.format(String, Object[])

beginClass

public CodeBuilder beginClass(String decl)
Begin building a class (or interface or enum). The state will become State.CLASS.

Parameters:
decl - The declaration for the class. This means anything that would be in the class statement, up to but not including the opening brace.
Returns:
this, for chaining.

beginClass

public CodeBuilder beginClass(String fmt,
                              Object... args)
Call beginClass(String.format(fmt, args)).

See Also:
beginClass(String)

finishClass

public CodeBuilder finishClass()
Finish building a class (or interface or enum).

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.CLASS.

beginMethod

public CodeBuilder beginMethod(String decl)
Begin building a method (or constructor). The state will become State.METHOD.

Parameters:
decl - The declaration for the method. This means anything that would be in the method declaration in the code, up to but not including the opening brace.
Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.CLASS.

beginMethod

public CodeBuilder beginMethod(String fmt,
                               Object... args)
Call beginMethod(String.format(fmt, args)).

See Also:
beginMethod(String)

finishMethod

public CodeBuilder finishMethod()
Finish building a method (or constructor).

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.METHOD.

beginStaticBlock

public CodeBuilder beginStaticBlock()
Begin building a static block for a class. The state will become State.METHOD.

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.CLASS.

finishStaticBlock

public CodeBuilder finishStaticBlock()
Finish building a static block for a class.

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.METHOD.

beginBlock

public CodeBuilder beginBlock(String header)
Begin building some kind of code block within a method. This could be anything involving braces - an if statement, a for loop, a switch block, even a bare { ... } block used for scoping. The one thing it shouldn't be is an inner class declaration - for that, use beginClass(String).

The current state will become State.BLOCK.

Parameters:
header - The part of the statement before the opening brace - for instance if (condition), switch(thing), do, or the empty string for bare braces. May include a label declaration (LABEL:) if you're into that sort of thing.
Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is neither State.METHOD nor State.BLOCK.

beginBlock

public CodeBuilder beginBlock(String fmt,
                              Object... args)
Call beginBlock(String.format(fmt, args)).

See Also:
beginBlock(String)

finishBlock

public CodeBuilder finishBlock()
Finish building a code block.

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.BLOCK.

finishBlock

public CodeBuilder finishBlock(String afterBrace)
Finish building a code block requiring further code after the closing brace. For instance, this could be the while part of a do/while loop.

Parameters:
afterBrace - The code to go after the brace, including any necessary semicolon.
Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.BLOCK.

finishBlock

public CodeBuilder finishBlock(String fmt,
                               Object... args)
Call finishBlock(String.format(fmt, args)).

See Also:
finishBlock(String)

chainBlock

public CodeBuilder chainBlock(String betweenBraces)
Finish building a code block, but begin another immediately. Used for the sort of construction often seen in chained if/else if/else code:

 if (condition) {
     // ...
 } else if (otherCondition) {
     // ...
 } else if (anotherCondition) {
     // ...
 } else {
     // ...
 }

Each of the else-ifs and the else would be generated by a call to this method. (The original if and the final closing brace would be generated by beginBlock("if (condition)") and finishBlock(), respectively.)

Parameters:
betweenBraces - The code to be put between the closing brace of the old block and the opening brace of the new one. (For example, the "else if" or "else" above.)
Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.BLOCK.

chainBlock

public CodeBuilder chainBlock(String fmt,
                              Object... args)
Call chainBlock(String.format(fmt, args)).

See Also:
chainBlock(String)

appendComment

public CodeBuilder appendComment(String comment)
Add a one-line-style comment to the code being built. The given string may actually span multiple lines; each will be prefixed appropriately.

Parameters:
comment - The text of the comment.
Returns:
this, for chaining.

appendComment

public CodeBuilder appendComment(String fmt,
                                 Object... args)
Call appendComment(String.format(fmt, args)).

See Also:
appendComment(String)

beginComment

public CodeBuilder beginComment()
Begin building a multi-line comment. The state will become State.COMMENT.

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is already State.COMMENT.

beginJavaDoc

public CodeBuilder beginJavaDoc()
Begin building a JavaDoc comment. The state will become State.COMMENT.

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is already State.COMMENT.

finishComment

public CodeBuilder finishComment()
Finish building a multi-line comment. This includes JavaDoc comments.

Returns:
this, for chaining.
Throws:
CodeBuilderStateError - If the current state is not State.COMMENT.

toString

public String toString()
Return the code generated by the builder so far. If there remain open scopes, this code will be incomplete (there will be unmatched opening braces).

Overrides:
toString in class Object
Returns:
The generated code.

finish

public String finish()
Return the code generated by the builder. It must be complete; that is, each call to a begin...() method must have been matched by one to the corresponding end...() method.

Specified by:
finish in interface Builders.Builder<String>
Returns:
The generated code.
Throws:
CodeBuilderStateError - If there remain unfinished scopes.