[DEV] add basic annitation and first introspection with attribute works.

This commit is contained in:
Edouard DUPIN 2021-02-27 01:29:38 +01:00
parent f610c366ba
commit 240b71805e
20 changed files with 996 additions and 13 deletions

View File

@ -10,7 +10,10 @@ open module org.atriasoft.exml {
exports org.atriasoft.exml.exception;
exports org.atriasoft.exml.builder;
exports org.atriasoft.exml.parser;
exports org.atriasoft.exml.annotation;
requires transitive org.atriasoft.etk;
requires transitive io.scenarium.logger;
requires java.base;
}

View File

@ -6,8 +6,13 @@
package org.atriasoft.exml;
import java.lang.reflect.Array;
import java.util.List;
import org.atriasoft.exml.builder.Builder;
import org.atriasoft.exml.builder.BuilderGeneric;
import org.atriasoft.exml.builder.BuilderIntrospection;
import org.atriasoft.exml.builder.IntrospectionObject;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
import org.atriasoft.exml.internal.Log;
@ -27,17 +32,19 @@ public class Exml {
Log.info("Generated XML : \n" + tmpp.toString());
}
public static void generate(final Object root, final StringBuilder data) {
// TODO: ...
}
/**
* generate a string that contain the created XML
* @param[out] _data Data where the xml is stored
* @return false : An error occured
* @return true : Parsing is OK
* Generate a string that contain the created XML
* @param data Data where the xml is stored
*/
public static void generate(final XmlNode root, final StringBuilder _data) {
public static void generate(final XmlNode root, final StringBuilder data) {
if (root.isElement() == false || ((XmlElement) root).getValue().isEmpty() == false) {
SerializerXml.serialize(root, _data, 0);
SerializerXml.serialize(root, data, 0);
} else {
SerializerXml.serializeRoot((XmlElement) root, _data);
SerializerXml.serializeRoot((XmlElement) root, data);
}
//return iGenerate(_data, 0);
}
@ -50,6 +57,23 @@ public class Exml {
return (XmlElement) parser.parse(data, property);
}
public static <TYPE> TYPE[] parse(final String data, final Class<TYPE> classType, final String rootNodeName) throws ExmlBuilderException, ExmlParserErrorMulti {
final Builder builder = new BuilderIntrospection(classType, rootNodeName);
final ParseXml parser = new ParseXml(builder);
final ParsingProperty property = new ParsingProperty();
property.setDisplayError(true);
final IntrospectionObject introspectionObject = (IntrospectionObject) parser.parse(data, property);
final Object listRet = introspectionObject.getData();
if (listRet != null && listRet instanceof List) {
final List<TYPE> rootList = (List<TYPE>) listRet;
final TYPE[] strarr = (TYPE[]) Array.newInstance(classType, 0);
return rootList.toArray(strarr);
} else {
return null;
}
}
/**
* Load the file that might contain the xml
* @param[in] _uri URI of the xml

View File

@ -0,0 +1,19 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Meta-annotation (annotations used on other annotations)
* used for marking all annotations that are
* part of Exml package. Can be used for recognizing all
* Exml annotations generically, and in future also for
* passing other generic annotation configuration.
*/
@Target({ ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExmlAnnotation {
// for now, a pure tag annotation, no parameters
}

View File

@ -0,0 +1,16 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation that set the element are not managed by default. Need to add @XmlManaged to be enable.
*
*/
@Target({ ElementType.MODULE })
@Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation
public @interface XmlDefaultNotManaged {
}

View File

@ -0,0 +1,16 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation that set the element not found are ignored.
*
*/
@Target({ ElementType.MODULE })
@Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation
public @interface XmlDefaultOptional {
}

View File

@ -0,0 +1,16 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation that force the xml Parser to manage this element (used when the class is mark as @XmldefaultNotManaged).
*
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation
public @interface XmlManaged {
}

View File

@ -0,0 +1,28 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation that can be used to define an other name of the attribute or the Element name.
*
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation
public @interface XmlName {
/**
* Set if the element has a specific case sensitivity (if the full parsing is case insensitive, this change nothing)
* @return true if the element is case insensitive.
*/
boolean caseSensitive() default true;
/**
* Names of the property of the Element name
* @note The first name if the default generated in serialization.
* @return The list the the possible names
*/
String[] names();
}

View File

@ -0,0 +1,16 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation that Permit to ignore the function or the attribute.
*
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation
public @interface XmlNotManaged {
}

View File

@ -0,0 +1,16 @@
package org.atriasoft.exml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation that to ignore the element if not present in the XML, the default case the parser throw a missing error.
*
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation
public @interface XmlOptional {
}

View File

@ -0,0 +1,96 @@
package org.atriasoft.exml.builder;
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 BuilderIntrospection implements Builder {
// Keep in cach all the object alredy parsed ==> optimize CPU
final Map<Class<?>, IntrospectionData> elements = new HashMap<>();
// The root class (need to keep it if we use 2 time the builder, the root class is no more accessible).
final Class<?> rootClassType;
final String rootNodeName;
public BuilderIntrospection(final Class<?> classType, final String rootNodeName) {
this.rootNodeName = rootNodeName;
this.rootClassType = classType;
this.elements.put(classType, new IntrospectionData(classType));
}
IntrospectionData findOrCreate(final Class<?> classType) {
IntrospectionData out = this.elements.get(classType);
if (out != null) {
return out;
}
out = new IntrospectionData(classType);
this.elements.put(classType, out);
return out;
}
@Override
public void newComment(final Object element, final String comment) throws ExmlBuilderException {
// we drop all comment, we have no need of it.
return;
}
@Override
public Object newDeclaration(final Object parent, final String text) throws ExmlBuilderException {
// we drop all declaration, no need of it too.
return null;
}
@Override
public Object newElement(final Object parent, final String nodeName) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
if (introspectionObject.getDataInterface() == null) {
final Object previousData = introspectionObject.getData();
if (previousData != null && previousData instanceof List) {
final List<Object> rootList = (List<Object>) previousData;
// detect root node...
if (nodeName.contentEquals(this.rootNodeName)) {
Log.verbose("Create new class: " + this.rootClassType.getCanonicalName());
final IntrospectionData inferData = findOrCreate(this.rootClassType);
final Object newElement = inferData.createObject();
rootList.add(newElement);
return new IntrospectionObject(inferData, newElement);
} else {
// need to add a throw on the node...
return null; // ==> disable the parsing..
}
} else {
// throw an error...
return null;
}
} else {
}
return null;
}
@Override
public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) element;
if (introspectionObject.getDataInterface() == null) {
// property on nothing ???
return;
}
introspectionObject.setProperty(propertyName, propertyValue);
}
@Override
public Object newRoot() throws ExmlBuilderException {
return new IntrospectionObject();
}
@Override
public void newText(final Object parent, final String text) throws ExmlBuilderException {
final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
}
}

