package ilarkesto.mda.generator; import ilarkesto.base.Str; import ilarkesto.core.logging.Log; import ilarkesto.io.IO; import java.io.File; import java.util.Collection; import java.util.List; public class JavaPrinter { private static final Log LOG = Log.get(JavaPrinter.class); private String packageName; private String className; private String charset = IO.UTF_8; private StringBuilder sb = new StringBuilder(); private int depth; private boolean lineStart = true; public void commentGenerated() { comment("// ----------> GENERATED FILE - DON'T TOUCH! <----------"); ln(); } public void comment(String text) { ln("// " + text); } public void loggerByClassName() { loggerByClassName(className); } public void loggerByClassName(String className) { field("protected static", Log.class.getName(), "log", Log.class.getName() + ".get(" + className + ".class)"); } public void logDebug(String params) { log("debug", params); } public void logInfo(String params) { log("info", params); } public void log(String level, String params) { statement("log." + level + "(" + params + ")"); } public void logger(String name) { field("protected static", Log.class.getName(), "log", Log.class.getName() + ".get(\"" + name + "\")"); } public void assignment(String var, String value) { statement(var + " = " + value); } public void returnStatement(String statement) { statement("return " + statement); } public void statement(String statement) { ln(statement + ";"); } public void protectedField(String type, String name) { protectedField(type, name, null); } public void protectedField(String type, String name, String value) { field("protected", type, name, value); } public void field(String modifiers, String type, String name, String value) { s(modifiers + " " + type + " " + name); if (value != null) s(" = " + value); ln(";"); ln(); } public void getter(String type, String name) { beginMethod(type, "get" + Str.uppercaseFirstLetter(name), null); returnStatement(name); endMethod(); } public void annotationOverride() { annotation("Override"); } public void annotation(String name) { s("@"); ln(name); } public void toStringMethod(String returnStatement) { annotationOverride(); beginToStringMethod(); returnStatement(returnStatement); endMethod(); } public void beginProcedure(String name, List<String> parameters) { beginMethod("void", name, parameters); } public void beginToStringMethod() { beginMethod("String", "toString", null); } public void beginMethod(String returnType, String name, List<String> parameters) { s("public " + returnType + " " + name + "("); if (parameters != null && !parameters.isEmpty()) s(Str.concat(parameters, ", ")); ln(") {"); in(); } public void abstractMethod(String returnType, String name, List<String> parameters) { if (returnType == null) returnType = "void"; s("public abstract " + returnType + " " + name + "("); if (parameters != null && !parameters.isEmpty()) s(Str.concat(parameters, ", ")); ln(");"); ln(); } public void interfaceMethod(String returnType, String name, List<String> parameters) { if (returnType == null) returnType = "void"; s(returnType + " " + name + "("); if (parameters != null && !parameters.isEmpty()) s(Str.concat(parameters, ", ")); ln(");"); ln(); } public void endProcedure() { endMethod(); } public void endMethod() { out(); ln("}"); ln(); } public void beginInterface(String name, Collection<String> interfaces) { if (className == null) className = name; s("public interface " + name); if (interfaces != null && !interfaces.isEmpty()) { s(" extends "); boolean first = true; for (String iface : interfaces) { if (first) { first = false; } else { s(", "); } s(iface); } } ln(" {"); in(); ln(); } public void beginIf(String condition) { ln("if (" + condition + ") {"); in(); } public void endIf() { out(); ln("}"); } public void beginSynchronized(String lock) { ln("synchronized (" + lock + ") {"); in(); } public void endSynchronized() { out(); ln("}"); } public void beginTry() { ln("try {"); in(); } public void beginCatchThrowable() { beginCatch("Throwable"); } public void beginCatch(String exceptionType) { out(); ln("} catch (" + exceptionType + " ex) {"); in(); } public void endCatch() { out(); ln("}"); } public void beginClass(String name, String superclassName, Collection<String> interfaces) { beginClass(false, name, superclassName, interfaces); } public void beginClass(boolean abstract_, String name, String superclassName, Collection<String> interfaces) { if (className == null) className = name; s("public"); if (abstract_) s(" abstract"); s(" class " + name); if (superclassName != null) s(" extends " + superclassName); if (interfaces != null && !interfaces.isEmpty()) s(" implements " + Str.concat(interfaces, ", ")); ln(" {"); in(); ln(); } public void endInterface() { endClass(); } public void endClass() { out(); ln("}"); ln(); } public void beginConstructor(List<String> parameters) { beginMethod("", className, parameters); } public void endConstructor() { out(); ln("}"); ln(); } public void package_(String name) { if (packageName == null) packageName = name; ln("package " + name + ";"); ln(); } public void imports(Collection<String> imports) { for (String imp : imports) { ln("import " + imp + ";"); } ln(); } public void ln(String s) { s(s); ln(); } public void s(String s) { if (lineStart) { indentation(); lineStart = false; } sb.append(s); } public void in() { if (!lineStart) throw new IllegalStateException("lineStart == false"); depth++; } public void out() { if (depth == 0) throw new IllegalStateException("depth == 0"); depth--; } public void ln() { sb.append("\n"); lineStart = true; } private void indentation() { for (int i = 0; i < depth; i++) { sb.append(" "); } } public void writeToFile(String basePath, boolean overwrite) { if (packageName == null) throw new IllegalStateException("packageName == null"); if (className == null) throw new IllegalStateException("className == null"); String path = basePath + "/" + packageName.replace('.', '/') + "/" + className + ".java"; File file = new File(path); writeToFile(file, overwrite); } public void writeToFile(File file, boolean overwrite) { if (file.exists()) { if (!overwrite) { LOG.debug("File already exists:", file.getPath()); return; } String oldCode = IO.readFile(file, charset); if (oldCode.equals(toString())) { LOG.debug("File is up to date:", file.getPath()); return; } } LOG.info("Writing file:", file.getPath()); IO.writeFile(file, toString(), charset); } @Override public String toString() { return sb.toString(); } }