[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.BuilderIntrospection;
import org.atriasoft.exml.builder.IntrospectionObject;
import org.atriasoft.exml.builder.ModelType;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
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 {
GeneratorIntrospection generator;
try {
generator = new GeneratorIntrospection(root.getClass(), rootNodeName);
generator = new GeneratorIntrospection(ModelType.NORMAL, root.getClass(), rootNodeName);
generator.generate(root, data);
/*
final SerializerXmlIntrospection serializer = new SerializerXmlIntrospection(generator);

View File

@ -9,24 +9,27 @@ import org.atriasoft.exml.internal.Log;
public class BuilderIntrospection implements Builder {
// 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).
final Class<?> rootClassType;
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.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 out = this.elements.get(classType);
IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException {
MapKey key = new MapKey(model, name, classType);
IntrospectionModel out = this.elements.get(key);
if (out != null) {
return out;
}
out = IntrospectionModelFactory.createModel(classType);
this.elements.put(classType, out);
out = IntrospectionModelFactory.createModelPlop(key);
this.elements.put(key, out);
return out;
}
@ -44,49 +47,43 @@ public class BuilderIntrospection implements Builder {
public Object newElement(final Object parent, final String nodeName) throws ExmlBuilderException, Exception {
Log.warning("new element on NodeName=" + nodeName);
final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
// special case of user request parsing of element with <XXX><value></value>...</XXX>
if (nodeName.equals(introspectionObject.getListNameModel())) {
IntrospectionModel inferData = introspectionObject.getDataInterface();
if (inferData.getClassType().isArray()) {
inferData = findOrCreate(inferData.getClassType().getComponentType());
} else if (List.class.isAssignableFrom(inferData.getClassType())) {
Log.critical("inferData = findOrCreate(inferData.getSubClassType());");
IntrospectionModel model = introspectionObject.getModelIntrospection();
Class<?> typeClass = null;
String listTreeName = null;
if (model.isArray() || model.isList()) {
List<String> nodesAvaillable = model.getNodeAvaillable();
if (nodesAvaillable == null || nodesAvaillable.size() == 0) {
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 (introspectionObject.getDataInterface() == null) {
if (nodeName.contentEquals(this.rootNodeName)) {
Log.verbose("Create new class: " + this.rootClassType.getCanonicalName());
final IntrospectionModel inferData = findOrCreate(this.rootClassType);
return new IntrospectionObject(inferData);
if (!nodesAvaillable.get(0).equals(nodeName)) {
throw new ExmlBuilderException("Model can not have subNode with name: '" + nodeName + "'. Must be " + nodesAvaillable.get(0));
}
// need to add a throw on the node...
return null; // ==> disable the parsing.. (node is not parsed...)
typeClass = model.getClassType();
} else {
typeClass = introspectionObject.getTypeOfSubNode(nodeName);
listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName);
}
Class<?> typeClass = introspectionObject.getTypeOfSubNode(nodeName);
String listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName);
if (typeClass != null) {
// specific case for List ==> need to get the subType in introspection ...
if (typeClass.isArray()) {
Class<?> subTypeClass = typeClass.getComponentType();
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...
return new IntrospectionObject(inferData, listTreeName);
return new IntrospectionObject(inferData);
}
if (List.class.isAssignableFrom(typeClass)) {
Class<?> subTypeClass = introspectionObject.getTypeOfSubNodeSubType(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...
return new IntrospectionObject(inferData, listTreeName);
return new IntrospectionObject(inferData);
}
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...
return new IntrospectionObject(inferData, listTreeName);
return new IntrospectionObject(inferData);
}
return null;
@ -95,30 +92,30 @@ public class BuilderIntrospection implements Builder {
@Override
public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlBuilderException, Exception {
final IntrospectionObject introspectionObject = (IntrospectionObject) element;
if (introspectionObject.getDataInterface() == null) {
// property on nothing ???
return;
IntrospectionModel model = introspectionObject.getModelIntrospection();
if (model.isArray() || model.isList()) {
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);
}
@Override
public Object newRoot() throws ExmlBuilderException {
// TODO here try to set : YYYYYYYYYYYYYYYYYYYYYYYYYYYY
/*
final IntrospectionData inferData = findOrCreate(this.rootClassType);
return new IntrospectionObject(inferData, rootNodeName);
*/
return new IntrospectionObject();
final IntrospectionModel inferData = findOrCreate(ModelType.ARRAY, this.rootNodeName, this.rootClassType);
return new IntrospectionObject(inferData);
}
@Override
public void newText(final Object parent, final String text) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
if (introspectionObject.getDataInterface() == null) {
// property on nothing ???
return;
IntrospectionModel model = introspectionObject.getModelIntrospection();
if (model.isArray() || model.isList()) {
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);
}
@ -126,7 +123,7 @@ public class BuilderIntrospection implements Builder {
@Override
public void endElement(final Object element) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) element;
if (introspectionObject.getDataInterface() == null) {
if (introspectionObject.getModelIntrospection() == null) {
// property on nothing ???
return;
}
@ -137,12 +134,12 @@ public class BuilderIntrospection implements Builder {
@Override
public void newElementFinished(final Object parent, final String tmpName, final Object element) {
final IntrospectionObject introspectionElementObject = (IntrospectionObject) element;
if (introspectionElementObject.getDataInterface() == null) {
if (introspectionElementObject.getModelIntrospection() == null) {
// property on nothing ???
return;
}
final IntrospectionObject introspectionParentObject = (IntrospectionObject) parent;
if (introspectionParentObject.getDataInterface() == null) {
if (introspectionParentObject.getModelIntrospection() == null) {
if (tmpName.equals(this.rootNodeName)) {
// this is the root node ...
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 {
return null;
}
public abstract boolean isEndPoint();
public boolean isEndPoint() {
return false;
}
public boolean isArray() {
return false;
}
public boolean isList() {
if (this.classType.isArray()) {
return true;
}
if (List.class.isAssignableFrom(this.classType) ) {
return true;
}
return false;
}
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 {
private IntrospectionModelFactory() {}
public static IntrospectionModel createModel(final Class<?> classType) throws ExmlBuilderException {
if (StringSerializer.contains(classType)) {
return new IntrospectionModelBaseType(classType);
public static IntrospectionModel createModelsssss(final MapKey modelType) throws ExmlBuilderException {
/*
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 {
private final IntrospectionModel modelInterface;
private Object data = null;
@Deprecated
private final String listNameModel;
private final Map<String, Object> properties = new HashMap<>();
private final Map<String, List<Object>> nodes = new HashMap<>();
@ -24,6 +25,7 @@ public class IntrospectionObject {
this.listNameModel = null;
}
@Deprecated
public IntrospectionObject(final IntrospectionModel dataInterface, final String listNameModel) {
this.modelInterface = dataInterface;
this.listNameModel = listNameModel;
@ -34,6 +36,7 @@ public class IntrospectionObject {
this.listNameModel = null;
}
@Deprecated
public String getListNameModel() {
return this.listNameModel;
}
@ -42,7 +45,7 @@ public class IntrospectionObject {
return this.data;
}
public IntrospectionModel getDataInterface() {
public IntrospectionModel getModelIntrospection() {
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.IntrospectionModelFactory;
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.internal.Log;
import org.atriasoft.exml.parser.Tools;
public class GeneratorIntrospection implements Generator {
// 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).
final Class<?> rootClassType;
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.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 out = this.elements.get(classType);
IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException {
MapKey key = new MapKey(model, name, classType);
IntrospectionModel out = this.elements.get(key);
if (out != null) {
return out;
}
out = IntrospectionModelFactory.createModel(classType);
this.elements.put(classType, out);
if (model == ModelType.ARRAY) {
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;
}
@ -60,33 +71,32 @@ public class GeneratorIntrospection implements Generator {
if (!elem.canGetValue()) {
continue;
}
String name = elem.getNames()[0];
Object dataObj =elem.getValue(data);
Object dataObj = elem.getValue(data);
if (dataObj == null) {
continue;
}
String name = elem.getNames()[0];
Class<?> type = elem.getType();
Class<?> subType = elem.getSubType();
generateNode(dataObj, name, tmpp, indent);
/*
if (List.class.isAssignableFrom(type)) {
// special case for List ...
type = elem.getSubType();
generateNodeList(dataObj, name, tmpp, indent);
IntrospectionModel introspectionSub = null;
if (type.isArray()) {
Class<?> typeClass = elem.getSubType();
String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.ARRAY, listTreeName, typeClass);
} else if (List.class.isAssignableFrom(type)) {
Class<?> typeClass = elem.getSubType();
String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.LIST, listTreeName, typeClass);
} 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 {
IntrospectionModel introspection = findOrCreate(data.getClass());
if (introspection.isEndPoint()) {
if (introspection.isList()) {
String[] listDatas = introspection.toStringList(data);
public void generateNode(final Object data, final IntrospectionModel model, final String nodeName, final StringBuilder tmpp, final int indent) throws ExmlBuilderException {
if (model.isEndPoint()) {
if (model.isList()) {
String[] listDatas = model.toStringList(data);
for (int iii=0; iii<listDatas.length; iii++) {
Tools.addIndent(tmpp, indent);
tmpp.append("<");
@ -102,21 +112,37 @@ public class GeneratorIntrospection implements Generator {
tmpp.append("<");
tmpp.append(nodeName);
tmpp.append(">");
tmpp.append(introspection.toString(data));
tmpp.append(model.toString(data));
tmpp.append("</");
tmpp.append(nodeName);
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");
} else {
Tools.addIndent(tmpp, indent);
tmpp.append("<");
tmpp.append(nodeName);
generateProperties(data, introspection, tmpp);
if (introspection.getNodes().size() != 0) {
generateProperties(data, model, tmpp);
if (model.getNodes().size() != 0) {
tmpp.append(">");
generateSubNodes(data, introspection, tmpp, indent + 1);
generateSubNodes(data, model, tmpp, indent + 1);
Tools.addIndent(tmpp, indent);
tmpp.append("</");
tmpp.append(nodeName);
@ -128,6 +154,7 @@ public class GeneratorIntrospection implements Generator {
}
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);
}
}