[DEV] start thing of xml introspection generation

This commit is contained in:
Edouard DUPIN 2021-06-29 23:39:03 +02:00
parent cd25863ed9
commit e68802010b
8 changed files with 345 additions and 12 deletions

View File

@ -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();
}
} }
/** /**

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);

View File

@ -0,0 +1,5 @@
package org.atriasoft.exml.generator;
public interface Generator {
}

View 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);
}
}

View File

@ -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()));
}
}

View File

@ -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());
}
}