[DEV] continue integration of generated object

This commit is contained in:
Edouard DUPIN 2021-06-24 21:48:10 +02:00
parent 48fb2da890
commit 7017468e46
11 changed files with 772 additions and 59 deletions

View File

@ -27,7 +27,7 @@ public interface Builder {
Object newDeclaration(Object parent, String text) throws ExmlBuilderException; Object newDeclaration(Object parent, String text) throws ExmlBuilderException;
/** /**
* Add a new sub-element on the current parent element * Add a new sub-element on the current parent element: {@code<ELEMENT>}
* @param parent Element representing the node of the Element is added * @param parent Element representing the node of the Element is added
* @param nodeName New element name. * @param nodeName New element name.
* @return the object representing the Element. * @return the object representing the Element.
@ -59,4 +59,19 @@ public interface Builder {
*/ */
void newText(Object parent, String text) throws ExmlBuilderException; void newText(Object parent, String text) throws ExmlBuilderException;
/**
* Detect the end of the element : {@code<ELEMENT>}
* @param element Element that is finished
* @throws ExmlBuilderException
*/
void endElement(Object element) throws ExmlBuilderException;
/**
* The sub-element is finish (creation done)
* @param parent Parent node of the element that is created
* @param tmpname Name of the node
* @param element Element builder that has been created
*/
void newElementFinished(Object parent, String tmpname, Object element);
} }

View File

@ -67,4 +67,14 @@ public class BuilderGeneric implements Builder {
throw new ExmlBuilderException("can not add Text on something else than Element or Declaration"); throw new ExmlBuilderException("can not add Text on something else than Element or Declaration");
} }
@Override
public void endElement(Object element) {
// Nothing to do...
}
@Override
public void newElementFinished(Object parent, String tmpname, Object element) {
// Nothing to do...
}
} }

View File

@ -56,19 +56,26 @@ public class BuilderIntrospection implements Builder {
if (nodeName.contentEquals(this.rootNodeName)) { if (nodeName.contentEquals(this.rootNodeName)) {
Log.verbose("Create new class: " + this.rootClassType.getCanonicalName()); Log.verbose("Create new class: " + this.rootClassType.getCanonicalName());
final IntrospectionData inferData = findOrCreate(this.rootClassType); final IntrospectionData inferData = findOrCreate(this.rootClassType);
final Object newElement = inferData.createObject(); //final Object newElement = inferData.createObject();
rootList.add(newElement); //rootList.add(newElement);
return new IntrospectionObject(inferData, newElement); return new IntrospectionObject(inferData);//, newElement);
} }
// need to add a throw on the node... // need to add a throw on the node...
return null; // ==> disable the parsing.. return null; // ==> disable the parsing..
} }
Class<?> typeClass = introspectionObject.getTypeOfSubNode(nodeName); Class<?> typeClass = introspectionObject.getTypeOfSubNode(nodeName);
if (typeClass != null) { if (typeClass != null) {
if (!List.class.isAssignableFrom(typeClass)) {
Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'"); Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionData inferData = findOrCreate(typeClass); final IntrospectionData inferData = findOrCreate(typeClass);
// Create the data when object is ended created... // Create the data when object is ended created...
return new IntrospectionObject(inferData, null); return new IntrospectionObject(inferData);
}
Class<?> subTypeClass = introspectionObject.getTypeOfSubNodeSubType(nodeName);
Log.verbose("Create new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionData inferData = findOrCreate(subTypeClass);
// Create the data when object is ended created...
return new IntrospectionObject(inferData);
} }
return null; return null;
} }
@ -99,4 +106,29 @@ public class BuilderIntrospection implements Builder {
introspectionObject.setText(text); introspectionObject.setText(text);
} }
@Override
public void endElement(Object element) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) element;
if (introspectionObject.getDataInterface() == null) {
// property on nothing ???
return;
}
introspectionObject.generateTheObject();
}
@Override
public void newElementFinished(Object parent, String tmpname, Object element) {
final IntrospectionObject introspectionElementObject = (IntrospectionObject) element;
if (introspectionElementObject.getDataInterface() == null) {
// property on nothing ???
return;
}
final IntrospectionObject introspectionParentObject = (IntrospectionObject) parent;
if (introspectionParentObject.getDataInterface() == null) {
// property on nothing ???
return;
}
introspectionParentObject.addObject(tmpname, introspectionElementObject.getData());
}
} }

View File

