[DEV] integrate new model model...

This commit is contained in:
Edouard DUPIN 2021-07-05 00:53:33 +02:00
parent c7297bd106
commit cb4d58c32f
10 changed files with 266 additions and 94 deletions

View File

@ -19,6 +19,7 @@ import org.atriasoft.exml.builder.Builder;
import org.atriasoft.exml.builder.BuilderGeneric; import org.atriasoft.exml.builder.BuilderGeneric;
import org.atriasoft.exml.builder.BuilderIntrospection; import org.atriasoft.exml.builder.BuilderIntrospection;
import org.atriasoft.exml.builder.IntrospectionObject; import org.atriasoft.exml.builder.IntrospectionObject;
import org.atriasoft.exml.builder.ModelType;
import org.atriasoft.exml.exception.ExmlBuilderException; import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlParserErrorMulti; import org.atriasoft.exml.exception.ExmlParserErrorMulti;
import org.atriasoft.exml.generator.GeneratorIntrospection; import org.atriasoft.exml.generator.GeneratorIntrospection;
@ -42,7 +43,7 @@ public class Exml {
public static void generate(final Object root, final String rootNodeName, final StringBuilder data) throws ExmlBuilderException { public static void generate(final Object root, final String rootNodeName, final StringBuilder data) throws ExmlBuilderException {
GeneratorIntrospection generator; GeneratorIntrospection generator;
try { try {
generator = new GeneratorIntrospection(root.getClass(), rootNodeName); generator = new GeneratorIntrospection(ModelType.NORMAL, root.getClass(), rootNodeName);
generator.generate(root, data); generator.generate(root, data);
/* /*
final SerializerXmlIntrospection serializer = new SerializerXmlIntrospection(generator); final SerializerXmlIntrospection serializer = new SerializerXmlIntrospection(generator);

View File

@ -9,24 +9,27 @@ import org.atriasoft.exml.internal.Log;
public class BuilderIntrospection implements Builder { public class BuilderIntrospection implements Builder {
// Keep in cach all the object alredy parsed ==> optimize CPU // Keep in cach all the object alredy parsed ==> optimize CPU
final Map<Class<?>, IntrospectionModel> elements = new HashMap<>(); final Map<MapKey, IntrospectionModel> elements = new HashMap<>();
// The root class (need to keep it if we use 2 time the builder, the root class is no more accessible). // The root class (need to keep it if we use 2 time the builder, the root class is no more accessible).
final Class<?> rootClassType; final Class<?> rootClassType;
final String rootNodeName; final String rootNodeName;
public BuilderIntrospection(final Class<?> classType, final String rootNodeName) throws Exception { public BuilderIntrospection(final ModelType model, final Class<?> classType, final String rootNodeName) throws Exception {
this.rootNodeName = rootNodeName; this.rootNodeName = rootNodeName;
this.rootClassType = classType; this.rootClassType = classType;
this.elements.put(classType, IntrospectionModelFactory.createModel(classType)); MapKey key = new MapKey(model, classType);
// TODO pb if it is a List or an Array ...
this.elements.put(key, IntrospectionModelFactory.createModelPlop(key));
} }
IntrospectionModel findOrCreate(final Class<?> classType) throws Exception { IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException {
IntrospectionModel out = this.elements.get(classType); MapKey key = new MapKey(model, name, classType);
IntrospectionModel out = this.elements.get(key);
if (out != null) { if (out != null) {
return out; return out;
} }
out = IntrospectionModelFactory.createModel(classType); out = IntrospectionModelFactory.createModelPlop(key);
this.elements.put(classType, out); this.elements.put(key, out);
return out; return out;
} }
@ -44,49 +47,43 @@ public class BuilderIntrospection implements Builder {
public Object newElement(final Object parent, final String nodeName) throws ExmlBuilderException, Exception { public Object newElement(final Object parent, final String nodeName) throws ExmlBuilderException, Exception {
Log.warning("new element on NodeName=" + nodeName); Log.warning("new element on NodeName=" + nodeName);
final IntrospectionObject introspectionObject = (IntrospectionObject) parent; final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
// special case of user request parsing of element with <XXX><value></value>...</XXX> IntrospectionModel model = introspectionObject.getModelIntrospection();
if (nodeName.equals(introspectionObject.getListNameModel())) { Class<?> typeClass = null;
IntrospectionModel inferData = introspectionObject.getDataInterface(); String listTreeName = null;
if (inferData.getClassType().isArray()) { if (model.isArray() || model.isList()) {
inferData = findOrCreate(inferData.getClassType().getComponentType()); List<String> nodesAvaillable = model.getNodeAvaillable();
} else if (List.class.isAssignableFrom(inferData.getClassType())) { if (nodesAvaillable == null || nodesAvaillable.size() == 0) {
Log.critical("inferData = findOrCreate(inferData.getSubClassType());"); throw new ExmlBuilderException("Model can not have subNode with name: '" + nodeName + "'");
}
return new IntrospectionObject(inferData);
} }
// TODO here try to remove this condition (see): YYYYYYYYYYYYYYYYYYYYYYYYYYYY if (!nodesAvaillable.get(0).equals(nodeName)) {
if (introspectionObject.getDataInterface() == null) { throw new ExmlBuilderException("Model can not have subNode with name: '" + nodeName + "'. Must be " + nodesAvaillable.get(0));
if (nodeName.contentEquals(this.rootNodeName)) {
Log.verbose("Create new class: " + this.rootClassType.getCanonicalName());
final IntrospectionModel inferData = findOrCreate(this.rootClassType);
return new IntrospectionObject(inferData);
} }
// need to add a throw on the node... typeClass = model.getClassType();
return null; // ==> disable the parsing.. (node is not parsed...) } else {
typeClass = introspectionObject.getTypeOfSubNode(nodeName);
listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName);
} }
Class<?> typeClass = introspectionObject.getTypeOfSubNode(nodeName);
String listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName);
if (typeClass != null) { if (typeClass != null) {
// specific case for List ==> need to get the subType in introspection ... // specific case for List ==> need to get the subType in introspection ...
if (typeClass.isArray()) { if (typeClass.isArray()) {
Class<?> subTypeClass = typeClass.getComponentType(); Class<?> subTypeClass = typeClass.getComponentType();
Log.verbose("Create array new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'"); Log.verbose("Create array new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionModel inferData = findOrCreate(subTypeClass); final IntrospectionModel inferData = findOrCreate(ModelType.ARRAY, listTreeName, subTypeClass);
// Create the data when object is ended created... // Create the data when object is ended created...
return new IntrospectionObject(inferData, listTreeName); return new IntrospectionObject(inferData);
} }
if (List.class.isAssignableFrom(typeClass)) { if (List.class.isAssignableFrom(typeClass)) {
Class<?> subTypeClass = introspectionObject.getTypeOfSubNodeSubType(nodeName); Class<?> subTypeClass = introspectionObject.getTypeOfSubNodeSubType(nodeName);
Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'"); Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionModel inferData = findOrCreate(subTypeClass); final IntrospectionModel inferData = findOrCreate(ModelType.LIST, listTreeName, subTypeClass);
// Create the data when object is ended created... // Create the data when object is ended created...
return new IntrospectionObject(inferData, listTreeName); return new IntrospectionObject(inferData);
} }
Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'"); Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionModel inferData = findOrCreate(typeClass); final IntrospectionModel inferData = findOrCreate(ModelType.NORMAL, listTreeName, typeClass);
// Create the data when object is ended created... // Create the data when object is ended created...
return new IntrospectionObject(inferData, listTreeName); return new IntrospectionObject(inferData);
} }
return null; return null;
@ -95,30 +92,30 @@ public class BuilderIntrospection implements Builder {
@Override @Override
public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlBuilderException, Exception { public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlBuilderException, Exception {
final IntrospectionObject introspectionObject = (IntrospectionObject) element; final IntrospectionObject introspectionObject = (IntrospectionObject) element;
if (introspectionObject.getDataInterface() == null) { IntrospectionModel model = introspectionObject.getModelIntrospection();
// property on nothing ??? if (model.isArray() || model.isList()) {
return; throw new ExmlBuilderException("Model (List/Array) can not have property with name '" + propertyName + "'");
} }
// TODO Check here, maybe a big problem with the custum object in properties ... !!!!!
introspectionObject.setProperty(propertyName, propertyValue); introspectionObject.setProperty(propertyName, propertyValue);
} }
@Override @Override
public Object newRoot() throws ExmlBuilderException { public Object newRoot() throws ExmlBuilderException {
// TODO here try to set : YYYYYYYYYYYYYYYYYYYYYYYYYYYY final IntrospectionModel inferData = findOrCreate(ModelType.ARRAY, this.rootNodeName, this.rootClassType);
/* return new IntrospectionObject(inferData);
final IntrospectionData inferData = findOrCreate(this.rootClassType);
return new IntrospectionObject(inferData, rootNodeName);
*/
return new IntrospectionObject();
} }
@Override @Override
public void newText(final Object parent, final String text) throws ExmlBuilderException { public void newText(final Object parent, final String text) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) parent; final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
if (introspectionObject.getDataInterface() == null) { IntrospectionModel model = introspectionObject.getModelIntrospection();
// property on nothing ??? if (model.isArray() || model.isList()) {
return; List<String> nodesAvaillable = model.getNodeAvaillable();
if (nodesAvaillable != null && nodesAvaillable.size() != 0) {
throw new ExmlBuilderException("Model can not have direct text with model data= '" + text + "'");
}
} }
introspectionObject.setText(text); introspectionObject.setText(text);
} }
@ -126,7 +123,7 @@ public class BuilderIntrospection implements Builder {
@Override @Override
public void endElement(final Object element) throws ExmlBuilderException { public void endElement(final Object element) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) element; final IntrospectionObject introspectionObject = (IntrospectionObject) element;
if (introspectionObject.getDataInterface() == null) { if (introspectionObject.getModelIntrospection() == null) {
// property on nothing ??? // property on nothing ???
return; return;
} }
@ -137,12 +134,12 @@ public class BuilderIntrospection implements Builder {
@Override @Override
public void newElementFinished(final Object parent, final String tmpName, final Object element) { public void newElementFinished(final Object parent, final String tmpName, final Object element) {
final IntrospectionObject introspectionElementObject = (IntrospectionObject) element; final IntrospectionObject introspectionElementObject = (IntrospectionObject) element;
if (introspectionElementObject.getDataInterface() == null) { if (introspectionElementObject.getModelIntrospection() == null) {
// property on nothing ??? // property on nothing ???
return; return;
} }
final IntrospectionObject introspectionParentObject = (IntrospectionObject) parent; final IntrospectionObject introspectionParentObject = (IntrospectionObject) parent;
if (introspectionParentObject.getDataInterface() == null) { if (introspectionParentObject.getModelIntrospection() == null) {
if (tmpName.equals(this.rootNodeName)) { if (tmpName.equals(this.rootNodeName)) {
// this is the root node ... // this is the root node ...
Object tmpp = introspectionParentObject.getData(); Object tmpp = introspectionParentObject.getData();

View File

@ -53,14 +53,13 @@ public abstract class IntrospectionModel {
public String getTreeNameOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException { public String getTreeNameOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException {
return null; return null;
} }
public abstract boolean isEndPoint(); public boolean isEndPoint() {
return false;
}
public boolean isArray() {
return false;
}
public boolean isList() { public boolean isList() {
if (this.classType.isArray()) {
return true;
}
if (List.class.isAssignableFrom(this.classType) ) {
return true;
}
return false; return false;
} }
public abstract String toString(final Object data); public abstract String toString(final Object data);

View File

@ -0,0 +1,51 @@
package org.atriasoft.exml.builder;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelArray extends IntrospectionModel {
final String nodeName;
public IntrospectionModelArray(final String nodeName, final Class<?> classType) {
super(classType);
this.nodeName = nodeName;
}
@Override
Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
return null;
}
@Override
protected List<String> getNodeAvaillable() {
return null;
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
return new Object[0];
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
@Override
public boolean isArray() {
return true;
}
@Override
public String toString(final Object data) {
return null;
}
@Override
public String[] toStringList(final Object data) {
return null;
}
}

View File

@ -7,11 +7,33 @@ import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelFactory { public class IntrospectionModelFactory {
private IntrospectionModelFactory() {} private IntrospectionModelFactory() {}
public static IntrospectionModel createModel(final Class<?> classType) throws ExmlBuilderException { public static IntrospectionModel createModelsssss(final MapKey modelType) throws ExmlBuilderException {
if (StringSerializer.contains(classType)) { /*
return new IntrospectionModelBaseType(classType); if (modelType.model() == ModelType.ARRAY) {
return new IntrospectionModelArray(modelType.type());
} }
return new IntrospectionModelComplex(classType); if (modelType.model() == ModelType.LIST) {
return new IntrospectionModelList(modelType.type());
}
*/
if (StringSerializer.contains(modelType.type())) {
return new IntrospectionModelBaseType(modelType.type());
}
return new IntrospectionModelComplex(modelType.type());
} }
public static IntrospectionModel createModelArray(final String nodeName, final MapKey modelType) throws ExmlBuilderException {
return new IntrospectionModelArray(nodeName, modelType.type());
}
public static IntrospectionModel createModelList(final String nodeName, final MapKey modelType) throws ExmlBuilderException {
return new IntrospectionModelList(nodeName, modelType.type());
}
public static IntrospectionModel createModelPlop(final MapKey modelType) throws ExmlBuilderException {
if (StringSerializer.contains(modelType.type())) {
return new IntrospectionModelBaseType(modelType.type());
}
return new IntrospectionModelComplex(modelType.type());
}
} }

View File

@ -0,0 +1,51 @@
package org.atriasoft.exml.builder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelList extends IntrospectionModel {
final String nodeName;
public IntrospectionModelList(final String nodeName, final Class<?> classType) {
super(classType);
this.nodeName = nodeName;
}
@Override
Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
return null;
}
@Override
protected List<String> getNodeAvaillable() {
return null;
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
return new ArrayList<Object>();
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
@Override
public boolean isList() {
return true;
}
@Override
public String toString(final Object data) {
return null;
}
@Override
public String[] toStringList(final Object data) {
return null;
}
}

View File

@ -11,6 +11,7 @@ import org.atriasoft.exml.internal.Log;
public class IntrospectionObject { public class IntrospectionObject {
private final IntrospectionModel modelInterface; private final IntrospectionModel modelInterface;
private Object data = null; private Object data = null;
@Deprecated
private final String listNameModel; private final String listNameModel;
private final Map<String, Object> properties = new HashMap<>(); private final Map<String, Object> properties = new HashMap<>();
private final Map<String, List<Object>> nodes = new HashMap<>(); private final Map<String, List<Object>> nodes = new HashMap<>();
@ -24,6 +25,7 @@ public class IntrospectionObject {
this.listNameModel = null; this.listNameModel = null;
} }
@Deprecated
public IntrospectionObject(final IntrospectionModel dataInterface, final String listNameModel) { public IntrospectionObject(final IntrospectionModel dataInterface, final String listNameModel) {
this.modelInterface = dataInterface; this.modelInterface = dataInterface;
this.listNameModel = listNameModel; this.listNameModel = listNameModel;
@ -34,6 +36,7 @@ public class IntrospectionObject {
this.listNameModel = null; this.listNameModel = null;
} }
@Deprecated
public String getListNameModel() { public String getListNameModel() {
return this.listNameModel; return this.listNameModel;
} }
@ -42,7 +45,7 @@ public class IntrospectionObject {
return this.data; return this.data;
} }
public IntrospectionModel getDataInterface() { public IntrospectionModel getModelIntrospection() {
return this.modelInterface; return this.modelInterface;
} }

View File

@ -0,0 +1,14 @@
package org.atriasoft.exml.builder;
public record MapKey (ModelType model,
String nodeName,
Class<?> type) {
public MapKey(final ModelType model, final String nodeName, final Class<?> type) {
this.model = model;
this.nodeName = nodeName;
this.type = type;
}
public MapKey(final ModelType model, final Class<?> type) {
this(model, null, type);
}
}

View File

@ -0,0 +1,7 @@
package org.atriasoft.exml.builder;
public enum ModelType {
NORMAL,
ARRAY,
LIST
}

View File

@ -7,30 +7,41 @@ import java.util.Map;
import org.atriasoft.exml.builder.IntrospectionModel; import org.atriasoft.exml.builder.IntrospectionModel;
import org.atriasoft.exml.builder.IntrospectionModelFactory; import org.atriasoft.exml.builder.IntrospectionModelFactory;
import org.atriasoft.exml.builder.IntrospectionProperty; import org.atriasoft.exml.builder.IntrospectionProperty;
import org.atriasoft.exml.builder.MapKey;
import org.atriasoft.exml.builder.ModelType;
import org.atriasoft.exml.exception.ExmlBuilderException; import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.internal.Log; import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.parser.Tools; import org.atriasoft.exml.parser.Tools;
public class GeneratorIntrospection implements Generator { public class GeneratorIntrospection implements Generator {
// Keep in cach all the object alredy parsed ==> optimize CPU // Keep in cach all the object alredy parsed ==> optimize CPU
final Map<Class<?>, IntrospectionModel> elements = new HashMap<>(); final Map<MapKey, IntrospectionModel> elements = new HashMap<>();
// The root class (need to keep it if we use 2 time the builder, the root class is no more accessible). // The root class (need to keep it if we use 2 time the builder, the root class is no more accessible).
final Class<?> rootClassType; final Class<?> rootClassType;
final String rootNodeName; final String rootNodeName;
public GeneratorIntrospection(final Class<?> classType, final String rootNodeName) throws Exception { public GeneratorIntrospection(final ModelType model, final Class<?> classType, final String rootNodeName) throws Exception {
this.rootNodeName = rootNodeName; this.rootNodeName = rootNodeName;
this.rootClassType = classType; this.rootClassType = classType;
this.elements.put(classType, IntrospectionModelFactory.createModel(classType)); MapKey key = new MapKey(model, classType);
// TODO pb if it is a List or an Array ...
this.elements.put(key, IntrospectionModelFactory.createModelPlop(key));
} }
IntrospectionModel findOrCreate(final Class<?> classType) throws ExmlBuilderException { IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException {
IntrospectionModel out = this.elements.get(classType); MapKey key = new MapKey(model, name, classType);
IntrospectionModel out = this.elements.get(key);
if (out != null) { if (out != null) {
return out; return out;
} }
out = IntrospectionModelFactory.createModel(classType); if (model == ModelType.ARRAY) {
this.elements.put(classType, out); out = IntrospectionModelFactory.createModelArray(key.nodeName(), key);
} else if (model == ModelType.LIST) {
out = IntrospectionModelFactory.createModelList(key.nodeName(), key);
} else {
out = IntrospectionModelFactory.createModelPlop(key);
}
this.elements.put(key, out);
return out; return out;
} }
@ -60,33 +71,32 @@ public class GeneratorIntrospection implements Generator {
if (!elem.canGetValue()) { if (!elem.canGetValue()) {
continue; continue;
} }
String name = elem.getNames()[0];
Object dataObj = elem.getValue(data); Object dataObj = elem.getValue(data);
if (dataObj == null) { if (dataObj == null) {
continue; continue;
} }
String name = elem.getNames()[0];
Class<?> type = elem.getType(); Class<?> type = elem.getType();
Class<?> subType = elem.getSubType(); IntrospectionModel introspectionSub = null;
if (type.isArray()) {
generateNode(dataObj, name, tmpp, indent); Class<?> typeClass = elem.getSubType();
/* String listTreeName = elem.getListName();
if (List.class.isAssignableFrom(type)) { introspectionSub = findOrCreate(ModelType.ARRAY, listTreeName, typeClass);
// special case for List ... } else if (List.class.isAssignableFrom(type)) {
type = elem.getSubType(); Class<?> typeClass = elem.getSubType();
generateNodeList(dataObj, name, tmpp, indent); String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.LIST, listTreeName, typeClass);
} else { } else {
generateNode(dataObj, name, tmpp, indent); introspectionSub = findOrCreate(ModelType.NORMAL, null, data.getClass());
} }
*/ generateNode(dataObj, introspectionSub, name, tmpp, indent);
} }
} }
public void generateNode(final Object data, final String nodeName, final StringBuilder tmpp, final int indent) throws ExmlBuilderException { public void generateNode(final Object data, final IntrospectionModel model, final String nodeName, final StringBuilder tmpp, final int indent) throws ExmlBuilderException {
IntrospectionModel introspection = findOrCreate(data.getClass()); if (model.isEndPoint()) {
if (introspection.isEndPoint()) { if (model.isList()) {
if (introspection.isList()) { String[] listDatas = model.toStringList(data);
String[] listDatas = introspection.toStringList(data);
for (int iii=0; iii<listDatas.length; iii++) { for (int iii=0; iii<listDatas.length; iii++) {
Tools.addIndent(tmpp, indent); Tools.addIndent(tmpp, indent);
tmpp.append("<"); tmpp.append("<");
@ -102,21 +112,37 @@ public class GeneratorIntrospection implements Generator {
tmpp.append("<"); tmpp.append("<");
tmpp.append(nodeName); tmpp.append(nodeName);
tmpp.append(">"); tmpp.append(">");
tmpp.append(introspection.toString(data)); tmpp.append(model.toString(data));
tmpp.append("</"); tmpp.append("</");
tmpp.append(nodeName); tmpp.append(nodeName);
tmpp.append(">"); tmpp.append(">");
} }
} else if (introspection.isList()) { } else if (model.isArray()) {
List<IntrospectionProperty> baseName = model.getNodes();
if (baseName == null || baseName.size() == 0) {
// mode render : <nodeName><val>aaa</val><val>bbb</val></nodeName>
} else {
// mode render : <nodeName>aaa</nodeName><nodeName>bbb</nodeName>
}
Log.error("lkjlk");
} else if (model.isList()) {
List<IntrospectionProperty> baseName = model.getNodes();
if (baseName == null || baseName.size() == 0) {
// mode render : <nodeName><val>aaa</val><val>bbb</val></nodeName>
} else {
// mode render : <nodeName>aaa</nodeName><nodeName>bbb</nodeName>
}
Log.error("lkjlk"); Log.error("lkjlk");
} else { } else {
Tools.addIndent(tmpp, indent); Tools.addIndent(tmpp, indent);
tmpp.append("<"); tmpp.append("<");
tmpp.append(nodeName); tmpp.append(nodeName);
generateProperties(data, introspection, tmpp); generateProperties(data, model, tmpp);
if (introspection.getNodes().size() != 0) { if (model.getNodes().size() != 0) {
tmpp.append(">"); tmpp.append(">");
generateSubNodes(data, introspection, tmpp, indent + 1); generateSubNodes(data, model, tmpp, indent + 1);
Tools.addIndent(tmpp, indent); Tools.addIndent(tmpp, indent);
tmpp.append("</"); tmpp.append("</");
tmpp.append(nodeName); tmpp.append(nodeName);
@ -128,6 +154,7 @@ public class GeneratorIntrospection implements Generator {
} }
public void generate(final Object root, final StringBuilder tmpp) throws ExmlBuilderException { public void generate(final Object root, final StringBuilder tmpp) throws ExmlBuilderException {
generateNode(root, this.rootNodeName, tmpp, 0); IntrospectionModel introspection = findOrCreate(ModelType.NORMAL, null, root.getClass());
generateNode(root, introspection, this.rootNodeName, tmpp, 0);
} }
} }