View File

@ -0,0 +1,89 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.atriasoft.exml.internal.Log;
public class IntrospectionData {
final Class<?> classType;
private final List<IntrospectionProperty> properties = new ArrayList<>();
public IntrospectionData(final Class<?> classType) {
this.classType = classType;
Log.info("Introspect class: '" + classType.getCanonicalName() + "'");
final Constructor<?>[] constructors = this.classType.getConstructors();
Log.info(" Constructors: (" + constructors.length + ")");
for (final Constructor<?> elem : constructors) {
Log.info(" - " + elem.toGenericString());
}
final Field[] fields = this.classType.getFields();
Log.info(" Fields: (" + fields.length + ")");
for (final Field elem : fields) {
// TODO: check if property does not already exist ...
this.properties.add(new IntrospectionPropertyField(elem));
Log.info(" - " + elem.toGenericString());
}
final Method[] methodsTmp = this.classType.getMethods();
final List<Method> methods = List.of(methodsTmp).stream().filter(o -> {
return (o.getName().startsWith("get") || o.getName().startsWith("set") || o.getName().startsWith("is")) && !o.getName().contentEquals("getClass");
}).collect(Collectors.toList());
// separate the methods...
final List<Method> methodsGet = methods.stream().filter(o -> {
return o.getName().startsWith("get");
}).collect(Collectors.toList());
final List<Method> methodsSet = methods.stream().filter(o -> {
return o.getName().startsWith("set");
}).collect(Collectors.toList());
final List<Method> methodsIs = methods.stream().filter(o -> {
return o.getName().startsWith("is");
}).collect(Collectors.toList());
// associate methods by pair.
// nameProperty, getter, setter
Log.info(" Methods: (" + methods.size() + ")");
for (final Method elem : methods) {
Log.info(" - " + elem.toGenericString());
}
}
Object createObject() {
try {
return this.classType.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
protected IntrospectionProperty findPropertyDescription(final String propertyName) throws Exception {
for (final IntrospectionProperty prop : this.properties) {
if (prop.isCompatible(propertyName) == true) {
return prop;
}
}
Log.error("lkjlkjlkjlkj");
throw new Exception("lkjlkjlk");
}
public void setProperty(final Object data, final String propertyName, final String propertyValue) {
try {
final IntrospectionProperty prop = findPropertyDescription(propertyName);
prop.setValue(data, propertyValue);
} catch (final Exception e) {
Log.error("can not find the field '" + propertyName + "' " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,34 @@
package org.atriasoft.exml.builder;
import java.util.ArrayList;
public class IntrospectionObject {
private final IntrospectionData dataInterface;
private final Object data;
/**
* 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 ...
*/
public IntrospectionObject() {
this.dataInterface = null;
this.data = new ArrayList<>();
}
public IntrospectionObject(final IntrospectionData dataInterface, final Object data) {
this.dataInterface = dataInterface;
this.data = data;
}
public Object getData() {
return this.data;
}
public IntrospectionData getDataInterface() {
return this.dataInterface;
}
public void setProperty(final String propertyName, final String propertyValue) {
this.dataInterface.setProperty(this.data, propertyName, propertyValue);
}
}

View File

@ -0,0 +1,56 @@
package org.atriasoft.exml.builder;
import java.util.ArrayList;
import java.util.List;
public abstract class IntrospectionProperty {
protected List<String> names = new ArrayList<>();
protected boolean caseSensitive = true;
protected final Class<?> type;
public IntrospectionProperty(final Class<?> type) {
this.type = type;
}
public List<String> getNames() {
return this.names;
}
public Class<?> getType() {
return this.type;
}
public abstract String getValue(Object object);
public boolean isCaseSensitive() {
return this.caseSensitive;
}
public boolean isCompatible(String name) {
if (this.caseSensitive == false) {
for (final String elem : this.names) {
if (elem.contentEquals(name) == true) {
return true;
}
}
} else {
name = name.toLowerCase();
for (final String elem : this.names) {
if (elem.toLowerCase().contentEquals(name) == true) {
return true;
}
}
}
return false;
}
public void setCaseSensitive(final boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
public void setNames(final List<String> names) {
this.names = names;
}
public abstract void setValue(Object object, String value);
}

View File

@ -0,0 +1,87 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.Field;
import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.parser.Tools;
public class IntrospectionPropertyField extends IntrospectionProperty {
private final Field fieldDescription;
public IntrospectionPropertyField(final Field fieldDescription) {
super(fieldDescription.getType());
this.fieldDescription = fieldDescription;
this.names.add(this.fieldDescription.getName());
}
@Override
public String getValue(final Object object) {
// TODO Auto-generated method stub
return null;
}
@Override
public void setValue(final Object object, final String value) {
try {
if (this.type == byte.class) {
final byte data = Byte.valueOf(value);
this.fieldDescription.setByte(object, data);
} else if (this.type == short.class) {
final short data = Short.valueOf(value);
this.fieldDescription.setShort(object, data);
} else if (this.type == int.class) {
final int data = Integer.valueOf(value);
this.fieldDescription.setInt(object, data);
} else if (this.type == long.class) {
final long data = Long.valueOf(value);
this.fieldDescription.setLong(object, data);
} else if (this.type == boolean.class) {
final boolean data = Boolean.valueOf(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 {
Log.error("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();
}
}
}

View File

@ -16,7 +16,7 @@ public class XmlDeclaration extends XmlAttributeList {
};
/**
* Constructor
* Constructor
* @param[in] _name name of the declaration (xml, xml:xxxx ...)
*/
public XmlDeclaration(final String _name) {

View File

@ -9,8 +9,8 @@ package org.atriasoft.exml.model;
* Basic main object of all xml elements.
*/
public abstract class XmlNode {
/// Value of the node (for element this is the name, for text it is the inside text ...);
protected String value = "";
/// Value of the node (for element this is the name, for text it is the inside text ...)(null for the root element);
protected String value = null;
/**
* basic element of a xml structure
@ -22,14 +22,14 @@ public abstract class XmlNode {
* @param[in] _value value of the node
*/
public XmlNode(final String _value) {
this.value = _value;
setValue(_value);
}
/**
* Clear the Node
*/
public void clear() {
this.value = "";
this.value = null;
}
@Override
@ -88,7 +88,11 @@ public abstract class XmlNode {
* @param[in] _value New value of the node.
*/
public final void setValue(final String _value) {
this.value = _value;
if (_value.isEmpty() == true || _value.isBlank() == true) {
this.value = null;
} else {
this.value = _value;
}
}
/**

View File

@ -36,6 +36,10 @@ public class Tools {
return true;
}
public static String cleanNumberList(final String data) {
return data.replaceAll("[ \t\n\r]", "").replaceAll(",", ";");
}
/**
* count the number of white char in the string from the specify position (stop at the first element that is not a white char)
* @param[in] _data Data to parse.
@ -128,6 +132,116 @@ public class Tools {
return false;
}
public static Boolean[] parseBooleanClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final Boolean[] out = new Boolean[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Boolean.valueOf(str);
}
return out;
}
public static boolean[] parseBooleanStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final boolean[] out = new boolean[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Boolean.valueOf(str);
}
return out;
}
public static Byte[] parseByteClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final Byte[] out = new Byte[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Byte.parseByte(str);
}
return out;
}
public static byte[] parseByteStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final byte[] out = new byte[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Byte.parseByte(str);
}
return out;
}
public static Integer[] parseIntegerClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final Integer[] out = new Integer[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Integer.parseInt(str);
}
return out;
}
public static int[] parseIntegerStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final int[] out = new int[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Integer.parseInt(str);
}
return out;
}
public static Long[] parseLongClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final Long[] out = new Long[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Long.parseLong(str);
}
return out;
}
public static long[] parseLongStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final long[] out = new long[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Long.parseLong(str);
}
return out;
}
public static Short[] parseShortClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final Short[] out = new Short[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Short.parseShort(str);
}
return out;
}
public static short[] parseShortStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data);
final String dataArray[] = data.split(";");
final short[] out = new short[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Short.parseShort(str);
}
return out;
}
// transform the Text with :
// "&lt;" == "<"
// "&gt;" == ">"

View File

@ -0,0 +1,131 @@
/** @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.Arrays;
import org.atriasoft.exml.Exml;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import test.atriasoft.exml.introspection.ClassPublicMemberOnly;
import test.atriasoft.exml.introspection.ClassPublicMethodOnly;
public class ExmlTestIntrospection {
@BeforeAll
public static void beforeClass() {
Log.verbose("----------------------------------------------------------------");
}
@Test
public void test1() throws ExmlParserErrorMulti, ExmlBuilderException {
//@formatter:off
final String dataToParse = "<elem\n"
+ " memberByte=\"12\"\n"
+ " memberShort=\"1223\"\n"
+ " memberInteger=\"4541542\"\n"
+ " memberLong = \"4564654654\"\n"
+ " memberBoolean = \"true\" \n"
+ " memberByteClass = \"55\" \n"
+ " memberShortClass = \"1523\" \n"
+ " memberIntegerClass = \"4654654\" \n"
+ " memberLongClass = \"545645645454\"\n"
+ " memberBooleanClass = \"true\" \n"
+ " memberStringClass = \"sdfgsdkjfglksqjéé\"\n"
+ " memberArrayByte=\"12, 15,123, 100, 2\"\n"
+ " memberArrayByteClass=\"\t\t\r\n 12,1, 100,122\"\n"
+ " memberArrayShort=\"1245,1894, -100,-12542\"\n"
+ " memberArrayShortClass=\"-1245,-1894, 0,2542,15615\"\n"
+ " memberArrayInteger=\"123456,-654987\"\n"
+ " memberArrayIntegerClass=\"1567845,45621354,-5646544\"\n"
+ " memberArrayLong=\"1651324654,65421351685,-5\"\n"
+ " memberArrayLongClass=\"6746541351,546546546,564654654,654654654654,-45546\"\n"
+ " memberArrayBoolean=\"true, true, false\"\n"
+ " memberArrayBooleanClass=\"false, false, true, true\"\n"
+ "/>\n";
//@formatter:on
final ClassPublicMemberOnly[] root = Assertions.assertDoesNotThrow(() -> Exml.parse(dataToParse, ClassPublicMemberOnly.class, "elem"));
Assertions.assertEquals(1, root.length);
final ClassPublicMemberOnly elem = root[0];
Assertions.assertEquals((byte) 12, elem.memberByte);
Assertions.assertEquals((short) 1223, elem.memberShort);
Assertions.assertEquals(4541542, elem.memberInteger);
Assertions.assertEquals(4564654654L, elem.memberLong);
Assertions.assertEquals(true, elem.memberBoolean);
Assertions.assertEquals((byte) 55, elem.memberByteClass);
Assertions.assertEquals((short) 1523, elem.memberShortClass);
Assertions.assertEquals(4654654, elem.memberIntegerClass);
Assertions.assertEquals(545645645454L, elem.memberLongClass);
Assertions.assertEquals(true, elem.memberBooleanClass);
Assertions.assertEquals("sdfgsdkjfglksqjéé", elem.memberStringClass);
Assertions.assertEquals(5, elem.memberArrayByte.length);
Assertions.assertEquals((byte) 12, elem.memberArrayByte[0]);
Assertions.assertEquals((byte) 15, elem.memberArrayByte[1]);
Assertions.assertEquals((byte) 123, elem.memberArrayByte[2]);
Assertions.assertEquals((byte) 100, elem.memberArrayByte[3]);
Assertions.assertEquals(2, elem.memberArrayByte[4]);
Assertions.assertEquals(4, elem.memberArrayByteClass.length);
Assertions.assertEquals((byte) 12, elem.memberArrayByteClass[0]);
Assertions.assertEquals((byte) 1, elem.memberArrayByteClass[1]);
Assertions.assertEquals((byte) 100, elem.memberArrayByteClass[2]);
Assertions.assertEquals((byte) 122, elem.memberArrayByteClass[3]);
Assertions.assertEquals(4, elem.memberArrayShort.length);
Assertions.assertEquals((short) 1245, elem.memberArrayShort[0]);
Assertions.assertEquals((short) 1894, elem.memberArrayShort[1]);
Assertions.assertEquals((short) -100, elem.memberArrayShort[2]);
Assertions.assertEquals((short) -12542, elem.memberArrayShort[3]);
Assertions.assertEquals(5, elem.memberArrayShortClass.length);
Assertions.assertEquals((short) -1245, elem.memberArrayShortClass[0]);
Assertions.assertEquals((short) -1894, elem.memberArrayShortClass[1]);
Assertions.assertEquals((short) 0, elem.memberArrayShortClass[2]);
Assertions.assertEquals((short) 2542, elem.memberArrayShortClass[3]);
Assertions.assertEquals((short) 15615, elem.memberArrayShortClass[4]);
Assertions.assertEquals(2, elem.memberArrayInteger.length);
//Assertions.assertArrayEquals(Arrays.asList(123456, -654987).toArray(), elem.memberArrayInteger);
Assertions.assertEquals(3, elem.memberArrayIntegerClass.length);
Assertions.assertArrayEquals(Arrays.asList(1567845, 45621354, -5646544).toArray(), elem.memberArrayIntegerClass);
Assertions.assertEquals(3, elem.memberArrayLong.length);
//Assertions.assertArrayEquals(Arrays.asList(1651324654L, 65421351685L, -5L).toArray(), elem.memberArrayLong);
Assertions.assertEquals(5, elem.memberArrayLongClass.length);
Assertions.assertArrayEquals(Arrays.asList(6746541351L, 546546546L, 564654654L, 654654654654L, -45546L).toArray(), elem.memberArrayLongClass);
Assertions.assertEquals(3, elem.memberArrayBoolean.length);
//Assertions.assertArrayEquals(Arrays.asList(true, true, false).toArray(), elem.memberArrayBoolean);
Assertions.assertEquals(4, elem.memberArrayBooleanClass.length);
Assertions.assertArrayEquals(Arrays.asList(false, false, true, true).toArray(), elem.memberArrayBooleanClass);
}
@Test
public void test2() {
//@formatter:off
final String dataToParse = "<elem\n"
+ " memberByte=\"12\"\n"
+ " memberShort=\"1223\"\n"
+ " memberInteger=\"4541542\"\n"
+ " memberLong = \"4564654654\"\n"
+ " memberBoolean = \"true\" \n"
+ " memberByteClass = \"55\" \n"
+ " memberShortClass = \"1523\" \n"
+ " memberIntegerClass = \"4654654\" \n"
+ " memberLongClass = \"545645645454\"\n"
+ " memberBooleanClass = \"true\" \n"
+ " memberStringClass = \"sdfgsdkjfglksqjéé\"\n/>\n";
//@formatter:on
final ClassPublicMethodOnly[] root = Assertions.assertDoesNotThrow(() -> Exml.parse(dataToParse, ClassPublicMethodOnly.class, "elem"));
Assertions.assertEquals(1, root.length);
}
}

View File

@ -0,0 +1,25 @@
package test.atriasoft.exml.introspection;
public class ClassPublicMemberOnly {
public byte memberByte;
public short memberShort;
public int memberInteger;
public long memberLong;
public boolean memberBoolean;
public Byte memberByteClass;
public Short memberShortClass;
public Integer memberIntegerClass;
public Long memberLongClass;
public Boolean memberBooleanClass;
public String memberStringClass;
public byte[] memberArrayByte;
public short[] memberArrayShort;
public int[] memberArrayInteger;
public long[] memberArrayLong;
public boolean[] memberArrayBoolean;
public Byte[] memberArrayByteClass;
public Short[] memberArrayShortClass;
public Integer[] memberArrayIntegerClass;
public Long[] memberArrayLongClass;
public Boolean[] memberArrayBooleanClass;
}

View File

@ -0,0 +1,193 @@
package test.atriasoft.exml.introspection;
public class ClassPublicMethodOnly {
private byte memberByte;
private short memberShort;
private int memberInteger;
private long memberLong;
private boolean memberBoolean;
private Byte memberByteClass;
private Short memberShortClass;
private Integer memberIntegerClass;
private Long memberLongClass;
private Boolean memberBooleanClass;
private String memberStringClass;
private byte[] memberArrayByte;
private short[] memberArrayShort;
private int[] memberArrayInteger;
private long[] memberArrayLong;
private boolean[] memberArrayBoolean;
private Byte[] memberArrayByteClass;
private Short[] memberArrayShortClass;
private Integer[] memberArrayIntegerClass;
private Long[] memberArrayLongClass;
private Boolean[] memberArrayBooleanClass;
public boolean[] getMemberArrayBoolean() {
return this.memberArrayBoolean;
}
public Boolean[] getMemberArrayBooleanClass() {
return this.memberArrayBooleanClass;
}
public byte[] getMemberArrayByte() {
return this.memberArrayByte;
}
public Byte[] getMemberArrayByteClass() {
return this.memberArrayByteClass;
}
public int[] getMemberArrayInteger() {
return this.memberArrayInteger;
}
public Integer[] getMemberArrayIntegerClass() {
return this.memberArrayIntegerClass;
}
public long[] getMemberArrayLong() {
return this.memberArrayLong;
}
public Long[] getMemberArrayLongClass() {
return this.memberArrayLongClass;
}
public short[] getMemberArrayShort() {
return this.memberArrayShort;
}
public Short[] getMemberArrayShortClass() {
return this.memberArrayShortClass;
}
public Boolean getMemberBooleanClass() {
return this.memberBooleanClass;
}
public byte getMemberByte() {
return this.memberByte;
}
public Byte getMemberByteClass() {
return this.memberByteClass;
}
public int getMemberInteger() {
return this.memberInteger;
}
public Integer getMemberIntegerClass() {
return this.memberIntegerClass;
}
public long getMemberLong() {
return this.memberLong;
}
public Long getMemberLongClass() {
return this.memberLongClass;
}
public short getMemberShort() {
return this.memberShort;
}
public Short getMemberShortClass() {
return this.memberShortClass;
}
public String getMemberStringClass() {
return this.memberStringClass;
}
public boolean isMemberBoolean() {
return this.memberBoolean;
}
public void setMemberArrayBoolean(final boolean[] memberArrayBoolean) {
this.memberArrayBoolean = memberArrayBoolean;
}
public void setMemberArrayBooleanClass(final Boolean[] memberArrayBooleanClass) {
this.memberArrayBooleanClass = memberArrayBooleanClass;
}
public void setMemberArrayByte(final byte[] memberArrayByte) {
this.memberArrayByte = memberArrayByte;
}
public void setMemberArrayByteClass(final Byte[] memberArrayByteClass) {
this.memberArrayByteClass = memberArrayByteClass;
}
public void setMemberArrayInteger(final int[] memberArrayInteger) {
this.memberArrayInteger = memberArrayInteger;
}
public void setMemberArrayIntegerClass(final Integer[] memberArrayIntegerClass) {
this.memberArrayIntegerClass = memberArrayIntegerClass;
}
public void setMemberArrayLong(final long[] memberArrayLong) {
this.memberArrayLong = memberArrayLong;
}
public void setMemberArrayLongClass(final Long[] memberArrayLongClass) {
this.memberArrayLongClass = memberArrayLongClass;
}
public void setMemberArrayShort(final short[] memberArrayShort) {
this.memberArrayShort = memberArrayShort;
}
public void setMemberArrayShortClass(final Short[] memberArrayShortClass) {
this.memberArrayShortClass = memberArrayShortClass;
}
public void setMemberBoolean(final boolean memberBoolean) {
this.memberBoolean = memberBoolean;
}
public void setMemberBooleanClass(final Boolean memberBooleanClass) {
this.memberBooleanClass = memberBooleanClass;
}
public void setMemberByte(final byte memberByte) {
this.memberByte = memberByte;
}
public void setMemberByteClass(final Byte memberByteClass) {
this.memberByteClass = memberByteClass;
}
public void setMemberInteger(final int memberInteger) {
this.memberInteger = memberInteger;
}
public void setMemberIntegerClass(final Integer memberIntegerClass) {
this.memberIntegerClass = memberIntegerClass;
}
public void setMemberLong(final long memberLong) {
this.memberLong = memberLong;
}
public void setMemberLongClass(final Long memberLongClass) {
this.memberLongClass = memberLongClass;
}
public void setMemberShort(final short memberShort) {
this.memberShort = memberShort;
}
public void setMemberShortClass(final Short memberShortClass) {
this.memberShortClass = memberShortClass;
}
public void setMemberStringClass(final String memberStringClass) {
this.memberStringClass = memberStringClass;
}
}