OPENJPA-2119: Added support for generating a constructor and greater support for tabbing. Also fixed a number of bugs.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1242154 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2012-02-08 22:38:07 +00:00
parent 91eb9d4792
commit 824753b36c
2 changed files with 121 additions and 12 deletions

View File

@ -127,7 +127,7 @@ public class SourceCode {
* @param name fully-qualified name of a class * @param name fully-qualified name of a class
* @return an existing class name instance or a new one. * @return an existing class name instance or a new one.
*/ */
ClassName getOrCreateImport(String name) { public ClassName getOrCreateImport(String name) {
for (Import i : imports) { for (Import i : imports) {
if (i.name.getFullName().equals(name)) if (i.name.getFullName().equals(name))
return i.name; return i.name;
@ -368,6 +368,7 @@ public class SourceCode {
private List<ClassName> interfaces = new ArrayList<ClassName>(); private List<ClassName> interfaces = new ArrayList<ClassName>();
private Set<Field> fields = new TreeSet<Field>(); private Set<Field> fields = new TreeSet<Field>();
private Set<Method> methods = new TreeSet<Method>(); private Set<Method> methods = new TreeSet<Method>();
private Set<Constructor> constructors = new TreeSet<Constructor>();
public Class(String name) { public Class(String name) {
super(name, getOrCreateImport(name)); super(name, getOrCreateImport(name));
@ -439,6 +440,13 @@ public class SourceCode {
return method; return method;
} }
public Constructor addConstructor(){
Constructor c = new Constructor(type.simpleName);
if (!constructors.add(c))
throw new IllegalArgumentException(_loc.get(
"src-duplicate-constructor", c, this).toString());
return c;
}
public void write(PrintWriter out, int tab) { public void write(PrintWriter out, int tab) {
super.write(out, tab); super.write(out, tab);
if (isAbstract) if (isAbstract)
@ -452,6 +460,9 @@ public class SourceCode {
out.println(SPACE + BLOCK_DELIMITER.start); out.println(SPACE + BLOCK_DELIMITER.start);
for (Field field:fields) for (Field field:fields)
field.write(out, 1); field.write(out, 1);
for(Constructor ctor : constructors){
ctor.write(out, 1);
}
for (Method method:methods) for (Method method:methods)
method.write(out, 1); method.write(out, 1);
out.println(BLOCK_DELIMITER.end); out.println(BLOCK_DELIMITER.end);
@ -536,10 +547,12 @@ public class SourceCode {
* *
* *
*/ */
class Method extends Element<Method> { public class Method extends Element<Method> {
private boolean isAbstract; private boolean isAbstract;
private List<Argument<ClassName,String>> args = new ArrayList<Argument<ClassName,String>>(); private List<Argument<ClassName,String>> args = new ArrayList<Argument<ClassName,String>>();
private List<String> codeLines = new ArrayList<String>(); private List<String> codeLines = new ArrayList<String>();
int tabCount = 0;
String tab = "";
Method(String n, String t) { Method(String n, String t) {
this(n, getOrCreateImport(t)); this(n, getOrCreateImport(t));
@ -555,16 +568,42 @@ public class SourceCode {
return this; return this;
} }
public Method addCodeLine(String line) { public Method addArgument(String className, String argName){
if (isAbstract) ClassName cn = getOrCreateImport(className);
throw new IllegalStateException("abstract method " + name args.add(new Argument<ClassName, String>(cn, argName," "));
+ " can not have body"); return this;
if (!line.endsWith(SEMICOLON))
line = line + SEMICOLON;
codeLines.add(line);
return this;
} }
public void setTab(boolean inc) {
if (inc)
tabCount++;
else
tabCount--;
tab = "";
for (int i = 0; i < tabCount * TABSIZE; i++) {
tab += SPACE;
}
}
public Method addCodeLine(String line) {
if (isAbstract)
throw new IllegalStateException("abstract method " + name + " can not have body");
// This doesn't handle try{ ... catch(){ if{
if (line.endsWith("{") || line.endsWith("}")) {
}
if (!line.endsWith(SEMICOLON)
&& !(line.isEmpty() || line.endsWith("{") || line.endsWith("}") || line.startsWith("if")))
line = line + SEMICOLON;
codeLines.add(tab + line);
return this;
}
// if tabInc = true, the current line, and all following lines will be tabbed. If false, a tab will be removed.
public Method addCodeLine(String line, boolean tabInc) {
setTab(tabInc);
return addCodeLine(line);
}
public Method makeAbstract() { public Method makeAbstract() {
if (codeLines.isEmpty()) if (codeLines.isEmpty())
isAbstract = true; isAbstract = true;
@ -607,6 +646,75 @@ public class SourceCode {
} }
} }
public class Constructor extends Element<Constructor> {
private List<Argument<ClassName,String>> args = new ArrayList<Argument<ClassName,String>>();
private List<String> codeLines = new ArrayList<String>();
int tabCount = 0;
String tab = "";
public Constructor(String name) {
super(name, null);
makePublic();
}
public Constructor addArgument(Argument<ClassName,String> arg) {
args.add(arg);
return this;
}
public Constructor addArgument(String className, String argName) {
ClassName cn = getOrCreateImport(className);
args.add(new Argument<ClassName, String>(cn, argName, " "));
return this;
}
public Constructor addCodeLine(String line) {
// This doesn't handle try{ ... catch(){ if{
if (line.endsWith("{") || line.endsWith("}")) {
}
if (!line.endsWith(SEMICOLON)
&& !(line.isEmpty() || line.endsWith("{") || line.endsWith("}") || line.startsWith("if")))
line = line + SEMICOLON;
codeLines.add(tab + line);
return this;
}
/**
* if tabInc = true, the current line, and all following lines will be tabbed. If false, a tab will be removed.
*/
public Constructor addCodeLine(String line, boolean tabInc) {
setTab(tabInc);
return addCodeLine(line);
}
public void setTab(boolean inc) {
if (inc)
tabCount++;
else
tabCount--;
tab = "";
for (int i = 0; i < tabCount * TABSIZE; i++) {
tab += SPACE;
}
}
@Override
public void write(PrintWriter out, int tab) {
out.println(BLANK);
super.write(out, tab);
out.print(name);
writeList(out, BLANK, args, ARGS_DELIMITER, true);
out.println(SPACE + BLOCK_DELIMITER.start);
for (String line : codeLines) {
tab(out, tab+1);
out.println(line);
}
tab(out, tab);
out.println(BLOCK_DELIMITER.end);
}
}
/** /**
* Represents <code>import</code> statement. * Represents <code>import</code> statement.
* *
@ -875,7 +983,7 @@ public class SourceCode {
final char end; final char end;
public Delimiter() { public Delimiter() {
this((char)0, (char)0); this((char)' ', (char)' ');
} }
public Delimiter(String pair) { public Delimiter(String pair) {

View File

@ -16,6 +16,7 @@
# under the License. # under the License.
src-duplicate-field: "{0}" is found to be a duplicated field in Class {1}. src-duplicate-field: "{0}" is found to be a duplicated field in Class {1}.
src-duplicate-method: "{0}" is found to be a duplicated method in Class {1}. src-duplicate-method: "{0}" is found to be a duplicated method in Class {1}.
src-duplicate-constructor: "{0}" is found to be a duplicated constructor in Class {1}.
src-invalid-method: "{0}" is not a valid method name. \ src-invalid-method: "{0}" is not a valid method name. \
It must be a non-reserved Java token and a valid Java identifier. It must be a non-reserved Java token and a valid Java identifier.
src-invalid-type: "{0}" is not a valid type name. It must be a valid Java package name, a non-reserved \ src-invalid-type: "{0}" is not a valid type name. It must be a valid Java package name, a non-reserved \