@ -5,10 +5,20 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.atriasoft.etk.util.ArraysTools;
import org.atriasoft.exml.annotation.XmlCaseSensitive; import org.atriasoft.exml.annotation.XmlCaseSensitive;
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive; import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
import org.atriasoft.exml.annotation.XmlDefaultManaged; import org.atriasoft.exml.annotation.XmlDefaultManaged;
@ -16,21 +26,140 @@ import org.atriasoft.exml.annotation.XmlDefaultOptional;
import org.atriasoft.exml.annotation.XmlManaged; import org.atriasoft.exml.annotation.XmlManaged;
import org.atriasoft.exml.annotation.XmlName; import org.atriasoft.exml.annotation.XmlName;
import org.atriasoft.exml.annotation.XmlOptional; import org.atriasoft.exml.annotation.XmlOptional;
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 IntrospectionData { public class IntrospectionData {
private static final Boolean DEFAULT_CASE_SENSITIVE = true; private static final Boolean DEFAULT_CASE_SENSITIVE = true;
private static final Boolean DEFAULT_MANAGED = true; private static final Boolean DEFAULT_MANAGED = true;
private static final Boolean DEFAULT_OPTIONAL = false; private static final Boolean DEFAULT_OPTIONAL = false;
public interface Converter {
Object valueOf(String value);
}
private static final Map<Class<?>, Converter> VALUES_OF = new HashMap<>();
static {
VALUES_OF.put(byte.class, new Converter() {
public Object valueOf(String value) {
return Byte.valueOf(value);
}
});
VALUES_OF.put(Byte.class, new Converter() {
public Object valueOf(String value) {
return Byte.valueOf(value);
}
});
VALUES_OF.put(int.class, new Converter() {
public Object valueOf(String value) {
return Integer.valueOf(value);
}
});
VALUES_OF.put(Integer.class, new Converter() {
public Object valueOf(String value) {
return Integer.valueOf(value);
}
});
VALUES_OF.put(long.class, new Converter() {
public Object valueOf(String value) {
return Long.valueOf(value);
}
});
VALUES_OF.put(Long.class, new Converter() {
public Object valueOf(String value) {
return Long.valueOf(value);
}
});
VALUES_OF.put(short.class, new Converter() {
public Object valueOf(String value) {
return Short.valueOf(value);
}
});
VALUES_OF.put(Short.class, new Converter() {
public Object valueOf(String value) {
return Short.valueOf(value);
}
});
VALUES_OF.put(boolean.class, new Converter() {
public Object valueOf(String value) {
return Boolean.valueOf(value);
}
});
VALUES_OF.put(Boolean.class, new Converter() {
public Object valueOf(String value) {
return Boolean.valueOf(value);
}
});
VALUES_OF.put(byte[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseByteStringList(value);
}
});
VALUES_OF.put(Byte[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseByteClassStringList(value);
}
});
VALUES_OF.put(short[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseShortStringList(value);
}
});
VALUES_OF.put(Short[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseShortClassStringList(value);
}
});
VALUES_OF.put(int[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseIntegerStringList(value);
}
});
VALUES_OF.put(Integer[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseIntegerClassStringList(value);
}
});
VALUES_OF.put(long[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseLongStringList(value);
}
});
VALUES_OF.put(Long[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseLongClassStringList(value);
}
});
VALUES_OF.put(boolean[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseBooleanStringList(value);
}
});
VALUES_OF.put(Boolean[].class, new Converter() {
public Object valueOf(String value) {
return Tools.parseBooleanClassStringList(value);
}
});
VALUES_OF.put(String.class, new Converter() {
public Object valueOf(String value) {
return value;
}
});
}
final Class<?> classType; final Class<?> classType;
final Class<?> subClassType;
private final Method valueof; // used for the set Text if the object is an end point...
private final List<IntrospectionProperty> methods = new ArrayList<>(); private final List<IntrospectionProperty> methods = new ArrayList<>();
private final List<IntrospectionProperty> properties = new ArrayList<>(); private final List<IntrospectionProperty> properties = new ArrayList<>();
public IntrospectionData(final Class<?> classType) throws Exception { public IntrospectionData(final Class<?> classType) throws Exception {
this(classType, null);
}
public IntrospectionData(final Class<?> classType, final Class<?> subClassType) throws Exception {
this.classType = classType; this.classType = classType;
this.subClassType = subClassType;
final Boolean isDefaultManaged = getIsDefaultManaged(classType, IntrospectionData.DEFAULT_MANAGED); final Boolean isDefaultManaged = getIsDefaultManaged(classType, IntrospectionData.DEFAULT_MANAGED);
final Boolean isDefaultOptional = getIsDefaultOptional(classType, IntrospectionData.DEFAULT_OPTIONAL); final Boolean isDefaultOptional = getIsDefaultOptional(classType, IntrospectionData.DEFAULT_OPTIONAL);
final Boolean isDefaultCaseSensitive = getIsDefaultCaseSensitive(classType, IntrospectionData.DEFAULT_CASE_SENSITIVE); final Boolean isDefaultCaseSensitive = getIsDefaultCaseSensitive(classType, IntrospectionData.DEFAULT_CASE_SENSITIVE);
@ -59,6 +188,12 @@ public class IntrospectionData {
if (o.getName().contentEquals("getClass")) { if (o.getName().contentEquals("getClass")) {
return false; return false;
} }
if (Modifier.isStatic(o.getModifiers())) {
if (o.getName().contentEquals("valueOf") && o.getParameterCount() == 1 && o.getParameters()[0].getType() == String.class) {
return true;
}
return false;
}
if (o.getName().startsWith("get")) { if (o.getName().startsWith("get")) {
if (o.getParameterCount() != 0 || o.getReturnType() == void.class || o.getReturnType() == Boolean.class || o.getReturnType() == boolean.class) { if (o.getParameterCount() != 0 || o.getReturnType() == void.class || o.getReturnType() == Boolean.class || o.getReturnType() == boolean.class) {
return false; return false;
@ -102,12 +237,12 @@ public class IntrospectionData {
} }
return false; return false;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
Log.verbose(" Methods: (" + methods.size() + ")"); Log.verbose(" Methods: (" + methods.size() + ")");
for (final Method elem : methods) { for (final Method elem : methods) {
Log.verbose(" - " + elem.toGenericString()); Log.verbose(" - " + elem.toGenericString());
} }
// Separate the methods and filer as: // Separate the methods and filer as:
// XXX GetXxx(); & XXX != boolean // XXX GetXxx(); & XXX != boolean
// void setXxx(XXX elem); // void setXxx(XXX elem);
@ -116,7 +251,14 @@ public class IntrospectionData {
final List<Method> methodsGet = methods.stream().filter(o -> o.getName().startsWith("get")).collect(Collectors.toList()); final List<Method> methodsGet = methods.stream().filter(o -> o.getName().startsWith("get")).collect(Collectors.toList());
final List<Method> methodsSet = methods.stream().filter(o -> o.getName().startsWith("set")).collect(Collectors.toList()); final List<Method> methodsSet = methods.stream().filter(o -> o.getName().startsWith("set")).collect(Collectors.toList());
final List<Method> methodsIs = methods.stream().filter(o -> o.getName().startsWith("is")).collect(Collectors.toList()); final List<Method> methodsIs = methods.stream().filter(o -> o.getName().startsWith("is")).collect(Collectors.toList());
final List<Method> valueOfString = methods.stream().filter(o -> o.getName().startsWith("valueOf")).collect(Collectors.toList());
if (valueOfString.size() == 1) {
valueof = valueOfString.get(0);
} else {
// some specific model:
valueof = null;
}
// associate methods by pair. // associate methods by pair.
final List<OrderData> elements = new ArrayList<>(); final List<OrderData> elements = new ArrayList<>();
for (final Method method : methodsGet) { for (final Method method : methodsGet) {
@ -146,6 +288,26 @@ public class IntrospectionData {
break; break;
} }
} }
/*
Class<?> internalModelClass = null;
Class<?>[] tmppp = method.getParameterTypes();
if (tmppp.length > 0 && (List.class.isAssignableFrom(tmppp[0]))) {
Log.warning(" * " + method.getName());
Type[] empppe = method.getGenericParameterTypes();
if (empppe.length > 0) {
if (empppe[0] instanceof ParameterizedType plopppppp) {
Type[] realType = plopppppp.getActualTypeArguments();
if (realType.length > 0) {
Log.warning(" -->> " + realType[0]);
internalModelClass = Class.forName(realType[0].getTypeName());
}
}
}
for (int iii=0; iii<tmppp.length; iii++) {
Log.warning(" -- " + tmppp[iii].getCanonicalName());
}
}
*/
if (tmp == null) { if (tmp == null) {
tmp = new OrderData(name); tmp = new OrderData(name);
tmp.setter = method; tmp.setter = method;
@ -220,17 +382,25 @@ public class IntrospectionData {
} }
Object createObject() { Object createObject(Map<String, Object> properties, Map<String, List<Object>> nodes) throws ExmlBuilderException {
Object tmp;
try { try {
return this.classType.getConstructor().newInstance(); tmp = this.classType.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
for (Entry<String, Object> elem : properties.entrySet()) {
setValue(tmp, elem.getKey(), elem.getValue());
}
for (Entry<String, List<Object>> elem : nodes.entrySet()) {
setValue(tmp, elem.getKey(), elem.getValue());
}
return tmp;
} }
protected IntrospectionProperty findMethodDescription(final String propertyName) throws Exception { protected IntrospectionProperty findMethodDescription(final String propertyName) throws ExmlBuilderException {
for (final IntrospectionProperty prop : this.methods) { for (final IntrospectionProperty prop : this.methods) {
if (prop.isCompatible(propertyName)) { if (prop.isCompatible(propertyName)) {
return prop; return prop;
@ -239,7 +409,7 @@ public class IntrospectionData {
return null; return null;
} }
protected IntrospectionProperty findPropertyDescription(final String propertyName) throws Exception { protected IntrospectionProperty findPropertyDescription(final String propertyName) throws ExmlBuilderException {
for (final IntrospectionProperty prop : this.properties) { for (final IntrospectionProperty prop : this.properties) {
if (prop.isCompatible(propertyName)) { if (prop.isCompatible(propertyName)) {
return prop; return prop;
@ -248,79 +418,79 @@ public class IntrospectionData {
return null; return null;
} }
protected Boolean getIsCaseSensitive(final Field element, final Boolean defaultValue) throws Exception { protected Boolean getIsCaseSensitive(final Field element, final Boolean defaultValue) throws ExmlBuilderException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlCaseSensitive.class); final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlCaseSensitive.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return defaultValue; return defaultValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlCaseSensitive) annotation[0]).value(); return ((XmlCaseSensitive) annotation[0]).value();
} }
protected Boolean getIsCaseSensitive(final Method element, final Boolean defaultValue) throws Exception { protected Boolean getIsCaseSensitive(final Method element, final Boolean defaultValue) throws ExmlBuilderException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlCaseSensitive.class); final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlCaseSensitive.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return defaultValue; return defaultValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlCaseSensitive) annotation[0]).value(); return ((XmlCaseSensitive) annotation[0]).value();
} }
private Boolean getIsDefaultCaseSensitive(final Class<?> classType, final Boolean defaultValue) throws Exception { private Boolean getIsDefaultCaseSensitive(final Class<?> classType, final Boolean defaultValue) throws ExmlBuilderException {
final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultCaseSensitive.class); final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultCaseSensitive.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return defaultValue; return defaultValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlDefaultCaseSensitive) annotation[0]).value(); return ((XmlDefaultCaseSensitive) annotation[0]).value();
} }
private Boolean getIsDefaultManaged(final Class<?> classType, final Boolean defaultValue) throws Exception { private Boolean getIsDefaultManaged(final Class<?> classType, final Boolean defaultValue) throws ExmlBuilderException {
final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultManaged.class); final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultManaged.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return defaultValue; return defaultValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlDefaultManaged) annotation[0]).value(); return ((XmlDefaultManaged) annotation[0]).value();
} }
private Boolean getIsDefaultOptional(final Class<?> classType, final Boolean defaultValue) throws Exception { private Boolean getIsDefaultOptional(final Class<?> classType, final Boolean defaultValue) throws ExmlBuilderException {
final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultOptional.class); final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultOptional.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return defaultValue; return defaultValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlDefaultOptional) annotation[0]).value(); return ((XmlDefaultOptional) annotation[0]).value();
} }
protected Boolean getIsManaged(final Field element, final Boolean parentValue) throws Exception { protected Boolean getIsManaged(final Field element, final Boolean parentValue) throws ExmlBuilderException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlManaged.class); final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlManaged.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return parentValue; return parentValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlManaged) annotation[0]).value(); return ((XmlManaged) annotation[0]).value();
} }
protected Boolean getIsManaged(final Method element, final Boolean parentValue) throws Exception { protected Boolean getIsManaged(final Method element, final Boolean parentValue) throws ExmlBuilderException {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlManaged.class); final Annotation[] annotation = element.getDeclaredAnnotationsByType(XmlManaged.class);
if (annotation.length == 0) { if (annotation.length == 0) {
return parentValue; return parentValue;
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new ExmlBuilderException("Must not hame more that ");
} }
return ((XmlManaged) annotation[0]).value(); return ((XmlManaged) annotation[0]).value();
} }
@ -404,8 +574,75 @@ public class IntrospectionData {
} }
return tmp; return tmp;
} }
@SuppressWarnings("unchecked")
private <T> T[] autoCast(Class<T> clazz, List<Object> data) {
T[] out = (T[]) java.lang.reflect.Array.newInstance(clazz, data.size());// T[data.size()];
public void setProperty(final Object data, final String propertyName, final String propertyValue) throws Exception { for(int iii=0; iii<data.size(); iii++) {
out[iii] = (T) data.get(iii);
}
return out;
//return data.stream().map(clazz::cast).toArray(new T[data.size()]);//java.lang.reflect.Array.newInstance((propMethode.getSubType(), tmpp.size()));
}
private void setValue(Object data, String name, Object value) throws ExmlBuilderException {
Log.error(" Set value ='" + name + "' propertyValue='" + value + "' " + value.getClass().getCanonicalName());
// by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(name);
if (propMethode != null && propMethode.canSetValue()) {
Log.verbose(" ==> find '" + Arrays.toString(propMethode.getNames()) + " type=" + propMethode.getType() + " sub-type=" + propMethode.getSubType() );
if (propMethode.getType().isAssignableFrom(value.getClass())) {
propMethode.setExistingValue(data, value);
} else {
@SuppressWarnings("unchecked")
List<Object> tmpp = (List<Object>)value;
if (propMethode.getType().isArray()) {
if (propMethode.getType().componentType() == byte.class) {
byte[] datas = ArraysTools.listByteToPrimitive(tmpp);
propMethode.setExistingValue(data, datas);
} else if (propMethode.getType().componentType() == short.class) {
short[] datas = ArraysTools.listShortToPrimitive(tmpp);
propMethode.setExistingValue(data, datas);
} else if (propMethode.getType().componentType() == int.class) {
int[] datas = ArraysTools.listIntegerToPrimitive(tmpp);
propMethode.setExistingValue(data, datas);
} else if (propMethode.getType().componentType() == long.class) {
long[] datas = ArraysTools.listLongToPrimitive(tmpp);
propMethode.setExistingValue(data, datas);
} else if (propMethode.getType().componentType() == boolean.class) {
boolean[] datas = ArraysTools.listBooleanToPrimitive(tmpp);
propMethode.setExistingValue(data, datas);
} else {
Log.verbose(" datas type: " + autoCast(propMethode.getType().componentType(), tmpp).getClass().getCanonicalName());
Log.verbose(" methode type: " + propMethode.getType().getCanonicalName());
propMethode.setExistingValue(data, autoCast(propMethode.getType().componentType(), tmpp));
}
} else {
if (tmpp.size() == 1) {
propMethode.setExistingValue(data, tmpp.get(0));
} else {
// impossible case ...
}
}
//Log.verbose(" ==> TODO....");
}
return;
}
// try with direct field
final IntrospectionProperty propField = findPropertyDescription(name);
if (propField != null && propField.canSetValue()) {
Log.verbose(" ==> find '" + Arrays.toString(propField.getNames()) + " type=" + propMethode.getType() + " sub-type=" + propMethode.getSubType() );
if (propField.getType().isAssignableFrom(value.getClass())) {
propField.setExistingValue(data, value);
} else {
Log.verbose(" ==> TODO....");
}
return;
}
throw new ExmlBuilderException("can not find the field '" + name + "'");
}
public void setProperty(final Object data, final String propertyName, final String propertyValue) throws ExmlBuilderException {
Log.error(" propertyName='" + propertyName + "' propertyValue='" + propertyValue + "' "); Log.error(" propertyName='" + propertyName + "' propertyValue='" + propertyValue + "' ");
// by default use setter to set the property // by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(propertyName); final IntrospectionProperty propMethode = findMethodDescription(propertyName);
@ -421,7 +658,7 @@ public class IntrospectionData {
propField.setValue(data, propertyValue); propField.setValue(data, propertyValue);
return; return;
} }
throw new Exception("can not find the field '" + propertyName + "'"); throw new ExmlBuilderException("can not find the field '" + propertyName + "'");
} }
/** /**
@ -429,7 +666,7 @@ public class IntrospectionData {
* @param nodeName Name of the node * @param nodeName Name of the node
* @return Class of the node to create * @return Class of the node to create
*/ */
public Class<?> getTypeOfSubNode(final Object data, final String nodeName) throws Exception { public Class<?> getTypeOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException {
Log.error(" nodeType='" + nodeName + "'"); Log.error(" nodeType='" + nodeName + "'");
// by default use setter to set the property // by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(nodeName); final IntrospectionProperty propMethode = findMethodDescription(nodeName);
@ -443,11 +680,89 @@ public class IntrospectionData {
Log.error(" ==> find '" + propField.getNames()); Log.error(" ==> find '" + propField.getNames());
return propMethode.getType(); return propMethode.getType();
} }
throw new Exception("can not find the field '" + nodeName + "'"); throw new ExmlBuilderException("can not find the field '" + nodeName + "'");
}
public Class<?> getTypeOfSubNodeList(Object data, String nodeName) throws ExmlBuilderException {
Log.error(" nodeType='" + nodeName + "'");
// by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(nodeName);
if (propMethode != null && propMethode.canSetValue()) {
Log.error(" ==> find '" + propMethode.getNames());
return propMethode.getSubType();
}
// try with direct field
final IntrospectionProperty propField = findPropertyDescription(nodeName);
if (propField != null && propField.canSetValue()) {
Log.error(" ==> find '" + propField.getNames());
return propMethode.getSubType();
}
throw new ExmlBuilderException("can not find the field '" + nodeName + "'");
} }
public void setText(final Object data, final String text) { public Object getValueFromText(final String text) throws ExmlBuilderException {
Log.todo("add text to element ... '" + text + "' for type : " + this.classType.getCanonicalName()); // Note if the type is an Array<>() or a List<>() ==> we parse element by element ... then we need to keep the undertype...
Class<?> classTypeLocal = this.classType;
Log.warning("======>>>>>>> Get input type : " + this.classType.getCanonicalName());
//Log.warning("======>>>>>>> Get input component type : " + this.classType.getComponentType().getCanonicalName());
if (this.classType.isArray()){
// generic array ...
classTypeLocal = this.classType.getComponentType();
} else if (List.class == this.classType || Collection.class.isAssignableFrom(this.classType)) {
// a generic list ....
if (subClassType != null) {
classTypeLocal = subClassType;
}
//Type[] tmpp = this.classType.getGenericInterfaces();
//Class<?>[] tmpp = this.classType.getNestMembers();
//Class<?>[] tmpp = this.classType.getClasses();
//Class<?>[] tmpp = this.classType.getDeclaredClasses();
//Class<?>[] tmpp = this.classType.getInterfaces();
//Class<?> tmpp = this.classType.getDeclaringClass();
//TypeVariable<?>[] tmpp = this.classType.getTypeParameters();
/*
Class<?> persistentClass =((ParameterizedType)classType.getGenericSuperclass()).getActualTypeArguments()[0];
*/
//Type tmpp = classType.getGenericSuperclass();
// Class<?> tmpp = classType.getInterfaces();
// Log.warning("======>>>>>>> Find List '" + tmpp + "'");
// for (int iii = 0; iii < tmpp.length; iii++) {
// Log.warning(" - " + tmpp[iii]);
// }
}
Log.warning("======>>>>>>> subElement input type : " + classTypeLocal.getCanonicalName());
if (this.valueof == null) {
Converter con = VALUES_OF.get(classTypeLocal);
if (con == null) {
throw new ExmlBuilderException("function 'valueOf' for '" + classTypeLocal.getCanonicalName() + "' is not defined and not registered for specific type");
} else {
return con.valueOf(text);
}
}
try {
return this.valueof.invoke(null, text);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in call 'valueOf(String ...)' for '" + classTypeLocal.getCanonicalName() + "' " + e.getMessage());
}
}
public Object getValue(String propertyName, String propertyValue) throws ExmlBuilderException {
Log.error(" propertyName='" + propertyName + "' propertyValue='" + propertyValue + "' ");
// by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(propertyName);
if (propMethode != null && propMethode.canSetValue()) {
Log.verbose(" ==> find '" + propMethode.getNames());
return propMethode.createValue(propertyValue);
}
// try with direct field
final IntrospectionProperty propField = findPropertyDescription(propertyName);
if (propField != null && propField.canSetValue()) {
Log.verbose(" ==> find '" + propField.getNames());
return propField.createValue(propertyValue);
}
throw new ExmlBuilderException("can not find the field '" + propertyName + "'");
} }
} }

