package org.lemsml.jlems.io.reader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import org.lemsml.jlems.core.logging.E;
import org.lemsml.jlems.core.type.LemsCollection;
import org.lemsml.jlems.io.util.FileUtil;
public class LemsFactoryGenerator {
private String generateJava() {
LemsClasses lclasses = LemsClasses.getInstance();
ArrayList<LemsClass> alc = lclasses.getClasses();
StringBuilder sb = new StringBuilder();
sb.append("package org.lemsml.jlems.core.reader;\n\n");
sb.append("import org.lemsml.jlems.core.type.*;\n");
sb.append("import org.lemsml.jlems.core.type.dynamics.*;\n");
sb.append("import org.lemsml.jlems.core.type.structure.*;\n");
sb.append("import org.lemsml.jlems.core.type.simulation.*;\n\n");
sb.append("import org.lemsml.jlems.core.type.procedure.*;\n\n");
sb.append("import org.lemsml.jlems.core.type.geometry.*;\n\n");
sb.append("import org.lemsml.jlems.core.xml.XMLElement;\n");
sb.append("import org.lemsml.jlems.core.xml.XMLAttribute;\n");
sb.append("import org.lemsml.jlems.core.logging.E;\n");
sb.append("// NB this is generated code. Don't edit it. If there is a problem, fix the superclass,\n");
sb.append("// the generator - org.lemsml.jlems.schema.LemsFactoryGenerator, or the class being instantiated.\n\n");
sb.append("public class LemsFactory extends AbstractLemsFactory {\n\n\n");
sb.append(" public Object instantiateFromXMLElement(XMLElement xel) {\n");
sb.append(" Object ret = null;\n");
sb.append(" String tag = xel.getName();\n\n");
sb.append(" if (tag.equals(\"UNUSED\")) {\n");
for (LemsClass lc : alc) {
Class c = lc.jclass;
sb.append(" } else if (tag.equals(\"" + c.getSimpleName() + "\")) {\n");
sb.append(" ret = build" + c.getSimpleName() + "(xel);\n");
}
sb.append(" } else {\n");
sb.append(" E.error(\"Unrecognized name \" + tag);\n");
sb.append(" }\n");
sb.append(" return ret;\n");
sb.append(" }\n\n\n");
for (LemsClass lc : alc) {
sb.append(generateClassBuilderMethod(lc.jclass));
}
sb.append("}\n");
return sb.toString();
}
private String generateClassBuilderMethod(Class<?> c) {
StringBuilder sb = new StringBuilder();
String cnm = c.getSimpleName();
sb.append(" private " + cnm + " build" + cnm + "(XMLElement xel) {\n");
sb.append(" " + cnm + " ret = new " + cnm + "();\n\n");
if (cnm.equals("Component")) {
sb.append(" // Extra code for a Component...\n"
+ " if (xel.getBody()!=null) {\n" +
" ret.abouts.add(new About((xel.getBody())));\n" +
" }\n"+
" //System.out.println(\"Adding component: \"+ret.getID()+\" (\"+ret.getAbout()+\")\");\n\n");
}
sb.append(" for (XMLAttribute xa : xel.getAttributes()) {\n");
sb.append(" String xn = internalFieldName(xa.getName());\n");
sb.append(" String xv = xa.getValue();\n\n");
sb.append(" if (xn.equals(\"UNUSED\")) {\n");
for (Field f : c.getFields()) {
if (java.lang.reflect.Modifier.isPublic(f.getModifiers())) {
if (java.lang.reflect.Modifier.isStatic(f.getModifiers())) {
// not set from xml
} else {
String exfn = null;
if (f.getType() == String.class) {
exfn = "parseString";
} else if (f.getType() == double.class) {
exfn = "parseDouble";
} else if (f.getType() == int.class) {
exfn = "parseInt";
} else if (f.getType() == boolean.class) {
exfn = "parseBoolean";
}
if (exfn != null) {
sb.append(" } else if (xn.equals(\"" + f.getName() + "\")) {\n");
sb.append(" ret." + f.getName() + " = " + exfn + "(xv);\n");
}
}
}
}
sb.append(" } else {\n");
sb.append(" E.warning(\"Unrecognized attribute \" + xa + \" \" + xv);\n");
sb.append(" }\n");
sb.append(" }\n\n\n");
if (hasListFields(c)) {
appendListItemInstantiation(sb, c);
}
sb.append(" return ret;\n");
sb.append(" }\n\n");
return sb.toString();
}
protected String getListClassName(String s) {
String ret = s;
// TODO no special cases
if (s.equals("dynamicses")) {
ret = "Dynamics";
} else if (s.equals("attachmentses")) {
ret = "Attachments";
} else {
if (ret.endsWith("s")) {
ret = ret.substring(0, ret.length() - 1);
}
ret = ret.substring(0, 1).toUpperCase() + ret.substring(1, ret.length());
}
return ret;
}
private boolean hasListFields(Class<?> c) {
boolean ret = false;
for (Field f : c.getFields()) {
if (java.lang.reflect.Modifier.isPublic(f.getModifiers())) {
if (f.getType() == LemsCollection.class) {
ret = true;
break;
}
}
}
return ret;
}
private void appendListItemInstantiation(StringBuilder sb, Class<?> c) {
sb.append(" for (XMLElement cel : xel.getXMLElements()) {\n");
sb.append(" String xn = cel.getTag();\n\n");
sb.append(" Object obj = instantiateFromXMLElement(cel);\n");
sb.append(" if (obj != null && obj instanceof DeprecatedElement) {\n");
sb.append(" obj = ((DeprecatedElement)obj).getReplacement();\n");
sb.append(" }\n");
sb.append(" if (xn.equals(\"UNUSED\")) {\n");
for (Field f : c.getFields()) {
if (java.lang.reflect.Modifier.isPublic(f.getModifiers())) {
if (f.getType() == LemsCollection.class) {
String ccnm = getListClassName(f.getName());
sb.append(" } else if (obj instanceof " + ccnm + ") {\n");
sb.append(" ret." + f.getName() + ".add((" + ccnm + ")obj);\n");
}
}
}
sb.append(" } else {\n");
sb.append(" E.warning(\"Unrecognized element (\"+xn+\"): \" + cel);\n");
sb.append(" }\n");
sb.append(" }\n\n\n");
}
public static void main(String[] argv) throws IOException {
LemsFactoryGenerator lfg = new LemsFactoryGenerator();
String txt = lfg.generateJava();
File f = new File("src/main/java/org/lemsml/jlems/core/reader/LemsFactory.java");
// E.info("About to write " + f.getAbsolutePath() + " local "+ (new File("")).getAbsolutePath());
boolean success = FileUtil.writeStringToFile(txt, f);
if (success) {
E.info("Written " + f.getAbsolutePath());
}
}
}