[DEV] start thing of xml introspection generation
This commit is contained in:
parent
cd25863ed9
commit
e68802010b
@ -21,6 +21,7 @@ import org.atriasoft.exml.builder.BuilderIntrospection;
|
|||||||
import org.atriasoft.exml.builder.IntrospectionObject;
|
import org.atriasoft.exml.builder.IntrospectionObject;
|
||||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||||
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||||
|
import org.atriasoft.exml.generator.GeneratorIntrospection;
|
||||||
import org.atriasoft.exml.internal.Log;
|
import org.atriasoft.exml.internal.Log;
|
||||||
import org.atriasoft.exml.model.XmlElement;
|
import org.atriasoft.exml.model.XmlElement;
|
||||||
import org.atriasoft.exml.model.XmlNode;
|
import org.atriasoft.exml.model.XmlNode;
|
||||||
@ -38,8 +39,24 @@ public class Exml {
|
|||||||
Log.info("Generated XML : \n" + tmpp.toString());
|
Log.info("Generated XML : \n" + tmpp.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generate(final Object root, final StringBuilder data) {
|
public static void generate(final Object root, final String rootNodeName, final StringBuilder data) throws ExmlBuilderException {
|
||||||
// TODO ...
|
GeneratorIntrospection generator;
|
||||||
|
try {
|
||||||
|
generator = new GeneratorIntrospection(root.getClass(), rootNodeName);
|
||||||
|
generator.generate(root, data);
|
||||||
|
/*
|
||||||
|
final SerializerXmlIntrospection serializer = new SerializerXmlIntrospection(generator);
|
||||||
|
final ParsingProperty property = new ParsingProperty();
|
||||||
|
property.setDisplayError(true);
|
||||||
|
|
||||||
|
serializer.generate(root, property, tmpp);
|
||||||
|
*/
|
||||||
|
} catch (final ExmlBuilderException ex) {
|
||||||
|
throw ex;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,6 +174,12 @@ public class IntrospectionData {
|
|||||||
|
|
||||||
private final List<IntrospectionProperty> properties = new ArrayList<>();
|
private final List<IntrospectionProperty> properties = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<IntrospectionProperty> getMethods() {
|
||||||
|
return this.methods;
|
||||||
|
}
|
||||||
|
public List<IntrospectionProperty> getProperties() {
|
||||||
|
return this.properties;
|
||||||
|
}
|
||||||
public Class<?> getClassType() {
|
public Class<?> getClassType() {
|
||||||
return this.classType;
|
return this.classType;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public abstract class IntrospectionProperty {
|
|||||||
return this.subType;
|
return this.subType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract String getValue(Object object) throws Exception;
|
public abstract String getValue(Object object) throws ExmlBuilderException;
|
||||||
|
|
||||||
public boolean isCaseSensitive() {
|
public boolean isCaseSensitive() {
|
||||||
return this.caseSensitive;
|
return this.caseSensitive;
|
||||||
|
@ -45,9 +45,69 @@ public class IntrospectionPropertyField extends IntrospectionProperty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(final Object object) {
|
public String getValue(final Object object) throws ExmlBuilderException {
|
||||||
// TODO Auto-generated method stub
|
try {
|
||||||
return null;
|
Object value = this.fieldDescription.get(object);
|
||||||
|
|
||||||
|
if (this.type == byte.class) {
|
||||||
|
return Byte.toString((byte)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.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);'");
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,17 +186,23 @@ public class IntrospectionPropertyField extends IntrospectionProperty {
|
|||||||
}
|
}
|
||||||
if (this.type == int.class) {
|
if (this.type == int.class) {
|
||||||
return Integer.valueOf(value);
|
return Integer.valueOf(value);
|
||||||
} else if (this.type == long.class) {
|
}
|
||||||
|
if (this.type == long.class) {
|
||||||
return Long.valueOf(value);
|
return Long.valueOf(value);
|
||||||
} else if (this.type == boolean.class) {
|
}
|
||||||
|
if (this.type == boolean.class) {
|
||||||
return Boolean.valueOf(value);
|
return Boolean.valueOf(value);
|
||||||
} else if (this.type == String.class) {
|
}
|
||||||
|
if (this.type == String.class) {
|
||||||
return value;
|
return value;
|
||||||
} else if (this.type == Byte.class) {
|
}
|
||||||
|
if (this.type == Byte.class) {
|
||||||
return Byte.valueOf(value);
|
return Byte.valueOf(value);
|
||||||
} else if (this.type == Short.class) {
|
}
|
||||||
|
if (this.type == Short.class) {
|
||||||
return Short.valueOf(value);
|
return Short.valueOf(value);
|
||||||
} else if (this.type == Integer.class) {
|
}
|
||||||
|
if (this.type == Integer.class) {
|
||||||
return Integer.valueOf(value);
|
return Integer.valueOf(value);
|
||||||
} else if (this.type == Long.class) {
|
} else if (this.type == Long.class) {
|
||||||
return Long.valueOf(value);
|
return Long.valueOf(value);
|
||||||
|
5
src/org/atriasoft/exml/generator/Generator.java
Normal file
5
src/org/atriasoft/exml/generator/Generator.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package org.atriasoft.exml.generator;
|
||||||
|
|
||||||
|
public interface Generator {
|
||||||
|
|
||||||
|
}
|
69
src/org/atriasoft/exml/generator/GeneratorIntrospection.java
Normal file
69
src/org/atriasoft/exml/generator/GeneratorIntrospection.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package org.atriasoft.exml.generator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.atriasoft.exml.builder.IntrospectionData;
|
||||||
|
import org.atriasoft.exml.builder.IntrospectionProperty;
|
||||||
|
|
||||||
|
public class GeneratorIntrospection implements Generator {
|
||||||
|
// 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 GeneratorIntrospection(final Class<?> classType, final String rootNodeName) throws Exception {
|
||||||
|
this.rootNodeName = rootNodeName;
|
||||||
|
this.rootClassType = classType;
|
||||||
|
this.elements.put(classType, new IntrospectionData(classType, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntrospectionData findOrCreate(final Class<?> classType) throws Exception {
|
||||||
|
IntrospectionData out = this.elements.get(classType);
|
||||||
|
if (out != null) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
out = new IntrospectionData(classType);
|
||||||
|
this.elements.put(classType, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateProperties(final Object node, final IntrospectionData introspection, final StringBuilder tmpp) throws Exception {
|
||||||
|
List<IntrospectionProperty> elements = introspection.getProperties();
|
||||||
|
for (IntrospectionProperty elem : elements) {
|
||||||
|
if (!elem.canGetValue()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = elem.getNames()[0];
|
||||||
|
String data=elem.getValue(node);
|
||||||
|
tmpp.append(" ");
|
||||||
|
tmpp.append(name);
|
||||||
|
tmpp.append("=\"");
|
||||||
|
tmpp.append(data);
|
||||||
|
tmpp.append("\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void generateSubNodes(final Object node, final IntrospectionData introspection, final StringBuilder tmpp) {
|
||||||
|
List<IntrospectionProperty> elements = introspection.getMethods();
|
||||||
|
for (IntrospectionProperty elem : elements) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void generateNode(final Object node, final String nodeName, final StringBuilder tmpp) throws Exception {
|
||||||
|
IntrospectionData introspection = findOrCreate(node.getClass());
|
||||||
|
tmpp.append("<");
|
||||||
|
tmpp.append(nodeName);
|
||||||
|
generateProperties(node, introspection, tmpp);
|
||||||
|
tmpp.append(">\n");
|
||||||
|
generateSubNodes(node, introspection, tmpp);
|
||||||
|
tmpp.append("</");
|
||||||
|
tmpp.append(nodeName);
|
||||||
|
tmpp.append(">\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
public void generate(final Object root, final StringBuilder tmpp) throws Exception {
|
||||||
|
generateNode(root, this.rootNodeName, tmpp);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package org.atriasoft.exml.serializer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.atriasoft.exml.generator.Generator;
|
||||||
|
import org.atriasoft.exml.internal.Log;
|
||||||
|
import org.atriasoft.exml.model.XmlAttribute;
|
||||||
|
import org.atriasoft.exml.model.XmlAttributeList;
|
||||||
|
import org.atriasoft.exml.model.XmlComment;
|
||||||
|
import org.atriasoft.exml.model.XmlDeclaration;
|
||||||
|
import org.atriasoft.exml.model.XmlElement;
|
||||||
|
import org.atriasoft.exml.model.XmlNode;
|
||||||
|
import org.atriasoft.exml.model.XmlNodeType;
|
||||||
|
import org.atriasoft.exml.model.XmlText;
|
||||||
|
import org.atriasoft.exml.parser.ParsingProperty;
|
||||||
|
import org.atriasoft.exml.parser.Tools;
|
||||||
|
|
||||||
|
public class SerializerXmlIntrospection {
|
||||||
|
public static void serialize(final XmlNode node, final StringBuilder data, final int indent) {
|
||||||
|
if (node instanceof XmlElement) {
|
||||||
|
SerializerXmlIntrospection.serializeElement((XmlElement) node, data, indent);
|
||||||
|
} else if (node instanceof XmlText) {
|
||||||
|
SerializerXmlIntrospection.serializeText((XmlText) node, data, indent);
|
||||||
|
} else if (node instanceof XmlDeclaration) {
|
||||||
|
SerializerXmlIntrospection.serializeDeclaration((XmlDeclaration) node, data, indent);
|
||||||
|
} else if (node instanceof XmlComment) {
|
||||||
|
SerializerXmlIntrospection.serializeComment((XmlComment) node, data, indent);
|
||||||
|
} else {
|
||||||
|
// TODO throw an error ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serializeAttribute(final XmlAttribute attribute, final StringBuilder data, final int indent) {
|
||||||
|
data.append(" ");
|
||||||
|
data.append(attribute.getName());
|
||||||
|
data.append("=\"");
|
||||||
|
data.append(attribute.getValue());
|
||||||
|
data.append("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serializeAttributeList(final XmlAttributeList list, final StringBuilder data, final int indent) {
|
||||||
|
for (int iii = 0; iii < list.getAttributes().size(); iii++) {
|
||||||
|
SerializerXmlIntrospection.serializeAttribute(list.getAttributes().get(iii), data, indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serializeComment(final XmlComment comment, final StringBuilder data, final int indent) {
|
||||||
|
Tools.addIndent(data, indent);
|
||||||
|
data.append("<!--");
|
||||||
|
data.append(comment.getValue());
|
||||||
|
data.append("-->\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serializeDeclaration(final XmlDeclaration declaration, final StringBuilder data, final int indent) {
|
||||||
|
Tools.addIndent(data, indent);
|
||||||
|
data.append("<?");
|
||||||
|
data.append(declaration.getValue());
|
||||||
|
SerializerXmlIntrospection.serializeAttributeList(declaration, data, indent);
|
||||||
|
data.append("?>\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serializeElement(final XmlElement element, final StringBuilder data, final int indent) {
|
||||||
|
|
||||||
|
Tools.addIndent(data, indent);
|
||||||
|
data.append("<");
|
||||||
|
data.append(element.getValue());
|
||||||
|
SerializerXmlIntrospection.serializeAttributeList(element, data, indent);
|
||||||
|
|
||||||
|
final List<XmlNode> nodes = element.getNodes();
|
||||||
|
if (nodes.size() > 0) {
|
||||||
|
if (nodes.size() == 1 && nodes.get(0) != null && nodes.get(0).getType() == XmlNodeType.TEXT && ((XmlText) nodes.get(0)).countLines() == 1) {
|
||||||
|
data.append(">");
|
||||||
|
SerializerXmlIntrospection.serialize(nodes.get(0), data, 0);
|
||||||
|
Log.verbose(" generate : '" + data + "'");
|
||||||
|
} else {
|
||||||
|
data.append(">\n");
|
||||||
|
for (XmlNode node : nodes) {
|
||||||
|
if (node != null) {
|
||||||
|
SerializerXmlIntrospection.serialize(node, data, indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tools.addIndent(data, indent);
|
||||||
|
}
|
||||||
|
data.append("</");
|
||||||
|
data.append(element.getValue());
|
||||||
|
data.append(">\n");
|
||||||
|
} else {
|
||||||
|
data.append("/>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void serializeRoot(final XmlElement root, final StringBuilder data) {
|
||||||
|
for (int iii = 0; iii < root.getNodes().size(); iii++) {
|
||||||
|
final XmlNode node = root.getNodes().get(iii);
|
||||||
|
SerializerXmlIntrospection.serialize(node, data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void serializeText(final XmlText text, final StringBuilder data, final int indent) {
|
||||||
|
data.append(Tools.replaceSpecialCharOut(text.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Generator generator;
|
||||||
|
public SerializerXmlIntrospection(final Generator generator) {
|
||||||
|
this.generator = generator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generate(final Object root, final ParsingProperty property, final StringBuilder tmpp) {
|
||||||
|
//property.append(Tools.replaceSpecialCharOut(root.getValue()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/** @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.exception.ExmlBuilderException;
|
||||||
|
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import test.atriasoft.exml.introspection.ClassPublicMemberOnly;
|
||||||
|
|
||||||
|
public class ExmlTestIntrospectionGenerate {
|
||||||
|
@BeforeAll
|
||||||
|
public static void beforeClass() {
|
||||||
|
Log.verbose("----------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() throws ExmlParserErrorMulti, ExmlBuilderException {
|
||||||
|
ClassPublicMemberOnly elem = new ClassPublicMemberOnly();
|
||||||
|
elem.memberArrayBoolean = new boolean[] {false, true};
|
||||||
|
elem.memberArrayBooleanClass = new Boolean[] {false, true, true};
|
||||||
|
elem.memberArrayByte = new byte[] {21,21,58};
|
||||||
|
elem.memberArrayByteClass = new Byte[] {54,21,65,32};
|
||||||
|
elem.memberArrayInteger = new int[] { 1521,2151,2156,216354};
|
||||||
|
elem.memberArrayIntegerClass = new Integer[] {5564,6546321,654564,231321,54654};
|
||||||
|
elem.memberArrayLong = new long[] {6546544L,654654651L,5646546541L,5465465163L} ;
|
||||||
|
elem.memberArrayLongClass = new Long[] {561651L, 6541321L, 651351L};
|
||||||
|
elem.memberArrayShort = new short[] {4564, -54,-564};
|
||||||
|
elem.memberArrayShortClass = new Short[] {-54, 5646, -8465, 852};
|
||||||
|
elem.memberBoolean = false;
|
||||||
|
elem.memberBooleanClass = true;
|
||||||
|
elem.memberByte = 12;
|
||||||
|
elem.memberByteClass = 54;
|
||||||
|
elem.memberInteger = 6543524;
|
||||||
|
elem.memberIntegerClass = 545666;
|
||||||
|
elem.memberLong = 400000055L;
|
||||||
|
elem.memberLongClass = 54654546L;
|
||||||
|
elem.memberShort = 31252;
|
||||||
|
elem.memberShortClass =-25212;
|
||||||
|
elem.memberStringClass ="lkjhlkjlkjlkj";
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
Exml.generate(elem, "elem", builder);
|
||||||
|
Log.warning("data generated: " + builder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user