View File

@ -1,10 +1,18 @@
package org.atriasoft.exml.builder; package org.atriasoft.exml.builder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.internal.Log;
public class IntrospectionObject { public class IntrospectionObject {
private final IntrospectionData dataInterface; private final IntrospectionData dataInterface;
private final Object data; private Object data = null;
private final Map<String, Object> properties = new HashMap<>();
private final Map<String, List<Object>> nodes = new HashMap<>();
/** /**
* Create and empty element that have nothing. this is for the root node ==> not capable of knowing if only one element is created or many ... * Create and empty element that have nothing. this is for the root node ==> not capable of knowing if only one element is created or many ...
@ -19,6 +27,11 @@ public class IntrospectionObject {
this.data = data; this.data = data;
} }
public IntrospectionObject(final IntrospectionData dataInterface) {
this.dataInterface = dataInterface;
this.data = null;
}
public Object getData() { public Object getData() {
return this.data; return this.data;
} }
@ -29,7 +42,13 @@ public class IntrospectionObject {
public void setProperty(final String propertyName, final String propertyValue) throws Exception { public void setProperty(final String propertyName, final String propertyValue) throws Exception {
this.dataInterface.setProperty(this.data, propertyName, propertyValue); this.dataInterface.setProperty(this.data, propertyName, propertyValue);
Object value = this.dataInterface.getValue(propertyName, propertyValue);
Object property = properties.get(propertyName);
if (property == null) {
properties.put(propertyName, value);
} else {
throw new ExmlBuilderException("Property have multiple values ==> impossible case; A Node must contain only 1 attibutes");
}
} }
/** /**
@ -37,11 +56,40 @@ public class IntrospectionObject {
* @param nodeName Name of the node * @param nodeName Name of the node
* @return Class of the node to create * @return Class of the node to create
*/ */
public Class<?> getTypeOfSubNode(final String nodeName) throws Exception { public Class<?> getTypeOfSubNode(final String nodeName) throws ExmlBuilderException {
return this.dataInterface.getTypeOfSubNode(this.data, nodeName); return this.dataInterface.getTypeOfSubNode(this.data, nodeName);
} }
public Class<?> getTypeOfSubNodeSubType(String nodeName) throws ExmlBuilderException {
public void setText(final String text) { return this.dataInterface.getTypeOfSubNodeList(this.data, nodeName);
this.dataInterface.setText(this.data, text);
} }
public void setText(final String text) throws ExmlBuilderException {
if (this.data != null) {
throw new ExmlBuilderException("Can not set multiple text value in a single NODE ...");
}
this.data = this.dataInterface.getValueFromText(text);
}
public void addObject(String nodeName, Object value) {
List<Object> node = nodes.get(nodeName);
if (node == null) {
node = new ArrayList<>();
node.add(value);
nodes.put(nodeName, node);
} else {
node.add(value);
}
}
public void generateTheObject() throws ExmlBuilderException {
if (data != null) {
// nothing to do ... ==> element already created
return;
}
Log.info("Create the element for the Specific node ... type = " + dataInterface.classType.getCanonicalName());
Log.info(" Properties : " + this.properties.keySet());
Log.info(" Nodes : " + this.nodes.keySet());
this.data = dataInterface.createObject(this.properties, this.nodes);
}
} }

