[DEV] continue integration

This commit is contained in:
Edouard DUPIN 2021-07-02 23:41:02 +02:00
parent 7ef59f2f7e
commit 956f78642b
19 changed files with 1094 additions and 566 deletions

View File

@ -5,6 +5,7 @@
*/
open module org.atriasoft.exml {
exports org.atriasoft.eStringSerialize;
exports org.atriasoft.exml;
exports org.atriasoft.exml.model;
exports org.atriasoft.exml.exception;

View File

@ -0,0 +1,22 @@
package org.atriasoft.eStringSerialize;
public interface Converter {
/**
* Un-serialize a String in a specified Object
* @param value String to parse
* @return Data generated or Null
*/
Object valueOf(final String value);
/**
* Serialize in a string the require data
* @param data Object to serialize
* @return The new data...
*/
String toString(final Object data);
/**
* Serialize in a string the require data
* @param data Object to serialize
* @return The new data...
*/
String[] toStringList(final Object data);
}

View File

@ -0,0 +1,475 @@
package org.atriasoft.eStringSerialize;
import java.util.HashMap;
import java.util.Map;
import org.atriasoft.exml.parser.Tools;
public class StringSerializer {
private static final Map<Class<?>, Converter> VALUES_OF = new HashMap<>();
static {
StringSerializer.VALUES_OF.put(byte.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Byte.valueOf(value);
}
@Override
public String toString(final Object data) {
return Byte.toString((Byte)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(Byte.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Byte.valueOf(value);
}
@Override
public String toString(final Object data) {
return Byte.toString((Byte)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(int.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Integer.valueOf(value);
}
@Override
public String toString(final Object data) {
return Integer.toString((Integer)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(Integer.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Integer.valueOf(value);
}
@Override
public String toString(final Object data) {
return Integer.toString((Integer)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(long.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Long.valueOf(value);
}
@Override
public String toString(final Object data) {
return Long.toString((Long)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(Long.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Long.valueOf(value);
}
@Override
public String toString(final Object data) {
return Long.toString((Long)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(short.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Short.valueOf(value);
}
@Override
public String toString(final Object data) {
return Short.toString((Short)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(Short.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Short.valueOf(value);
}
@Override
public String toString(final Object data) {
return Short.toString((Short)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(boolean.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Boolean.valueOf(value);
}
@Override
public String toString(final Object data) {
return Boolean.toString((Boolean)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(Boolean.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Boolean.valueOf(value);
}
@Override
public String toString(final Object data) {
return Boolean.toString((Boolean)data);
}
@Override
public String[] toStringList(final Object data) {
return new String[] { toString(data) };
}
});
StringSerializer.VALUES_OF.put(byte[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseByteStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((byte[])data);
}
@Override
public String[] toStringList(final Object data) {
byte[] dataCast = (byte[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Byte.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(Byte[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseByteClassStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((Byte[])data);
}
@Override
public String[] toStringList(final Object data) {
Byte[] dataCast = (Byte[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Byte.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(short[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseShortStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((short[])data);
}
@Override
public String[] toStringList(final Object data) {
short[] dataCast = (short[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Short.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(Short[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseShortClassStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((Short[])data);
}
@Override
public String[] toStringList(final Object data) {
Short[] dataCast = (Short[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Short.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(int[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseIntegerStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((int[])data);
}
@Override
public String[] toStringList(final Object data) {
int[] dataCast = (int[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Integer.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(Integer[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseIntegerClassStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((Integer[])data);
}
@Override
public String[] toStringList(final Object data) {
Integer[] dataCast = (Integer[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Integer.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(long[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseLongStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((long[])data);
}
@Override
public String[] toStringList(final Object data) {
long[] dataCast = (long[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Long.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(Long[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseLongClassStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((Long[])data);
}
@Override
public String[] toStringList(final Object data) {
Long[] dataCast = (Long[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Long.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(boolean[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseBooleanStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((boolean[])data);
}
@Override
public String[] toStringList(final Object data) {
boolean[] dataCast = (boolean[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Boolean.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(Boolean[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseBooleanClassStringList(value);
}
@Override
public String toString(final Object data) {
return Tools.toString((Boolean[])data);
}
@Override
public String[] toStringList(final Object data) {
Boolean[] dataCast = (Boolean[])data;
String[] out = new String[dataCast.length];
for (int iii=0; iii<dataCast.length; iii++) {
out[iii] = Boolean.toString(dataCast[iii]);
}
return out;
}
});
StringSerializer.VALUES_OF.put(String.class, new Converter() {
@Override
public Object valueOf(final String value) {
return value;
}
@Override
public String toString(final Object data) {
return (String)data;
}
@Override
public String[] toStringList(final Object data) {
return new String[] { (String)data };
}
});
StringSerializer.VALUES_OF.put(String[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return value.split(";");
}
@Override
public String toString(final Object data) {
StringBuilder out = new StringBuilder();
String[] dataCast = (String[])data;
for (int iii=0; iii<dataCast.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(dataCast[iii]);
}
return out.toString();
}
@Override
public String[] toStringList(final Object data) {
return (String[])data;
}
});
}
public static boolean contains(final Class<?> clazz) {
return StringSerializer.VALUES_OF.containsKey(clazz);
}
/**
* Un-serialize a String in a specified Object
* @param value String to parse
* @return Data generated or Null
*/
public static Object valueOf(final Class<?> clazz, final String value) {
if (value == null) {
return null;
}
Converter conv = StringSerializer.VALUES_OF.get(clazz);
return conv.valueOf(value);
}
public static String toString(final byte data) {
return Byte.toString(data);
}
public static String toString(final boolean data) {
return Boolean.toString(data);
}
public static String toString(final int data) {
return Integer.toString(data);
}
public static String toString(final short data) {
return Short.toString(data);
}
public static String toString(final long data) {
return Long.toString(data);
}
/**
* Serialize in a string the require data
* @param data Object to serialize
* @return The new data...
*/
public static String toString(final Object data) {
if (data == null) {
return null;
}
Class<?> clazz = data.getClass();
Converter conv = StringSerializer.VALUES_OF.get(clazz);
return conv.toString(data);
}
public static String[] toStringList(final Object data) {
if (data == null) {
return null;
}
Converter conv = StringSerializer.VALUES_OF.get(data.getClass());
return conv.toStringList(data);
}
private StringSerializer() {}
}

View File

@ -104,8 +104,19 @@ public class Exml {
e.printStackTrace();
return null;
}
}
public static <T> T parseOne(final String data, final Class<T> classType, final String rootNodeName) throws ExmlBuilderException, ExmlParserErrorMulti {
T[] elements = Exml.parse(data, classType, rootNodeName);
if (elements == null || elements.length == 0 ) {
throw new ExmlBuilderException("Error in parsing the file, no node find ...");
}
if (elements.length > 1 ) {
throw new ExmlBuilderException("Error in parsing the file, More than One node find ...");
}
return elements[0];
}
private static String readFile(final Path path, final Charset encoding) throws IOException
{
byte[] encoded = Files.readAllBytes(path);

View File

@ -9,7 +9,7 @@ import org.atriasoft.exml.internal.Log;
public class BuilderIntrospection implements Builder {
// Keep in cach all the object alredy parsed ==> optimize CPU
final Map<Class<?>, IntrospectionData> elements = new HashMap<>();
final Map<Class<?>, 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;
@ -17,15 +17,15 @@ public class BuilderIntrospection implements Builder {
public BuilderIntrospection(final Class<?> classType, final String rootNodeName) throws Exception {
this.rootNodeName = rootNodeName;
this.rootClassType = classType;
this.elements.put(classType, new IntrospectionData(classType, null));
this.elements.put(classType, IntrospectionModelFactory.createModel(classType));
}
IntrospectionData findOrCreate(final Class<?> classType) throws Exception {
IntrospectionData out = this.elements.get(classType);
IntrospectionModel findOrCreate(final Class<?> classType) throws Exception {
IntrospectionModel out = this.elements.get(classType);
if (out != null) {
return out;
}
out = new IntrospectionData(classType);
out = IntrospectionModelFactory.createModel(classType);
this.elements.put(classType, out);
return out;
}
@ -46,11 +46,11 @@ public class BuilderIntrospection implements Builder {
final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
// special case of user request parsing of element with <XXX><value></value>...</XXX>
if (nodeName.equals(introspectionObject.getListNameModel())) {
IntrospectionData inferData = introspectionObject.getDataInterface();
IntrospectionModel inferData = introspectionObject.getDataInterface();
if (inferData.getClassType().isArray()) {
inferData = findOrCreate(inferData.getClassType().getComponentType());
} else if (List.class.isAssignableFrom(inferData.getClassType())) {
inferData = findOrCreate(inferData.getSubClassType());
Log.critical("inferData = findOrCreate(inferData.getSubClassType());");
}
return new IntrospectionObject(inferData);
}
@ -59,7 +59,7 @@ public class BuilderIntrospection implements Builder {
if (introspectionObject.getDataInterface() == null) {
if (nodeName.contentEquals(this.rootNodeName)) {
Log.verbose("Create new class: " + this.rootClassType.getCanonicalName());
final IntrospectionData inferData = findOrCreate(this.rootClassType);
final IntrospectionModel inferData = findOrCreate(this.rootClassType);
return new IntrospectionObject(inferData);
}
// need to add a throw on the node...
@ -71,13 +71,13 @@ public class BuilderIntrospection implements Builder {
// specific case for List ==> need to get the subType in introspection ...
if (!List.class.isAssignableFrom(typeClass)) {
Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionData inferData = findOrCreate(typeClass);
final IntrospectionModel inferData = findOrCreate(typeClass);
// Create the data when object is ended created...
return new IntrospectionObject(inferData, listTreeName);
}
Class<?> subTypeClass = introspectionObject.getTypeOfSubNodeSubType(nodeName);
Log.verbose("Create new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
final IntrospectionData inferData = findOrCreate(subTypeClass);
final IntrospectionModel inferData = findOrCreate(subTypeClass);
// Create the data when object is ended created...
return new IntrospectionObject(inferData, listTreeName);
}
@ -127,7 +127,7 @@ public class BuilderIntrospection implements Builder {
}
@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;
if (introspectionElementObject.getDataInterface() == null) {
// property on nothing ???
@ -135,7 +135,7 @@ public class BuilderIntrospection implements Builder {
}
final IntrospectionObject introspectionParentObject = (IntrospectionObject) parent;
if (introspectionParentObject.getDataInterface() == null) {
if (tmpname.equals(this.rootNodeName)) {
if (tmpName.equals(this.rootNodeName)) {
// this is the root node ...
Object tmpp = introspectionParentObject.getData();
if( tmpp instanceof List) {
@ -146,6 +146,6 @@ public class BuilderIntrospection implements Builder {
}
return;
}
introspectionParentObject.addObject(tmpname, introspectionElementObject.getData());
introspectionParentObject.addObject(tmpName, introspectionElementObject.getData());
}
}

View File

@ -0,0 +1,68 @@
package org.atriasoft.exml.builder;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
public abstract class IntrospectionModel {
protected static final Boolean DEFAULT_CASE_SENSITIVE = true;
protected static final Boolean DEFAULT_MANAGED = true;
protected static final Boolean DEFAULT_OPTIONAL = false;
protected final Class<?> classType;
public List<IntrospectionProperty> getMethods() {
return null;
}
public List<IntrospectionProperty> getProperties() {
return null;
}
public Class<?> getClassType() {
return this.classType;
}
public IntrospectionModel(final Class<?> classType) {
this.classType = classType;
}
Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
return null;
}
protected List<String> getNodeAvaillable() {
return null;
}
public Object getValueFromText(final String text) throws ExmlBuilderException {
return null;
}
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
public Class<?> getTypeOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException {
return null;
}
public Class<?> getTypeOfSubNodeList(final Object data, final String nodeName) throws ExmlBuilderException {
return null;
}
public String getTreeNameOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException {
return null;
}
public abstract boolean isEndPoint();
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);
public abstract String[] toStringList(final Object data);
}

View File

@ -0,0 +1,50 @@
package org.atriasoft.exml.builder;
import java.util.List;
import java.util.Map;
import org.atriasoft.eStringSerialize.StringSerializer;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelBaseType extends IntrospectionModel {
public IntrospectionModelBaseType(final Class<?> classType) {
super(classType);
}
@Override
Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
throw new ExmlBuilderException("Base type model can not have properties and nodes ... ");
}
@Override
protected List<String> getNodeAvaillable() {
return null;
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
return StringSerializer.valueOf(this.classType, text);
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
@Override
public boolean isEndPoint() {
return true;
}
@Override
public String toString(final Object data) {
return StringSerializer.toString(data);
}
@Override
public String[] toStringList(final Object data) {
return StringSerializer.toStringList(data);
}
}

View File

@ -9,12 +9,12 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.atriasoft.eStringSerialize.StringSerializer;
import org.atriasoft.etk.util.ArraysTools;
import org.atriasoft.exml.annotation.XmlCaseSensitive;
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
@ -29,173 +29,30 @@ import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.parser.Tools;
public class IntrospectionData {
private static final Boolean DEFAULT_CASE_SENSITIVE = true;
private static final Boolean DEFAULT_MANAGED = true;
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 {
IntrospectionData.VALUES_OF.put(byte.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Byte.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(Byte.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Byte.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(int.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Integer.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(Integer.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Integer.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(long.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Long.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(Long.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Long.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(short.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Short.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(Short.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Short.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(boolean.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Boolean.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(Boolean.class, new Converter() {
@Override
public Object valueOf(final String value) {
return Boolean.valueOf(value);
}
});
IntrospectionData.VALUES_OF.put(byte[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseByteStringList(value);
}
});
IntrospectionData.VALUES_OF.put(Byte[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseByteClassStringList(value);
}
});
IntrospectionData.VALUES_OF.put(short[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseShortStringList(value);
}
});
IntrospectionData.VALUES_OF.put(Short[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseShortClassStringList(value);
}
});
IntrospectionData.VALUES_OF.put(int[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseIntegerStringList(value);
}
});
IntrospectionData.VALUES_OF.put(Integer[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseIntegerClassStringList(value);
}
});
IntrospectionData.VALUES_OF.put(long[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseLongStringList(value);
}
});
IntrospectionData.VALUES_OF.put(Long[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseLongClassStringList(value);
}
});
IntrospectionData.VALUES_OF.put(boolean[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseBooleanStringList(value);
}
});
IntrospectionData.VALUES_OF.put(Boolean[].class, new Converter() {
@Override
public Object valueOf(final String value) {
return Tools.parseBooleanClassStringList(value);
}
});
IntrospectionData.VALUES_OF.put(String.class, new Converter() {
@Override
public Object valueOf(final String value) {
return value;
}
});
}
public class IntrospectionModelComplex extends IntrospectionModel {
private final Class<?> classType;
private final Class<?> subClassType; // TODO deprecated
// TODO Optimize this with external object for basic types....
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> properties = new ArrayList<>();
@Override
public List<IntrospectionProperty> getMethods() {
return this.methods;
}
@Override
public List<IntrospectionProperty> getProperties() {
return this.properties;
}
public Class<?> getClassType() {
return this.classType;
}
public Class<?> getSubClassType() {
return this.subClassType;
}
public IntrospectionData(final Class<?> classType) throws ExmlBuilderException {
this(classType, null);
}
public IntrospectionData(final Class<?> classType, final Class<?> subClassType) throws ExmlBuilderException {
public IntrospectionModelComplex(final Class<?> classType) throws ExmlBuilderException {
super(classType);
try {
this.classType = classType;
this.subClassType = subClassType;
final Boolean isDefaultManaged = getIsDefaultManaged(classType, IntrospectionData.DEFAULT_MANAGED);
final Boolean isDefaultOptional = getIsDefaultOptional(classType, IntrospectionData.DEFAULT_OPTIONAL);
final Boolean isDefaultCaseSensitive = getIsDefaultCaseSensitive(classType, IntrospectionData.DEFAULT_CASE_SENSITIVE);
final Boolean isDefaultManaged = getIsDefaultManaged(classType, IntrospectionModel.DEFAULT_MANAGED);
final Boolean isDefaultOptional = getIsDefaultOptional(classType, IntrospectionModel.DEFAULT_OPTIONAL);
final Boolean isDefaultCaseSensitive = getIsDefaultCaseSensitive(classType, IntrospectionModel.DEFAULT_CASE_SENSITIVE);
Log.verbose("Introspect class: '" + classType.getCanonicalName() + "'");
final Constructor<?>[] constructors = this.classType.getConstructors();
Log.verbose(" Constructors: (" + constructors.length + ")");
@ -446,12 +303,16 @@ public class IntrospectionData {
}
}
@Override
Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
Object tmp;
try {
// pb here, can not create a primitive object with the coreect elements... ==> must be generated with a siblist of elements
tmp = this.classType.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
// pb here, can not create a primitive object with the correct elements... ==> must be generated with a siblist of elements
Constructor<?>[] constructors = this.classType.getConstructors();
Object tmp2 = null;
tmp = constructors[0].newInstance(tmp2);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
@ -466,6 +327,7 @@ public class IntrospectionData {
}
@Override
protected List<String> getNodeAvaillable() {
List<String> out = new ArrayList<>();
for (final IntrospectionProperty prop : this.methods) {
@ -804,30 +666,13 @@ public class IntrospectionData {
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 + "' ");
// by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(propertyName);
if (propMethode != null && propMethode.canSetValue()) {
Log.verbose(" ==> find '" + propMethode.getNames());
propMethode.setValue(data, propertyValue);
return;
}
// try with direct field
final IntrospectionProperty propField = findPropertyDescription(propertyName);
if (propField != null && propField.canSetValue()) {
Log.verbose(" ==> find '" + propField.getNames());
propField.setValue(data, propertyValue);
return;
}
throw new ExmlBuilderException("can not find the field '" + propertyName + "'");
}
/**
* Detect a subNode, and ask the type of the node at the parent Class
* @param nodeName Name of the node
* @return Class of the node to create
*/
@Override
public Class<?> getTypeOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException {
Log.error(" nodeType='" + nodeName + "'");
// by default use setter to set the property
@ -845,6 +690,7 @@ public class IntrospectionData {
throw new ExmlBuilderException("can not find the field '" + nodeName + "' availlable: " + getNodeAvaillable());
}
@Override
public Class<?> getTypeOfSubNodeList(final Object data, final String nodeName) throws ExmlBuilderException {
Log.error(" nodeType='" + nodeName + "'");
// by default use setter to set the property
@ -861,6 +707,7 @@ public class IntrospectionData {
}
throw new ExmlBuilderException("can not find the field '" + nodeName + "' availlable: " + getNodeAvaillable());
}
@Override
public String getTreeNameOfSubNode(final Object data, final String nodeName) throws ExmlBuilderException {
Log.error(" nodeType='" + nodeName + "'");
// by default use setter to set the property
@ -879,6 +726,7 @@ public class IntrospectionData {
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
// 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;
@ -889,9 +737,9 @@ public class IntrospectionData {
classTypeLocal = this.classType.getComponentType();
} else if (List.class == this.classType || Collection.class.isAssignableFrom(this.classType)) {
// a generic list ....
if (this.subClassType != null) {
/*if (this.subClassType != null) {
classTypeLocal = this.subClassType;
}
}*/
//Type[] tmpp = this.classType.getGenericInterfaces();
//Class<?>[] tmpp = this.classType.getNestMembers();
//Class<?>[] tmpp = this.classType.getClasses();
@ -912,11 +760,10 @@ public class IntrospectionData {
Log.warning("======>>>>>>> subElement input type : " + classTypeLocal.getCanonicalName());
if (this.valueof == null) {
Converter con = IntrospectionData.VALUES_OF.get(classTypeLocal);
if (con == null) {
if (StringSerializer.contains(classTypeLocal)) {
throw new ExmlBuilderException("function 'valueOf' for '" + classTypeLocal.getCanonicalName() + "' is not defined and not registered for specific type");
}
return con.valueOf(text);
return StringSerializer.valueOf(classTypeLocal, text);
}
try {
return this.valueof.invoke(null, text);
@ -929,6 +776,7 @@ public class IntrospectionData {
}
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
Log.error(" propertyName='" + propertyName + "' propertyValue='" + propertyValue + "' ");
// by default use setter to set the property
@ -945,6 +793,19 @@ public class IntrospectionData {
}
throw new ExmlBuilderException("can not find the field '" + propertyName + "'");
}
@Override
public boolean isEndPoint() {
return false;
}
@Override
public String toString(final Object data) {
return null;
}
@Override
public String[] toStringList(final Object data) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,17 @@
package org.atriasoft.exml.builder;
import org.atriasoft.eStringSerialize.StringSerializer;
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);
}
return new IntrospectionModelComplex(classType);
}
}

View File

@ -9,7 +9,7 @@ import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.internal.Log;
public class IntrospectionObject {
private final IntrospectionData dataInterface;
private final IntrospectionModel dataInterface;
private Object data = null;
private final String listNameModel;
private final Map<String, Object> properties = new HashMap<>();
@ -24,12 +24,12 @@ public class IntrospectionObject {
this.listNameModel = null;
}
public IntrospectionObject(final IntrospectionData dataInterface, final String listNameModel) {
public IntrospectionObject(final IntrospectionModel dataInterface, final String listNameModel) {
this.dataInterface = dataInterface;
this.listNameModel = listNameModel;
}
public IntrospectionObject(final IntrospectionData dataInterface) {
public IntrospectionObject(final IntrospectionModel dataInterface) {
this.dataInterface = dataInterface;
this.listNameModel = null;
}
@ -42,7 +42,7 @@ public class IntrospectionObject {
return this.data;
}
public IntrospectionData getDataInterface() {
public IntrospectionModel getDataInterface() {
return this.dataInterface;
}

View File

@ -1,7 +1,11 @@
package org.atriasoft.exml.builder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.atriasoft.eStringSerialize.StringSerializer;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.parser.Tools;
public abstract class IntrospectionProperty {
protected final Boolean caseSensitive;
@ -47,61 +51,23 @@ public abstract class IntrospectionProperty {
if (value == null) {
return null;
}
if (this.type == byte.class) {
return Byte.toString((byte)value);
if (StringSerializer.contains(this.type)) {
return StringSerializer.toString(value);
}
if (this.type == short.class) {
return Short.toString((short)value);
}
if (this.type == int.class) {
return Integer.toString((int)value);
}
if (this.type == long.class) {
return Long.toString((long)value);
}
if (this.type == boolean.class) {
return Boolean.toString((boolean)value);
}
if (this.type == String.class) {
return (String)value;
}
if (this.type == Byte.class) {
return Byte.toString((Byte)value);
}
if (this.type == Short.class) {
return Short.toString((short)value);
}
if (this.type == Integer.class) {
return Integer.toString((Integer)value);
} else if (this.type == Long.class) {
return Long.toString((Long)value);
} else if (this.type == Boolean.class) {
return Boolean.toString((Boolean)value);
} else if (this.type == byte[].class) {
return Tools.toString((byte[])value);
} else if (this.type == Byte[].class) {
return Tools.toString((Byte[])value);
} else if (this.type == short[].class) {
return Tools.toString((short[])value);
} else if (this.type == Short[].class) {
return Tools.toString((Short[])value);
} else if (this.type == int[].class) {
return Tools.toString((int[])value);
} else if (this.type == Integer[].class) {
return Tools.toString((Integer[])value);
} else if (this.type == long[].class) {
return Tools.toString((long[])value);
} else if (this.type == Long[].class) {
return Tools.toString((Long[])value);
} else if (this.type == boolean[].class) {
return Tools.toString((boolean[])value);
} else if (this.type == Boolean[].class) {
return Tools.toString((Boolean[])value);
} else {
//throw new ExmlBuilderException("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'");
if (value instanceof Collection) {
ArrayList<Object> data = new ArrayList<>((Collection<?>)value);
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.size(); iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data.get(iii).toString());
}
return out.toString();
}
return value.toString();
}
public abstract Object getValue(Object object) throws ExmlBuilderException;
public boolean isCaseSensitive() {
@ -125,13 +91,6 @@ public abstract class IntrospectionProperty {
}
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
@ -147,5 +106,23 @@ public abstract class IntrospectionProperty {
* @throws Exception An error occurred
* @return The object created
*/
protected abstract Object createValue(String value) throws ExmlBuilderException;
protected Object createValue(final String value) throws ExmlBuilderException {
try {
if (StringSerializer.contains(this.type)) {
return StringSerializer.valueOf(this.type, value);
}
if ((this.type != List.class) || !StringSerializer.contains(this.subType)) {
throw new ExmlBuilderException("Can not parse the specific element ... need to introspect and find the 'xxx valueOf(String data);'");
}
ArrayList<Object> out = new ArrayList<>();
for (String elem : value.split(";")) {
out.add(StringSerializer.valueOf(this.subType, elem));
}
return out;
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
}
}
}

View File

@ -5,7 +5,6 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.parser.Tools;
public class IntrospectionPropertyField extends IntrospectionProperty {
private final Field fieldDescription;
@ -54,133 +53,6 @@ public class IntrospectionPropertyField extends IntrospectionProperty {
}
}
@Override
public void setValue(final Object object, final String value) throws ExmlBuilderException {
try {
if (this.type == byte.class) {
final byte data = Byte.parseByte(value);
this.fieldDescription.setByte(object, data);
} else if (this.type == short.class) {
final short data = Short.parseShort(value);
this.fieldDescription.setShort(object, data);
} else if (this.type == int.class) {
final int data = Integer.parseInt(value);
this.fieldDescription.setInt(object, data);
} else if (this.type == long.class) {
final long data = Long.parseLong(value);
this.fieldDescription.setLong(object, data);
} else if (this.type == boolean.class) {
final boolean data = Boolean.parseBoolean(value);
this.fieldDescription.setBoolean(object, data);
} else if (this.type == String.class) {
this.fieldDescription.set(object, value);
} else if (this.type == Byte.class) {
final Byte data = Byte.valueOf(value);
this.fieldDescription.set(object, data);
} else if (this.type == Short.class) {
final Short data = Short.valueOf(value);
this.fieldDescription.set(object, data);
} else if (this.type == Integer.class) {
final Integer data = Integer.valueOf(value);
this.fieldDescription.set(object, data);
} else if (this.type == Long.class) {
final Long data = Long.valueOf(value);
this.fieldDescription.set(object, data);
} else if (this.type == Boolean.class) {
final Boolean data = Boolean.valueOf(value);
this.fieldDescription.set(object, data);
} else if (this.type == byte[].class) {
this.fieldDescription.set(object, Tools.parseByteStringList(value));
} else if (this.type == Byte[].class) {
this.fieldDescription.set(object, Tools.parseByteClassStringList(value));
} else if (this.type == short[].class) {
this.fieldDescription.set(object, Tools.parseShortStringList(value));
} else if (this.type == Short[].class) {
this.fieldDescription.set(object, Tools.parseShortClassStringList(value));
} else if (this.type == int[].class) {
this.fieldDescription.set(object, Tools.parseIntegerStringList(value));
} else if (this.type == Integer[].class) {
this.fieldDescription.set(object, Tools.parseIntegerClassStringList(value));
} else if (this.type == long[].class) {
this.fieldDescription.set(object, Tools.parseLongStringList(value));
} else if (this.type == Long[].class) {
this.fieldDescription.set(object, Tools.parseLongClassStringList(value));
} else if (this.type == boolean[].class) {
this.fieldDescription.set(object, Tools.parseBooleanStringList(value));
} else if (this.type == Boolean[].class) {
this.fieldDescription.set(object, 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 | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
}
}
@Override
protected Object createValue(final String value) throws ExmlBuilderException {
try {
if (this.type == byte.class) {
return Byte.valueOf(value);
}
if (this.type == short.class) {
return Short.valueOf(value);
}
if (this.type == int.class) {
return Integer.valueOf(value);
}
if (this.type == long.class) {
return Long.valueOf(value);
}
if (this.type == boolean.class) {
return Boolean.valueOf(value);
}
if (this.type == String.class) {
return value;
}
if (this.type == Byte.class) {
return Byte.valueOf(value);
}
if (this.type == Short.class) {
return Short.valueOf(value);
}
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(final Object object, final Object value) throws ExmlBuilderException {

View File

@ -8,7 +8,6 @@ import java.util.List;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.parser.Tools;
public class IntrospectionPropertyMethod extends IntrospectionProperty {
private static Class<?>[] getTypefunction(final Method setter, final Method getter) throws Exception {
@ -91,138 +90,6 @@ public class IntrospectionPropertyMethod extends IntrospectionProperty {
}
}
@Override
public void setValue(final Object object, final String value) throws ExmlBuilderException {
if (this.setter == null) {
throw new ExmlBuilderException("no setter availlable");
}
try {
if (this.type == byte.class) {
final byte data = Byte.parseByte(value);
this.setter.invoke(object, data);
} else if (this.type == short.class) {
final short data = Short.parseShort(value);
this.setter.invoke(object, data);
} else if (this.type == int.class) {
final int data = Integer.parseInt(value);
this.setter.invoke(object, data);
} else if (this.type == long.class) {
final long data = Long.parseLong(value);
this.setter.invoke(object, data);
} else if (this.type == boolean.class) {
final boolean data = Boolean.parseBoolean(value);
this.setter.invoke(object, data);
} else if (this.type == String.class) {
this.setter.invoke(object, value);
} else if (this.type == Byte.class) {
final Byte data = Byte.valueOf(value);
this.setter.invoke(object, data);
} else if (this.type == Short.class) {
final Short data = Short.valueOf(value);
this.setter.invoke(object, data);
} else if (this.type == Integer.class) {
final Integer data = Integer.valueOf(value);
this.setter.invoke(object, data);
} else if (this.type == Long.class) {
final Long data = Long.valueOf(value);
this.setter.invoke(object, data);
} else if (this.type == Boolean.class) {
final Boolean data = Boolean.valueOf(value);
this.setter.invoke(object, data);
} else if (this.type == byte[].class) {
this.setter.invoke(object, Tools.parseByteStringList(value));
} else if (this.type == Byte[].class) {
this.setter.invoke(object, (Object) Tools.parseByteClassStringList(value));
} else if (this.type == short[].class) {
this.setter.invoke(object, Tools.parseShortStringList(value));
} else if (this.type == Short[].class) {
this.setter.invoke(object, (Object) Tools.parseShortClassStringList(value));
} else if (this.type == int[].class) {
this.setter.invoke(object, Tools.parseIntegerStringList(value));
} else if (this.type == Integer[].class) {
this.setter.invoke(object, (Object) Tools.parseIntegerClassStringList(value));
} else if (this.type == long[].class) {
this.setter.invoke(object, Tools.parseLongStringList(value));
} else if (this.type == Long[].class) {
this.setter.invoke(object, (Object) Tools.parseLongClassStringList(value));
} else if (this.type == boolean[].class) {
this.setter.invoke(object, Tools.parseBooleanStringList(value));
} else if (this.type == Boolean[].class) {
this.setter.invoke(object, (Object) 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 | IllegalAccessException e) {
// TODO Auto-generated catch block
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(final String value) throws ExmlBuilderException {
try {
if (this.type == byte.class) {
return Byte.valueOf(value);
}
if (this.type == short.class) {
return Short.valueOf(value);
}
if (this.type == int.class) {
return Integer.valueOf(value);
}
if (this.type == long.class) {
return Long.valueOf(value);
}
if (this.type == boolean.class) {
return Boolean.valueOf(value);
}
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(final Object object, final Object value) throws ExmlBuilderException {
if (this.setter == null) {

View File

@ -4,14 +4,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.builder.IntrospectionData;
import org.atriasoft.exml.builder.IntrospectionModel;
import org.atriasoft.exml.builder.IntrospectionModelFactory;
import org.atriasoft.exml.builder.IntrospectionProperty;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.parser.Tools;
public class GeneratorIntrospection implements Generator {
// Keep in cach all the object alredy parsed ==> optimize CPU
final Map<Class<?>, IntrospectionData> elements = new HashMap<>();
final Map<Class<?>, 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;
@ -19,35 +20,40 @@ public class GeneratorIntrospection implements Generator {
public GeneratorIntrospection(final Class<?> classType, final String rootNodeName) throws Exception {
this.rootNodeName = rootNodeName;
this.rootClassType = classType;
this.elements.put(classType, new IntrospectionData(classType, null));
this.elements.put(classType, IntrospectionModelFactory.createModel(classType));
}
IntrospectionData findOrCreate(final Class<?> classType) throws ExmlBuilderException {
IntrospectionData out = this.elements.get(classType);
IntrospectionModel findOrCreate(final Class<?> classType) throws ExmlBuilderException {
IntrospectionModel out = this.elements.get(classType);
if (out != null) {
return out;
}
out = new IntrospectionData(classType);
out = IntrospectionModelFactory.createModel(classType);
this.elements.put(classType, out);
return out;
}
public void generateProperties(final Object data, final IntrospectionData introspection, final StringBuilder tmpp) throws ExmlBuilderException {
public void generateProperties(final Object data, final IntrospectionModel introspection, final StringBuilder tmpp) throws ExmlBuilderException {
List<IntrospectionProperty> elements = introspection.getProperties();
if (elements == null) {
return;
}
for (IntrospectionProperty elem : elements) {
if (!elem.canGetValue()) {
continue;
}
String name = elem.getNames()[0];
String dataString=elem.getValueString(data);
tmpp.append(" ");
tmpp.append(name);
tmpp.append("=\"");
tmpp.append(dataString);
tmpp.append("\"");
if (dataString != null) {
String name = elem.getNames()[0];
tmpp.append(" ");
tmpp.append(name);
tmpp.append("=\"");
tmpp.append(dataString);
tmpp.append("\"");
}
}
}
public void generateSubNodes(final Object data, final IntrospectionData introspection, final StringBuilder tmpp, int indent) throws ExmlBuilderException {
public void generateSubNodes(final Object data, final IntrospectionModel introspection, final StringBuilder tmpp, final int indent) throws ExmlBuilderException {
List<IntrospectionProperty> elements = introspection.getMethods();
for (IntrospectionProperty elem : elements) {
if (!elem.canGetValue()) {
@ -56,28 +62,65 @@ public class GeneratorIntrospection implements Generator {
String name = elem.getNames()[0];
Object dataObj =elem.getValue(data);
if (dataObj != null) {
if (dataObj == null) {
continue;
}
Class<?> type = elem.getType();
generateNode(dataObj, name, tmpp, indent);
/*
if (List.class.isAssignableFrom(type)) {
// special case for List ...
type = elem.getSubType();
generateNodeList(dataObj, name, tmpp, indent);
} else {
generateNode(dataObj, name, tmpp, indent);
}
*/
}
}
public void generateNode(final Object data, final String nodeName, final StringBuilder tmpp, int indent) throws ExmlBuilderException {
IntrospectionData introspection = findOrCreate(data.getClass());
Tools.addIndent(tmpp, indent);
tmpp.append("<");
tmpp.append(nodeName);
generateProperties(data, introspection, tmpp);
if (introspection.getMethods().size() != 0) {
tmpp.append(">\n");
generateSubNodes(data, introspection, tmpp, indent + 1);
Tools.addIndent(tmpp, indent);
tmpp.append("</");
tmpp.append(nodeName);
tmpp.append(">\n");
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);
for (int iii=0; iii<listDatas.length; iii++) {
Tools.addIndent(tmpp, indent);
tmpp.append("<");
tmpp.append(nodeName);
tmpp.append(">");
tmpp.append(listDatas[iii]);
tmpp.append("</");
tmpp.append(nodeName);
tmpp.append(">");
}
} else {
Tools.addIndent(tmpp, indent);
tmpp.append("<");
tmpp.append(nodeName);
tmpp.append(">");
tmpp.append(introspection.toString(data));
tmpp.append("</");
tmpp.append(nodeName);
tmpp.append(">");
}
} else {
tmpp.append("/>\n");
Tools.addIndent(tmpp, indent);
tmpp.append("<");
tmpp.append(nodeName);
generateProperties(data, introspection, tmpp);
if (introspection.getMethods().size() != 0) {
tmpp.append(">");
generateSubNodes(data, introspection, tmpp, indent + 1);
Tools.addIndent(tmpp, indent);
tmpp.append("</");
tmpp.append(nodeName);
tmpp.append(">");
} else {
tmpp.append("/>");
}
}
}
public void generate(final Object root, final StringBuilder tmpp) throws ExmlBuilderException {
generateNode(root, this.rootNodeName, tmpp, 0);

View File

@ -7,6 +7,9 @@ public class Tools {
* @param indent Number of tab to add at the string.
*/
public static void addIndent(final StringBuilder data, final int indent) {
if (!data.isEmpty()) {
data.append("\n");
}
for (int iii = 0; iii < indent; iii++) {
data.append("\t");
}
@ -159,7 +162,7 @@ public class Tools {
}
return out;
}
public static String toString(Boolean[] data) {
public static String toString(final Boolean[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -180,7 +183,7 @@ public class Tools {
}
return out;
}
public static String toString(boolean[] data) {
public static String toString(final boolean[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -202,7 +205,7 @@ public class Tools {
return out;
}
public static String toString(Byte[] data) {
public static String toString(final Byte[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -223,7 +226,7 @@ public class Tools {
}
return out;
}
public static String toString(byte[] data) {
public static String toString(final byte[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -244,7 +247,7 @@ public class Tools {
}
return out;
}
public static String toString(Integer[] data) {
public static String toString(final Integer[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -265,7 +268,7 @@ public class Tools {
}
return out;
}
public static String toString(int[] data) {
public static String toString(final int[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -286,7 +289,7 @@ public class Tools {
}
return out;
}
public static String toString(Long[] data) {
public static String toString(final Long[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -307,7 +310,7 @@ public class Tools {
}
return out;
}
public static String toString(long[] data) {
public static String toString(final long[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -329,7 +332,7 @@ public class Tools {
return out;
}
public static String toString(Short[] data) {
public static String toString(final Short[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {
@ -350,7 +353,7 @@ public class Tools {
}
return out;
}
public static String toString(short[] data) {
public static String toString(final short[] data) {
StringBuilder out = new StringBuilder();
for (int iii=0; iii<data.length; iii++) {
if (iii != 0) {

View File

@ -46,7 +46,7 @@ public class SerializerXml {
Tools.addIndent(data, indent);
data.append("<!--");
data.append(comment.getValue());
data.append("-->\n");
data.append("-->");
}
private static void serializeDeclaration(final XmlDeclaration declaration, final StringBuilder data, final int indent) {
@ -54,7 +54,7 @@ public class SerializerXml {
data.append("<?");
data.append(declaration.getValue());
SerializerXml.serializeAttributeList(declaration, data, indent);
data.append("?>\n");
data.append("?>");
}
@ -72,7 +72,7 @@ public class SerializerXml {
SerializerXml.serialize(nodes.get(0), data, 0);
Log.verbose(" generate : '" + data + "'");
} else {
data.append(">\n");
data.append(">");
for (XmlNode node : nodes) {
if (node != null) {
SerializerXml.serialize(node, data, indent + 1);
@ -82,9 +82,9 @@ public class SerializerXml {
}
data.append("</");
data.append(element.getValue());
data.append(">\n");
data.append(">");
} else {
data.append("/>\n");
data.append("/>");
}
}

View File

@ -0,0 +1,211 @@
/** @file
* @author Edouard DUPIN
* @copyright 2021, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
package test.atriasoft.exml;
import java.util.List;
import org.atriasoft.exml.Exml;
import org.atriasoft.exml.annotation.XmlDefaultAttibute;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class ExmlTestIntrospectionBoolean {
static final String NODE_NAME = "elem";
@BeforeAll
public static void beforeClass() {
Log.warning("================================================================");
}
@XmlDefaultAttibute
public class TestBoolean {
public Boolean valueA;
public Boolean valueB;
public Boolean valueNull;
}
@Test
public void testModelBoolean() {
TestBoolean elem = new TestBoolean();
elem.valueA = false;
elem.valueB = true;
elem.valueNull = null;
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
String dataTest = builder.toString();
Log.warning("data generated: " + builder.toString());
Assertions.assertEquals("<elem valueA=\"false\" valueB=\"true\"/>", dataTest);
final TestBoolean root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestBoolean.class, ExmlTestIntrospectionBoolean.NODE_NAME));
Assertions.assertEquals(false, root.valueA);
Assertions.assertEquals(true, root.valueB);
Assertions.assertEquals(null, root.valueNull);
}
@XmlDefaultAttibute
public class TestArrayBoolean {
public Boolean[] values;
}
@Test
public void testModelArrayBoolean() {
TestArrayBoolean elem = new TestArrayBoolean();
elem.values = new Boolean[] {false, false, true, false, true};
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
String dataTest = builder.toString();
Log.warning("data generated: " + builder.toString());
Assertions.assertEquals("<elem values=\"false;false;true;false;true\"/>", dataTest);
final TestArrayBoolean root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestArrayBoolean.class, ExmlTestIntrospectionBoolean.NODE_NAME));
Assertions.assertEquals(5, root.values.length);
Assertions.assertEquals(false, root.values[0]);
Assertions.assertEquals(false, root.values[1]);
Assertions.assertEquals(true, root.values[2]);
Assertions.assertEquals(false, root.values[3]);
Assertions.assertEquals(true, root.values[4]);
}
@XmlDefaultAttibute
public class TestListBoolean {
public List<Boolean> values;
}
@Test
public void testModelListBoolean() {
TestListBoolean elem = new TestListBoolean();
elem.values = List.of(false, false, true, false, true);
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
String dataTest = builder.toString();
Log.warning("data generated: " + builder.toString());
Assertions.assertEquals("<elem values=\"false;false;true;false;true\"/>", dataTest);
final TestListBoolean root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestListBoolean.class, ExmlTestIntrospectionBoolean.NODE_NAME));
Assertions.assertEquals(5, root.values.size());
Assertions.assertEquals(false, root.values.get(0));
Assertions.assertEquals(false, root.values.get(1));
Assertions.assertEquals(true, root.values.get(2));
Assertions.assertEquals(false, root.values.get(3));
Assertions.assertEquals(true, root.values.get(4));
}
@XmlDefaultAttibute
public class TestBooleanFunc {
private Boolean valueA;
private Boolean valueB;
private Boolean valueNull;
public Boolean getValueA() {
return this.valueA;
}
public void setValueA(final Boolean valueA) {
this.valueA = valueA;
}
public Boolean getValueB() {
return this.valueB;
}
public void setValueB(final Boolean valueB) {
this.valueB = valueB;
}
public Boolean getValueNull() {
return this.valueNull;
}
public void setValueNull(final Boolean valueNull) {
this.valueNull = valueNull;
}
}
@Test
public void testModelBooleanFunc() {
TestBooleanFunc elem = new TestBooleanFunc();
elem.setValueA(false);
elem.setValueB(true);
elem.setValueNull(null);
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
String dataTest = builder.toString();
Log.warning("data generated: " + builder.toString());
Assertions.assertEquals("<elem valueA=\"false\" valueB=\"true\"/>", dataTest);
final TestBooleanFunc root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestBooleanFunc.class, ExmlTestIntrospectionBoolean.NODE_NAME));
Assertions.assertEquals(false, root.getValueA());
Assertions.assertEquals(true, root.getValueB());
Assertions.assertEquals(null, root.getValueNull());
}
@XmlDefaultAttibute
public class TestArrayBooleanFunc {
private Boolean[] values;
public Boolean[] getValues() {
return this.values;
}
public void setValues(final Boolean[] values) {
this.values = values;
}
}
@Test
public void testModelArrayBooleanFunc() {
TestArrayBooleanFunc elem = new TestArrayBooleanFunc();
elem.setValues(new Boolean[] {false, false, true, false, true});
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
String dataTest = builder.toString();
Log.warning("data generated: " + builder.toString());
Assertions.assertEquals("<elem values=\"false;false;true;false;true\"/>", dataTest);
final TestArrayBooleanFunc root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestArrayBooleanFunc.class, ExmlTestIntrospectionBoolean.NODE_NAME));
Assertions.assertEquals(5, root.getValues().length);
Assertions.assertEquals(false, root.getValues()[0]);
Assertions.assertEquals(false, root.getValues()[1]);
Assertions.assertEquals(true, root.getValues()[2]);
Assertions.assertEquals(false, root.getValues()[3]);
Assertions.assertEquals(true, root.getValues()[4]);
}
@XmlDefaultAttibute
public class TestListBooleanFunc {
private List<Boolean> values;
public List<Boolean> getValues() {
return this.values;
}
public void setValues(final List<Boolean> values) {
this.values = values;
}
}
@Test
public void testModelListBooleanFunc() {
TestListBooleanFunc elem = new TestListBooleanFunc();
elem.setValues(List.of(false, false, true, false, true));
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
String dataTest = builder.toString();
Log.warning("data generated: " + builder.toString());
Assertions.assertEquals("<elem values=\"false;false;true;false;true\"/>", dataTest);
final TestListBooleanFunc root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestListBooleanFunc.class, ExmlTestIntrospectionBoolean.NODE_NAME));
Assertions.assertEquals(5, root.getValues().size());
Assertions.assertEquals(false, root.getValues().get(0));
Assertions.assertEquals(false, root.getValues().get(1));
Assertions.assertEquals(true, root.getValues().get(2));
Assertions.assertEquals(false, root.getValues().get(3));
Assertions.assertEquals(true, root.getValues().get(4));
}
}

View File

@ -0,0 +1,49 @@
/** @file
* @author Edouard DUPIN
* @copyright 2021, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
package test.atriasoft.exml;
import org.atriasoft.exml.Exml;
import org.atriasoft.exml.annotation.XmlDefaultAttibute;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class ExmlTestIntrospectionBooleanNative {
private static final String NODE_NAME = "elem";
@BeforeAll
public static void beforeClass() {
Log.verbose("----------------------------------------------------------------");
}
@XmlDefaultAttibute
public class TestArrayBooleanNative {
public boolean[] values;
}
@Test
public void testModelArrayBooleanNative() {
TestArrayBooleanNative elem = new TestArrayBooleanNative();
elem.values = new boolean[] {false, false, true, false, true};
StringBuilder builder = new StringBuilder();
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionBoolean.NODE_NAME, builder));
final String dataTest = builder.toString();
Assertions.assertEquals("<elem values=\"false;true\"/>", dataTest);
Log.warning("data generated: " + builder.toString());
final TestArrayBooleanNative root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, TestArrayBooleanNative.class, ExmlTestIntrospectionBooleanNative.NODE_NAME));
Assertions.assertEquals(1, root.values.length);
Assertions.assertEquals(false, root.values[0]);
Assertions.assertEquals(false, root.values[1]);
Assertions.assertEquals(true, root.values[2]);
Assertions.assertEquals(false, root.values[3]);
Assertions.assertEquals(true, root.values[4]);
}
}

View File

@ -17,6 +17,7 @@ import test.atriasoft.exml.introspection.ClassPublicMethodOnly;
import test.atriasoft.exml.introspection.ClassPublicMethodeNode;
public class ExmlTestIntrospectionGenerate {
private static final String NODE_NAME = "elem";
@BeforeAll
public static void beforeClass() {
Log.verbose("----------------------------------------------------------------");