View File

@ -1,13 +1,17 @@
package org.atriasoft.exml.builder; package org.atriasoft.exml.builder;
import org.atriasoft.exml.exception.ExmlBuilderException;
public abstract class IntrospectionProperty { public abstract class IntrospectionProperty {
protected final Boolean caseSensitive; protected final Boolean caseSensitive;
protected final Boolean isOptionnal; protected final Boolean isOptionnal;
protected final String[] names; protected final String[] names;
protected final Class<?> type; protected final Class<?> type;
protected final Class<?> subType;
public IntrospectionProperty(final Class<?> type, final String[] names, final Boolean caseSensitive, final Boolean isOptionnal) { public IntrospectionProperty(final Class<?>[] type, final String[] names, final Boolean caseSensitive, final Boolean isOptionnal) {
this.type = type; this.type = type[0];
this.subType = type[1];
this.names = names; this.names = names;
this.caseSensitive = caseSensitive; this.caseSensitive = caseSensitive;
this.isOptionnal = isOptionnal; this.isOptionnal = isOptionnal;
@ -25,6 +29,10 @@ public abstract class IntrospectionProperty {
return this.type; return this.type;
} }
public Class<?> getSubType() {
return this.subType;
}
public abstract String getValue(Object object) throws Exception; public abstract String getValue(Object object) throws Exception;
public boolean isCaseSensitive() { public boolean isCaseSensitive() {
@ -48,6 +56,27 @@ public abstract class IntrospectionProperty {
} }
return false; return false;
} }
/**
* set the specific string value in the specified object
* @param object Object to add the value
* @param value Value to set in the Object
* @throws Exception An error occurred
*/
public abstract void setValue(Object object, String value) throws ExmlBuilderException;
/**
* set the specific string value in the specified object
* @param object Object to add the value
* @param value Value to set in the Object
* @throws Exception An error occurred
*/
public abstract void setExistingValue(Object object, Object value) throws ExmlBuilderException;
public abstract void setValue(Object object, String value) throws Exception; /**
* Create a value adapted to the property type.
* @apiNote generic type is transformed byte -> Byte, int -> Integer ...
* @param value Value to set in the Object
* @throws Exception An error occurred
* @return The object created
*/
protected abstract Object createValue(String value) throws ExmlBuilderException;
} }

View File

@ -1,15 +1,39 @@
package org.atriasoft.exml.builder; package org.atriasoft.exml.builder;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
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 IntrospectionPropertyField extends IntrospectionProperty { public class IntrospectionPropertyField extends IntrospectionProperty {
private final Field fieldDescription; private final Field fieldDescription;
private static Class<?>[] getTypeField(final Field fieldDescription) {
Class<?> type = fieldDescription.getType();
Class<?> subType = null;
Type empppe = fieldDescription.getGenericType();
if (empppe instanceof ParameterizedType plopppppp) {
Type[] realType = plopppppp.getActualTypeArguments();
if (realType.length > 0) {
try {
subType = Class.forName(realType[0].getTypeName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return new Class<?>[] {type, subType};
}
public IntrospectionPropertyField(final Field fieldDescription, final String[] names, final Boolean caseSensitive, final Boolean isOptionnal) { public IntrospectionPropertyField(final Field fieldDescription, final String[] names, final Boolean caseSensitive, final Boolean isOptionnal) {
super(fieldDescription.getType(), names, caseSensitive, isOptionnal); super(getTypeField(fieldDescription), names, caseSensitive, isOptionnal);
this.fieldDescription = fieldDescription; this.fieldDescription = fieldDescription;
} }
@ -30,7 +54,7 @@ public class IntrospectionPropertyField extends IntrospectionProperty {
} }
@Override @Override
public void setValue(final Object object, final String value) { public void setValue(final Object object, final String value) throws ExmlBuilderException {
try { try {
if (this.type == byte.class) { if (this.type == byte.class) {
final byte data = Byte.valueOf(value); final byte data = Byte.valueOf(value);
@ -85,11 +109,78 @@ public class IntrospectionPropertyField extends IntrospectionProperty {
} else if (this.type == Boolean[].class) { } else if (this.type == Boolean[].class) {
this.fieldDescription.set(object, Tools.parseBooleanClassStringList(value)); this.fieldDescription.set(object, Tools.parseBooleanClassStringList(value));
} else { } else {
Log.error("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'"); throw new ExmlBuilderException("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'");
} }
} catch (IllegalArgumentException | IllegalAccessException e) { } catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
}
}
@Override
protected Object createValue(String value) throws ExmlBuilderException {
try {
if (this.type == byte.class) {
return Byte.valueOf(value);
} else if (this.type == short.class) {
return Short.valueOf(value);
} else if (this.type == int.class) {
return Integer.valueOf(value);
} else if (this.type == long.class) {
return Long.valueOf(value);
} else if (this.type == boolean.class) {
return Boolean.valueOf(value);
} else if (this.type == String.class) {
return value;
} else if (this.type == Byte.class) {
return Byte.valueOf(value);
} else if (this.type == Short.class) {
return Short.valueOf(value);
} else if (this.type == Integer.class) {
return Integer.valueOf(value);
} else if (this.type == Long.class) {
return Long.valueOf(value);
} else if (this.type == Boolean.class) {
return Boolean.valueOf(value);
} else if (this.type == byte[].class) {
return Tools.parseByteStringList(value);
} else if (this.type == Byte[].class) {
return Tools.parseByteClassStringList(value);
} else if (this.type == short[].class) {
return Tools.parseShortStringList(value);
} else if (this.type == Short[].class) {
return Tools.parseShortClassStringList(value);
} else if (this.type == int[].class) {
return Tools.parseIntegerStringList(value);
} else if (this.type == Integer[].class) {
return Tools.parseIntegerClassStringList(value);
} else if (this.type == long[].class) {
return Tools.parseLongStringList(value);
} else if (this.type == Long[].class) {
return Tools.parseLongClassStringList(value);
} else if (this.type == boolean[].class) {
return Tools.parseBooleanStringList(value);
} else if (this.type == Boolean[].class) {
return Tools.parseBooleanClassStringList(value);
} else {
throw new ExmlBuilderException("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'");
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
}
}
@Override
public void setExistingValue(Object object, Object value) throws ExmlBuilderException {
try {
this.fieldDescription.set(object, value);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
} }
} }

View File

@ -1,19 +1,33 @@
package org.atriasoft.exml.builder; package org.atriasoft.exml.builder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
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 IntrospectionPropertyMethod extends IntrospectionProperty { public class IntrospectionPropertyMethod extends IntrospectionProperty {
private static Class<?> getTypefunction(final Method setter, final Method getter) throws Exception { private static Class<?>[] getTypefunction(final Method setter, final Method getter) throws Exception {
Class<?> type = null; Class<?> type = null;
Class<?> subType = null;
if (setter == null && getter == null) { if (setter == null && getter == null) {
// impossible case... // impossible case...
throw new Exception("kjhkhjkj"); throw new Exception("kjhkhjkj");
} }
if (getter != null) { if (getter != null) {
type = getter.getReturnType(); type = getter.getReturnType();
Type empppe = getter.getGenericReturnType();
if (empppe instanceof ParameterizedType plopppppp) {
Type[] realType = plopppppp.getActualTypeArguments();
if (realType.length > 0) {
subType = Class.forName(realType[0].getTypeName());
}
}
} }
if (setter != null) { if (setter != null) {
if (type != null && setter.getParameters()[0].getType() != type) { if (type != null && setter.getParameters()[0].getType() != type) {
@ -21,8 +35,26 @@ public class IntrospectionPropertyMethod extends IntrospectionProperty {
} else { } else {
type = setter.getParameters()[0].getType(); type = setter.getParameters()[0].getType();
} }
// specific for the list:
if (List.class.isAssignableFrom(type)) {
Class<?> internalModelClass = null;
Type[] empppe = setter.getGenericParameterTypes();
if (empppe.length > 0) {
if (empppe[0] instanceof ParameterizedType plopppppp) {
Type[] realType = plopppppp.getActualTypeArguments();
if (realType.length > 0) {
Log.warning(" -->> " + realType[0]);
internalModelClass = Class.forName(realType[0].getTypeName());
} }
return type; }
}
if (getter!=null && internalModelClass != subType) {
throw new Exception("The type of the setter and the type return by the getter are not the same ...");
}
subType = internalModelClass;
}
}
return new Class<?>[] {type, subType};
} }
protected Method setter; protected Method setter;
@ -46,18 +78,18 @@ public class IntrospectionPropertyMethod extends IntrospectionProperty {
} }
@Override @Override
public String getValue(final Object object) throws Exception { public String getValue(final Object object) throws ExmlBuilderException {
if (this.getter == null) { if (this.getter == null) {
throw new Exception("no getter availlable"); throw new ExmlBuilderException("no getter availlable");
} }
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
@Override @Override
public void setValue(final Object object, final String value) throws Exception { public void setValue(final Object object, final String value) throws ExmlBuilderException {
if (this.setter == null) { if (this.setter == null) {
throw new Exception("no setter availlable"); throw new ExmlBuilderException("no setter availlable");
} }
try { try {
if (this.type == byte.class) { if (this.type == byte.class) {
@ -113,12 +145,85 @@ public class IntrospectionPropertyMethod extends IntrospectionProperty {
} else if (this.type == Boolean[].class) { } else if (this.type == Boolean[].class) {
this.setter.invoke(object, (Object) Tools.parseBooleanClassStringList(value)); this.setter.invoke(object, (Object) Tools.parseBooleanClassStringList(value));
} else { } else {
Log.error("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'"); throw new ExmlBuilderException("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'");
} }
} catch (IllegalArgumentException | IllegalAccessException e) { } catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in invoque setter of the Object ... " + e.getMessage());
}
} }
@Override
protected Object createValue(String value) throws ExmlBuilderException {
try {
if (this.type == byte.class) {
return Byte.valueOf(value);
} else if (this.type == short.class) {
return Short.valueOf(value);
} else if (this.type == int.class) {
return Integer.valueOf(value);
} else if (this.type == long.class) {
return Long.valueOf(value);
} else if (this.type == boolean.class) {
return Boolean.valueOf(value);
} else if (this.type == String.class) {
return value;
} else if (this.type == Byte.class) {
return Byte.valueOf(value);
} else if (this.type == Short.class) {
return Short.valueOf(value);
} else if (this.type == Integer.class) {
return Integer.valueOf(value);
} else if (this.type == Long.class) {
return Long.valueOf(value);
} else if (this.type == Boolean.class) {
return Boolean.valueOf(value);
} else if (this.type == byte[].class) {
return Tools.parseByteStringList(value);
} else if (this.type == Byte[].class) {
return Tools.parseByteClassStringList(value);
} else if (this.type == short[].class) {
return Tools.parseShortStringList(value);
} else if (this.type == Short[].class) {
return Tools.parseShortClassStringList(value);
} else if (this.type == int[].class) {
return Tools.parseIntegerStringList(value);
} else if (this.type == Integer[].class) {
return Tools.parseIntegerClassStringList(value);
} else if (this.type == long[].class) {
return Tools.parseLongStringList(value);
} else if (this.type == Long[].class) {
return Tools.parseLongClassStringList(value);
} else if (this.type == boolean[].class) {
return Tools.parseBooleanStringList(value);
} else if (this.type == Boolean[].class) {
return Tools.parseBooleanClassStringList(value);
} else {
throw new ExmlBuilderException("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'");
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
}
}
@Override
public void setExistingValue(Object object, Object value) throws ExmlBuilderException {
if (this.setter == null) {
throw new ExmlBuilderException("no setter availlable");
}
try {
this.setter.invoke(object, value);
} catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
}
} }
} }

View File

@ -489,6 +489,8 @@ public class ParseXml {
if (data.charAt(jjj) == '>') { if (data.charAt(jjj) == '>') {
pos.value = jjj; pos.value = jjj;
filePos.add(tmpPos); filePos.add(tmpPos);
Log.todo("End of node: '" + nameElement + "' ==> need add build result to parent and create object ...");
this.builder.endElement(parent);
return true; return true;
} }
if (data.charAt(jjj) != '\r' && data.charAt(jjj) != ' ' && data.charAt(jjj) != '\t') { if (data.charAt(jjj) != '\r' && data.charAt(jjj) != ' ' && data.charAt(jjj) != '\t') {
@ -498,6 +500,7 @@ public class ParseXml {
return false; return false;
} }
} }
} }
if (data.charAt(iii + white + 1) == '>') { if (data.charAt(iii + white + 1) == '>') {
// end of something == > this is really bad // end of something == > this is really bad
@ -541,6 +544,8 @@ public class ParseXml {
if (!iParseElement(element, tmpnameOriginal, data, pos, filePos, parsingProperty)) { if (!iParseElement(element, tmpnameOriginal, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
// TODO : Add the element in the parent ...
this.builder.newElementFinished(parent, tmpname, element);
iii = pos.value; iii = pos.value;
continue; continue;
} }

View File

@ -6,6 +6,7 @@
package test.atriasoft.exml; package test.atriasoft.exml;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import org.atriasoft.exml.Exml; import org.atriasoft.exml.Exml;
import org.atriasoft.exml.exception.ExmlBuilderException; import org.atriasoft.exml.exception.ExmlBuilderException;
@ -247,6 +248,17 @@ public class ExmlTestIntrospection {
+ " <memberArrayBooleanClass> false</memberArrayBooleanClass>\n" + " <memberArrayBooleanClass> false</memberArrayBooleanClass>\n"
+ " <memberArrayBooleanClass>true</memberArrayBooleanClass>\n" + " <memberArrayBooleanClass>true</memberArrayBooleanClass>\n"
+ " <memberArrayBooleanClass> true</memberArrayBooleanClass>\n" + " <memberArrayBooleanClass> true</memberArrayBooleanClass>\n"
+ " <memberListByteClass>55 </memberListByteClass>\n"
+ " <memberListByteClass> -53 </memberListByteClass>\n"
+ " <memberListShortClass> 31632</memberListShortClass>\n"
+ " <memberListShortClass>-32100 </memberListShortClass>\n"
+ " <memberListIntegerClass>15612 </memberListIntegerClass>\n"
+ " <memberListIntegerClass> 542 </memberListIntegerClass>\n"
+ " <memberListLongClass>16521 </memberListLongClass>\n"
+ " <memberListLongClass> 4654 </memberListLongClass>\n"
+ " <memberListLongClass>9875546 </memberListLongClass>\n"
+ " <memberListBooleanClass> true</memberListBooleanClass>\n"
+ " <memberListBooleanClass>false </memberListBooleanClass>\n"
+ "</elem>\n"; + "</elem>\n";
//@formatter:on //@formatter:on
final ClassPublicMethodeNode[] root = Assertions.assertDoesNotThrow(() -> Exml.parse(dataToParse, ClassPublicMethodeNode.class, "elem")); final ClassPublicMethodeNode[] root = Assertions.assertDoesNotThrow(() -> Exml.parse(dataToParse, ClassPublicMethodeNode.class, "elem"));

View File

@ -1,5 +1,7 @@
package test.atriasoft.exml.introspection; package test.atriasoft.exml.introspection;
import java.util.List;
import org.atriasoft.exml.annotation.XmlDefaultManaged; import org.atriasoft.exml.annotation.XmlDefaultManaged;
@XmlDefaultManaged(value = false) @XmlDefaultManaged(value = false)
@ -15,6 +17,11 @@ public class ClassPublicMethodeNode {
private Long[] memberArrayLongClass; private Long[] memberArrayLongClass;
private short[] memberArrayShort; private short[] memberArrayShort;
private Short[] memberArrayShortClass; private Short[] memberArrayShortClass;
private List<Boolean> memberListBooleanClass;
private List<Byte> memberListByteClass;
private List<Integer> memberListIntegerClass;
private List<Long> memberListLongClass;
private List<Short> memberListShortClass;
private boolean memberBoolean; private boolean memberBoolean;
private Boolean memberBooleanClass; private Boolean memberBooleanClass;
private byte memberByte; private byte memberByte;
@ -27,6 +34,50 @@ public class ClassPublicMethodeNode {
private Short memberShortClass; private Short memberShortClass;
private String memberStringClass; private String memberStringClass;
public List<Boolean> getMemberListBooleanClass() {
return memberListBooleanClass;
}
public void setMemberListBooleanClass(List<Boolean> memberListBooleanClass) {
this.memberListBooleanClass = memberListBooleanClass;
}
public List<Byte> getMemberListByteClass() {
return memberListByteClass;
}
public void setMemberListByteClass(List<Byte> memberListByteClass) {
this.memberListByteClass = memberListByteClass;
}
public List<Integer> getMemberListIntegerClass() {
return memberListIntegerClass;
}
public void setMemberListIntegerClass(List<Integer> memberListIntegerClass) {
this.memberListIntegerClass = memberListIntegerClass;
}
public List<Long> getMemberListLongClass() {
return memberListLongClass;
}
public void setMemberListLongClass(List<Long> memberListLongClass) {
this.memberListLongClass = memberListLongClass;
}
public List<Short> getMemberListShortClass() {
return memberListShortClass;
}
public void setMemberListShortClass(List<Short> memberListShortClass) {
this.memberListShortClass = memberListShortClass;
}
public Boolean getMemberBooleanClass() {
return memberBooleanClass;
}
public boolean[] getMemberArrayBoolean() { public boolean[] getMemberArrayBoolean() {
return this.memberArrayBoolean; return this.memberArrayBoolean;
} }