[DEV] externalize the introspection in aknot

# Conflicts:
#	src/org/atriasoft/exml/builder/BuilderIntrospection.java
#	src/org/atriasoft/exml/builder/IntrospectionModelComplex.java
This commit is contained in:
Edouard DUPIN 2022-05-11 00:49:00 +02:00
parent 80a9db1f25
commit e268e655a4
32 changed files with 208 additions and 3237 deletions

View File

@ -5,7 +5,6 @@
*/
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

@ -1,16 +0,0 @@
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);
}

View File

@ -1,228 +0,0 @@
package org.atriasoft.eStringSerialize;
import java.util.HashMap;
import java.util.Map;
public class StringSerializer {
private static final Map<Class<?>, Converter> VALUES_OF = new HashMap<>();
static {
StringSerializer.VALUES_OF.put(byte.class, new Converter() {
@Override
public String toString(final Object data) {
return Byte.toString((Byte) data);
}
@Override
public Object valueOf(final String value) {
return Byte.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Byte.class, new Converter() {
@Override
public String toString(final Object data) {
return Byte.toString((Byte) data);
}
@Override
public Object valueOf(final String value) {
return Byte.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(int.class, new Converter() {
@Override
public String toString(final Object data) {
return Integer.toString((Integer) data);
}
@Override
public Object valueOf(final String value) {
return Integer.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Integer.class, new Converter() {
@Override
public String toString(final Object data) {
return Integer.toString((Integer) data);
}
@Override
public Object valueOf(final String value) {
return Integer.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(long.class, new Converter() {
@Override
public String toString(final Object data) {
return Long.toString((Long) data);
}
@Override
public Object valueOf(final String value) {
return Long.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Long.class, new Converter() {
@Override
public String toString(final Object data) {
return Long.toString((Long) data);
}
@Override
public Object valueOf(final String value) {
return Long.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(short.class, new Converter() {
@Override
public String toString(final Object data) {
return Short.toString((Short) data);
}
@Override
public Object valueOf(final String value) {
return Short.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Short.class, new Converter() {
@Override
public String toString(final Object data) {
return Short.toString((Short) data);
}
@Override
public Object valueOf(final String value) {
return Short.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(float.class, new Converter() {
@Override
public String toString(final Object data) {
return Float.toString((Float) data);
}
@Override
public Object valueOf(final String value) {
return Float.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Float.class, new Converter() {
@Override
public String toString(final Object data) {
return Float.toString((Float) data);
}
@Override
public Object valueOf(final String value) {
return Float.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(double.class, new Converter() {
@Override
public String toString(final Object data) {
return Double.toString((Double) data);
}
@Override
public Object valueOf(final String value) {
return Double.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Double.class, new Converter() {
@Override
public String toString(final Object data) {
return Double.toString((Double) data);
}
@Override
public Object valueOf(final String value) {
return Double.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(boolean.class, new Converter() {
@Override
public String toString(final Object data) {
return Boolean.toString((Boolean) data);
}
@Override
public Object valueOf(final String value) {
return Boolean.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(Boolean.class, new Converter() {
@Override
public String toString(final Object data) {
return Boolean.toString((Boolean) data);
}
@Override
public Object valueOf(final String value) {
return Boolean.valueOf(value.trim());
}
});
StringSerializer.VALUES_OF.put(String.class, new Converter() {
@Override
public String toString(final Object data) {
return (String) data;
}
@Override
public Object valueOf(final String value) {
return value;
}
});
}
public static boolean contains(final Class<?> clazz) {
return StringSerializer.VALUES_OF.containsKey(clazz);
}
public static String toString(final boolean data) {
return Boolean.toString(data);
}
public static String toString(final byte data) {
return Byte.toString(data);
}
public static String toString(final int data) {
return Integer.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;
}
final Class<?> clazz = data.getClass();
final Converter conv = StringSerializer.VALUES_OF.get(clazz);
return conv.toString(data);
}
public static String toString(final short data) {
return Short.toString(data);
}
/**
* 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;
}
final Converter conv = StringSerializer.VALUES_OF.get(clazz);
return conv.valueOf(value);
}
private StringSerializer() {}
}

View File

@ -12,13 +12,14 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import org.atriasoft.aknot.exception.AknotException;
import org.atriasoft.aknot.model.InterfaceFactoryAccess;
import org.atriasoft.aknot.model.ModelType;
import org.atriasoft.aknot.pojo.IntrospectionObject;
import org.atriasoft.etk.Uri;
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.builder.ModelType;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlException;
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
@ -74,7 +75,7 @@ public class Exml {
// return iGenerate(_data, 0);
}
public static XmlElement parse(final Path data) throws ExmlException, ExmlParserErrorMulti {
public static XmlElement parse(final Path data) throws ExmlException, ExmlParserErrorMulti, AknotException {
final Builder builder = new BuilderGeneric();
final ParseXml parser = new ParseXml(builder);
final ParsingProperty property = new ParsingProperty();
@ -94,7 +95,7 @@ public class Exml {
return (XmlElement) parser.parse(dataToParse, property);
}
public static <T> T[] parse(final Path path, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti {
public static <T> T[] parse(final Path path, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti, AknotException {
String content = null;
try {
content = Exml.readFile(path, StandardCharsets.UTF_8);
@ -104,7 +105,7 @@ public class Exml {
return Exml.parse(content, classType, rootNodeName);
}
public static XmlElement parse(final String data) throws ExmlException, ExmlParserErrorMulti {
public static XmlElement parse(final String data) throws ExmlException, ExmlParserErrorMulti, AknotException {
final Builder builder = new BuilderGeneric();
final ParseXml parser = new ParseXml(builder);
final ParsingProperty property = new ParsingProperty();
@ -113,7 +114,7 @@ public class Exml {
}
@SuppressWarnings("unchecked")
public static <T> T[] parse(final String data, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti {
public static <T> T[] parse(final String data, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti, AknotException {
Builder builder;
try {
builder = new BuilderIntrospection(ModelType.ARRAY, classType, rootNodeName);
@ -134,7 +135,7 @@ public class Exml {
}
}
public static Object[] parse(final String data, final InterfaceFactoryAccess widgetXmlFactory) throws ExmlException, ExmlParserErrorMulti {
public static Object[] parse(final String data, final InterfaceFactoryAccess widgetXmlFactory) throws ExmlException, ExmlParserErrorMulti, AknotException {
Builder builder;
try {
builder = new BuilderIntrospection(widgetXmlFactory);
@ -176,7 +177,7 @@ public class Exml {
* parse(tmpDataUnicode); //Display(); return ret; }
*/
public static XmlElement parse(final Uri data) throws ExmlException {
public static XmlElement parse(final Uri data) throws ExmlException, AknotException {
final Builder builder = new BuilderGeneric();
final ParseXml parser = new ParseXml(builder);
final ParsingProperty property = new ParsingProperty();
@ -190,7 +191,7 @@ public class Exml {
return (XmlElement) parser.parse(dataToParse, property);
}
public static <T> T parseOne(final Path path, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti {
public static <T> T parseOne(final Path path, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti, AknotException {
final T[] elements = Exml.parse(path, classType, rootNodeName);
if (elements == null || elements.length == 0) {
throw new ExmlBuilderException("Error in parsing the file, no node find ...");
@ -201,7 +202,7 @@ public class Exml {
return elements[0];
}
public static <T> T parseOne(final String data, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti {
public static <T> T parseOne(final String data, final Class<T> classType, final String rootNodeName) throws ExmlException, ExmlParserErrorMulti, AknotException {
final T[] elements = Exml.parse(data, classType, rootNodeName);
if (elements == null || elements.length == 0) {
throw new ExmlBuilderException("Error in parsing the file, no node find ...");

View File

@ -5,6 +5,7 @@
*/
package org.atriasoft.exml.builder;
import org.atriasoft.aknot.exception.AknotException;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlException;
@ -15,7 +16,7 @@ public interface Builder {
* @param element Element that is finished
* @throws ExmlBuilderException
*/
void endElement(Object element) throws ExmlException;
void endElement(Object element) throws ExmlException, AknotException;
/**
* This is called before a text adding, in some case the subData must not be parsed, then all the subData is pack as a single string without managing the XML properties.
@ -23,7 +24,7 @@ public interface Builder {
* @return true if the data must be packed.
* @throws ExmlException
*/
boolean isPackText(Object parent) throws ExmlException;
boolean isPackText(Object parent) throws ExmlException, AknotException;
/**
* New comment added on this Element
@ -31,7 +32,7 @@ public interface Builder {
* @param comment Comment value
* @throws ExmlBuilderException Error with this node or element.
*/
void newComment(Object element, String comment) throws ExmlException;
void newComment(Object element, String comment) throws ExmlException, AknotException;
/**
* New comment added on this Element
@ -40,7 +41,7 @@ public interface Builder {
* @return Declaration object value
* @throws ExmlBuilderException Error with this node or element.
*/
Object newDeclaration(Object parent, String text) throws ExmlException;
Object newDeclaration(Object parent, String text) throws ExmlException, AknotException;
/**
* Add a new sub-element on the current parent element: {@code<ELEMENT>}
@ -49,7 +50,7 @@ public interface Builder {
* @return the object representing the Element.
* @throws ExmlBuilderException Error with this node or element.
*/
Object newElement(Object parent, String nodeName) throws ExmlException;
Object newElement(Object parent, String nodeName) throws ExmlException, AknotException;
/**
* The sub-element is finish (creation done)
@ -57,7 +58,7 @@ public interface Builder {
* @param tmpname Name of the node
* @param element Element builder that has been created
*/
void newElementFinished(Object parent, String tmpname, Object element) throws ExmlException;
void newElementFinished(Object parent, String tmpname, Object element) throws ExmlException, AknotException;
/**
* Add a property on the Element.
@ -66,14 +67,14 @@ public interface Builder {
* @param propertyValue Value of the property
* @throws ExmlBuilderException Error with this node or element.
*/
void newProperty(Object element, String propertyName, String propertyValue) throws ExmlException;
void newProperty(Object element, String propertyName, String propertyValue) throws ExmlException, AknotException;
/**
* Create or get the root element of the document
* @return An object that id a root element.
* @throws ExmlBuilderException Error with this node or element.
*/
Object newRoot() throws ExmlBuilderException;
Object newRoot() throws ExmlBuilderException, AknotException;
/**
* Add a text value on the current Element
@ -81,6 +82,6 @@ public interface Builder {
* @param text Test to add.
* @throws ExmlBuilderException Error with this node or element.
*/
void newText(Object parent, String text) throws ExmlException;
void newText(Object parent, String text) throws ExmlException, AknotException;
}

View File

@ -3,8 +3,13 @@ package org.atriasoft.exml.builder;
import java.util.ArrayList;
import java.util.List;
import org.atriasoft.aknot.StringSerializer;
import org.atriasoft.aknot.exception.AknotException;
import org.atriasoft.aknot.model.InterfaceFactoryAccess;
import org.atriasoft.eStringSerialize.StringSerializer;
import org.atriasoft.aknot.model.IntrospectionModel;
import org.atriasoft.aknot.model.ModelType;
import org.atriasoft.aknot.pojo.CacheIntrospectionModel;
import org.atriasoft.aknot.pojo.IntrospectionObject;
import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlException;
@ -18,7 +23,7 @@ public class BuilderIntrospection implements Builder {
final String rootNodeName;
final InterfaceFactoryAccess factory;
public BuilderIntrospection(final InterfaceFactoryAccess factory) throws ExmlException {
public BuilderIntrospection(final InterfaceFactoryAccess factory) throws ExmlException, AknotException {
this.factory = factory;
this.rootNodeName = null;
this.rootClassType = null;
@ -27,7 +32,7 @@ public class BuilderIntrospection implements Builder {
}
}
public BuilderIntrospection(final ModelType model, final Class<?> classType, final String rootNodeName) throws ExmlException {
public BuilderIntrospection(final ModelType model, final Class<?> classType, final String rootNodeName) throws ExmlException, AknotException {
this.factory = null;
this.rootNodeName = rootNodeName;
this.rootClassType = classType;
@ -35,7 +40,7 @@ public class BuilderIntrospection implements Builder {
}
@Override
public void endElement(final Object element) throws ExmlBuilderException {
public void endElement(final Object element) throws ExmlBuilderException, AknotException {
Log.verbose("End of Element: {}", element);
if (element == null) {
return;
@ -63,16 +68,16 @@ public class BuilderIntrospection implements Builder {
}
@Override
public void newComment(final Object element, final String comment) throws ExmlException {}
public void newComment(final Object element, final String comment) {}
@Override
public Object newDeclaration(final Object parent, final String text) throws ExmlException {
public Object newDeclaration(final Object parent, final String text) {
// we drop all declaration, no need of it too.
return null;
}
@Override
public Object newElement(final Object parent, final String nodeName) throws ExmlException {
public Object newElement(final Object parent, final String nodeName) throws ExmlException, AknotException {
if (parent == null) {
return null;
}
@ -136,7 +141,7 @@ public class BuilderIntrospection implements Builder {
}
@Override
public void newElementFinished(final Object parent, final String tmpName, final Object element) throws ExmlException {
public void newElementFinished(final Object parent, final String tmpName, final Object element) throws ExmlException, AknotException {
Log.debug("new element fionished : ==> " + tmpName);
if (parent == null || element == null) {
return;
@ -163,7 +168,7 @@ public class BuilderIntrospection implements Builder {
}
@Override
public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlException {
public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlException, AknotException {
if (element == null) {
return;
}
@ -217,13 +222,13 @@ public class BuilderIntrospection implements Builder {
}
@Override
public Object newRoot() throws ExmlBuilderException {
public Object newRoot() throws ExmlBuilderException, AknotException {
final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.ARRAY, this.rootNodeName, this.rootClassType);
return new IntrospectionObject(inferData);
}
@Override
public void newText(final Object parent, final String text) throws ExmlException {
public void newText(final Object parent, final String text) throws ExmlException, AknotException {
if (parent == null) {
return;
}

View File

@ -1,34 +0,0 @@
package org.atriasoft.exml.builder;
import java.util.HashMap;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class CacheIntrospectionModel {
final Map<MapKey, IntrospectionModel> elements = new HashMap<>();
IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException {
MapKey key = new MapKey(model, name, classType);
IntrospectionModel out = this.elements.get(key);
if (out != null) {
return out;
}
if (model == ModelType.ARRAY) {
out = IntrospectionModelFactory.createModelArray(key.nodeName(), key);
} else if (model == ModelType.LIST) {
out = IntrospectionModelFactory.createModelList(key.nodeName(), key);
} else if (classType.isEnum()) {
out = IntrospectionModelFactory.createModelEnum(key);
} else {
out = IntrospectionModelFactory.createModel(key);
}
this.elements.put(key, out);
return out;
}
public CacheIntrospectionModel() {
}
}

View File

@ -1,132 +0,0 @@
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_ATTRIBUTE = false;
protected static final Boolean DEFAULT_IGNORE_UNBKNOWN = false;
protected static final Boolean DEFAULT_DEFAULT_NULL_VALUE = false;
protected static final Boolean DEFAULT_CASE_SENSITIVE = true;
protected static final Boolean DEFAULT_MANAGED = true;
protected static final Boolean DEFAULT_OPTIONAL = false;
protected boolean defaultNullValue = false;
protected boolean ignoreUnknown = false;
protected final Class<?> classType;
public IntrospectionModel(final Class<?> classType) {
this.classType = classType;
}
public Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
return null;
}
public List<IntrospectionProperty> getAttributes() {
return null;
}
public String getBeanName(final String nodeName) {
return nodeName;
}
public String getBeanNameModel(final String nodeName) {
return getBeanName(nodeName);
}
public Class<?> getClassType() {
return this.classType;
}
public List<String> getNodeAvaillable() {
return null;
}
public List<IntrospectionProperty> getNodes() {
return null;
}
public String getTextBeanName() {
// TODO Auto-generated method stub
return null;
}
public String getTreeNameOfSubNode(final String nodeName) throws ExmlBuilderException {
return null;
}
public Class<?> getTypeOfProperty(final String nodeName) throws ExmlBuilderException {
return null;
}
public Class<?> getTypeOfSubNode(final String nodeName) throws ExmlBuilderException {
return null;
}
public Class<?> getTypeOfSubNodeList(final String nodeName) throws ExmlBuilderException {
return null;
}
public Class<?> getTypeOfSubProperty(final String nodeName) throws ExmlBuilderException {
return null;
}
protected Class<?> getTypeOfText() {
return null;
}
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
public Object getValueFromText(final String text) throws ExmlBuilderException {
return null;
}
/**
* This permit to know if an alement in the property is able to manage the Whole text under (this remove all parsing of xml inside the model...) Annotation @XmlText
* @return true if a parameter manage the text (otherwise the text is sended to the fromString() function.
*/
public boolean hasTextModel() {
return false;
}
public boolean isArray() {
return false;
}
protected boolean isDefaultNullValue() {
return this.defaultNullValue;
}
public boolean isEnum() {
return this.classType.isEnum();
}
protected boolean isIgnoreUnknown() {
return this.ignoreUnknown;
}
public boolean isList() {
return false;
}
public boolean isNative() {
return false;
}
public boolean isObject(final String propertyName) {
return Object.class.isAssignableFrom(this.classType);
}
public boolean isRecord(final String propertyName) {
return Record.class.isAssignableFrom(this.classType);
}
public abstract String toString(final Object data) throws ExmlBuilderException;
}

View File

@ -1,76 +0,0 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.atriasoft.etk.util.ArraysTools;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelArray extends IntrospectionModel {
@SuppressWarnings("unchecked")
public static <T> T[] convertList(final Class<T> classType, final List<Object> data) {
final List<T> rootList = (List<T>) data;
final T[] strarr = (T[]) Array.newInstance(classType, 0);
return rootList.toArray(strarr);
}
final String nodeName;
public IntrospectionModelArray(final String nodeName, final Class<?> classType) {
super(classType);
this.nodeName = nodeName;
}
@Override
public Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
List<Object> tmp = null;
if (this.nodeName == null) {
tmp = nodes.get(IntrospectionObject.STUPID_TOCKEN);
} else {
tmp = nodes.get(this.nodeName);
}
if (tmp == null) {
return null;
}
if (this.classType.isPrimitive()) {
return ArraysTools.listToPrimitiveAuto(this.classType, tmp);
}
return IntrospectionModelArray.convertList(this.classType, tmp);
}
@Override
public List<String> getNodeAvaillable() {
if (this.nodeName != null) {
return Arrays.asList(this.nodeName);
}
return null;
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
return new Object[0];
}
@Override
public boolean hasTextModel() {
return false;
}
@Override
public boolean isArray() {
return true;
}
@Override
public String toString(final Object data) {
return null;
}
}

View File

@ -1,47 +0,0 @@
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
public 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
public List<String> getNodeAvaillable() {
return null;
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
//il y a un bug ici ...
return StringSerializer.valueOf(this.classType, text);
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
@Override
public boolean isNative() {
return true;
}
@Override
public String toString(final Object data) {
return StringSerializer.toString(data);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
package org.atriasoft.exml.builder;
import org.atriasoft.eStringSerialize.StringSerializer;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelFactory {
private IntrospectionModelFactory() {}
public static IntrospectionModel createModelArray(final String nodeName, final MapKey modelType) throws ExmlBuilderException {
return new IntrospectionModelArray(nodeName, modelType.type());
}
public static IntrospectionModel createModelList(final String nodeName, final MapKey modelType) throws ExmlBuilderException {
return new IntrospectionModelList(nodeName, modelType.type());
}
public static IntrospectionModel createModelEnum(final MapKey modelType) throws ExmlBuilderException {
return new IntrospectionModelComplex(modelType.type());
}
public static IntrospectionModel createModel(final MapKey modelType) throws ExmlBuilderException {
if (StringSerializer.contains(modelType.type())) {
return new IntrospectionModelBaseType(modelType.type());
}
return new IntrospectionModelComplex(modelType.type());
}
}

View File

@ -1,54 +0,0 @@
package org.atriasoft.exml.builder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionModelList extends IntrospectionModel {
final String nodeName;
public IntrospectionModelList(final String nodeName, final Class<?> classType) {
super(classType);
this.nodeName = nodeName;
}
@Override
public Object createObject(final Map<String, Object> properties, final Map<String, List<Object>> nodes) throws ExmlBuilderException {
if (this.nodeName == null) {
return nodes.get(IntrospectionObject.STUPID_TOCKEN);
}
return nodes.get(this.nodeName);
}
@Override
public List<String> getNodeAvaillable() {
if (this.nodeName != null) {
return Arrays.asList(this.nodeName);
}
return null;
}
@Override
public Object getValueFromText(final String text) throws ExmlBuilderException {
return new ArrayList<Object>();
}
@Override
public Object getValue(final String propertyName, final String propertyValue) throws ExmlBuilderException {
return null;
}
@Override
public boolean isList() {
return true;
}
@Override
public String toString(final Object data) {
return null;
}
}

View File

@ -1,168 +0,0 @@
package org.atriasoft.exml.builder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.exception.ExmlException;
import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
import org.atriasoft.exml.internal.Log;
public class IntrospectionObject {
public static final String PUBLIC_TEXT_NAME = "##<< ** TEXT-ZONE ** >>##";
public static final String STUPID_TOCKEN = "___aé\"'__-è==**ù!^$:;,;AZEARTYUIOPMLKJHGFDSQW>XCVBN?"; // can not exist ....
private final IntrospectionModel modelInterface;
private Object data = null;
private final Map<String, Object> properties = new HashMap<>();
private final Map<String, List<Object>> nodes = new HashMap<>();
public IntrospectionObject(final IntrospectionModel dataInterface) {
this.modelInterface = dataInterface;
}
@SuppressWarnings("unchecked")
public void addObject(final String nodeName, final Object value) throws ExmlException {
if (value == null) {
// specific case when a List is empty <links></links> but define for a specific list ==> need no action
return;
}
final String beanName = this.modelInterface.getBeanName(nodeName);
if (beanName == null) {
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
}
List<Object> node = this.nodes.get(beanName);
if (node == null) {
if (List.class.isAssignableFrom(value.getClass())) {
node = (List<Object>) value;
} else if (value.getClass().isArray()) {
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
} else {
node = new ArrayList<>();
node.add(value);
}
this.nodes.put(beanName, node);
} else if (value.getClass().isArray()) {
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
Log.error("this is a big problem ...");
} else if (List.class.isAssignableFrom(value.getClass())) {
final List<Object> nodeIn = (List<Object>) value;
node.addAll(nodeIn);
} else {
node.add(value);
}
}
public void generateTheObject() throws ExmlBuilderException {
if (this.data != null) {
// nothing to do ... ==> element already created
return;
}
Log.debug("Create the element for the Specific node ... type = " + this.modelInterface.getClassType().getCanonicalName() + (this.modelInterface.isArray() ? "[array]" : "")
+ (this.modelInterface.isList() ? "[List]" : ""));
Log.debug(" Properties : " + this.properties.keySet());
Log.debug(" Nodes : " + this.nodes.keySet());
this.data = this.modelInterface.createObject(this.properties, this.nodes);
}
public Object getData() {
return this.data;
}
public IntrospectionModel getModelIntrospection() {
return this.modelInterface;
}
public String getTreeNameOfSubNode(final String nodeName) throws ExmlException {
final String beanName = this.modelInterface.getBeanName(nodeName);
if (beanName == null) {
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
}
return this.modelInterface.getTreeNameOfSubNode(beanName);
}
public Class<?> getTypeOfProperty(final String nodeName) throws ExmlException {
final String beanName = this.modelInterface.getBeanName(nodeName);
if (beanName == null) {
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
}
return this.modelInterface.getTypeOfProperty(beanName);
}
/**
* 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
*/
public Class<?> getTypeOfSubNode(final String nodeName) throws ExmlException {
final String beanName = this.modelInterface.getBeanNameModel(nodeName);
if (beanName == null) {
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
}
return this.modelInterface.getTypeOfSubNode(beanName);
}
public Class<?> getTypeOfSubNodeSubType(final String nodeName) throws ExmlException {
final String beanName = this.modelInterface.getBeanNameModel(nodeName);
if (beanName == null) {
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
}
return this.modelInterface.getTypeOfSubNodeList(beanName);
}
public Class<?> getTypeOfSubProperty(final String nodeName) throws ExmlException {
final String beanName = this.modelInterface.getBeanName(nodeName);
if (beanName == null) {
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
}
return this.modelInterface.getTypeOfSubProperty(beanName);
}
public boolean isSubNodeOrPropertyExist(final String nodeName) {
final String beanName = this.modelInterface.getBeanName(nodeName);
if (beanName == null) {
return false;
}
return true;
}
public void putProperty(final String propertyName, final Object propertyValue) throws ExmlException {
String beanName = null;
if (propertyName == PUBLIC_TEXT_NAME) {
beanName = this.modelInterface.getTextBeanName();
} else {
beanName = this.modelInterface.getBeanName(propertyName);
}
if (this.properties.containsKey(beanName)) {
throw new ExmlBuilderException("Property have multiple values ==> impossible case; A Node must contain only 1 attibutes");
}
this.properties.put(beanName, propertyValue);
}
public void setText(final String text) throws ExmlBuilderException {
if (this.data != null) {
throw new ExmlBuilderException("Can not set multiple text value in a single NODE ...");
}
this.data = this.modelInterface.getValueFromText(text);
}
}

View File

@ -1,322 +0,0 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import org.atriasoft.aknot.model.InterfaceFactoryAccess;
import org.atriasoft.eStringSerialize.StringSerializer;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.internal.Log;
public final class IntrospectionProperty {
// if the element is not managed by us (set at null while not define by a function attribute, parameter ...)
private Boolean managed = null;
// Case sensitive in parsing XML or not (set at null while not define by a function attribute, parameter ...)
private Boolean caseSensitive = null;
// Optional or not (set at null while not define by a function attribute, parameter ...)
private Boolean optionnal = null;
// Attribute or Node (set at null while not define by a function attribute, parameter ...)
private Boolean attribute = null;
private Boolean textMode = null;
// name of the field or the function before renaming...
private final String beanName;
// names that can take the Node or the aatibute
private String[] names = null;
// if organized in sublist (!= null) then the subNode have this value
private String listName = null;
private boolean canBeSetByConstructor = false;
private Class<?> factory = null;
private InterfaceFactoryAccess factoryCreated = null;
private final Class<?> type;
private final Class<?> subType;
// can get the property, if null not gettable ... ==> TODO need to remove this property ???
// First function call
// second field access
IntrospectionPropertyGetter getter = null;
// can get the property, if null not settable (otherwise use the constructor???)
// First constructor call
// second function call
// third field access
IntrospectionPropertySetter setter = null;
public IntrospectionProperty(final String beanName, final Class<?>[] type, final String[] names) {
this.beanName = beanName;
this.type = type[0];
this.subType = type[1];
this.names = names;
}
public boolean canGetValue() {
return this.getter != null;
}
public boolean canSetValue() {
return this.canBeSetByConstructor || this.setter != null;
}
/**
* Create a value adapted to the property type.
* @apiNote generic type is transformed byte -> Byte, int -> Integer ...
* @param value Value to set in the Object
* @throws Exception An error occurred
* @return The object created
*/
public Object createValue(final String value) throws ExmlBuilderException {
try {
if (StringSerializer.contains(this.type)) {
// TODO This might be a deprecated code ....
return StringSerializer.valueOf(this.type, value);
}
if (this.type.isEnum()) {
} else 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);'");
}
final ArrayList<Object> out = new ArrayList<>();
for (final String elem : value.split(";")) {
out.add(StringSerializer.valueOf(this.subType, elem));
}
return out;
} catch (final IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Error in parsing the property value ... " + e.getMessage());
}
}
public String getBeanName() {
return this.beanName;
}
public Class<?> getCompatible(final String name) {
final InterfaceFactoryAccess factoryGenerator = getFactory();
if (factoryGenerator != null) {
if (this.caseSensitive) {
for (final Entry<String, Class<?>> elem : factoryGenerator.getConversionMap().entrySet()) {
if (elem.getKey().contentEquals(name)) {
return elem.getValue();
}
}
} else {
for (final Entry<String, Class<?>> elem : factoryGenerator.getConversionMap().entrySet()) {
if (elem.getKey().equalsIgnoreCase(name)) {
return elem.getValue();
}
}
}
return null;
}
if (this.caseSensitive) {
for (final String elem : this.names) {
if (elem.contentEquals(name)) {
Log.verbose(" - '{}' ==> true", elem);
return getType();
}
Log.verbose(" - '{}' == false", elem);
}
} else {
for (final String elem : this.names) {
if (elem.equalsIgnoreCase(name)) {
Log.verbose(" - '{}' ==> true", elem);
return getType();
}
Log.verbose(" - '{}' == false", elem);
}
}
return null;
}
public InterfaceFactoryAccess getFactory() {
if (this.factoryCreated == null && this.factory != null) {
try {
this.factoryCreated = (InterfaceFactoryAccess) this.factory.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.factoryCreated = null;
this.factory = null;
}
}
return this.factoryCreated;
}
public String getListName() {
return this.listName;
}
/**
* Get list of all names of the property/node (minimal 1 name)
* @return Array of names available
*/
public String[] getNames() {
return this.names;
}
/**
* Get the type of the property (if list ==> need to be get on method otherwise it is an Object...)
* @return Type of the list element.
*/
public Class<?> getSubType() {
return this.subType;
}
/**
* Get basic type of the property
* @return property type detected.
*/
public Class<?> getType() {
return this.type;
}
/**
* Get the value in the object.
* @param object Object that is invoke to get the value.
* @return The generate value of the object
* @throws ExmlBuilderException in an error occured
*/
public Object getValue(final Object object) throws ExmlBuilderException {
if (this.getter != null) {
return this.getter.getValue(object);
}
throw new ExmlBuilderException("Property: " + this.names + " have no getter");
}
public boolean hasFactory() {
return this.factory != null;
}
public Boolean isAttribute() {
return this.attribute;
}
public boolean isCanBeSetByConstructor() {
return this.canBeSetByConstructor;
}
public Boolean isCaseSensitive() {
return this.caseSensitive;
}
/**
* Check if the input name is compatible win an element in the list availlable (respect case sensitive if needed)
* @param name Name to check
* @return true if the element is compatible, false otherwise
*/
public boolean isCompatible(final String name) {
Log.verbose("Check compatible : '{}' in {}", name, Arrays.toString(this.names));
final InterfaceFactoryAccess factoryGenerator = getFactory();
if (factoryGenerator != null) {
Log.verbose(" ===> Detect factory !!!!");
if (this.caseSensitive) {
for (final Entry<String, Class<?>> elem : factoryGenerator.getConversionMap().entrySet()) {
if (elem.getKey().contentEquals(name)) {
Log.verbose(" + '{}' ==> true", elem.getKey());
return true;
}
Log.verbose(" + '{}' == false", elem.getKey());
}
} else {
for (final Entry<String, Class<?>> elem : factoryGenerator.getConversionMap().entrySet()) {
if (elem.getKey().equalsIgnoreCase(name)) {
Log.verbose(" + '{}' ==> true", elem.getKey());
return true;
}
Log.verbose(" + '{}' == false", elem.getKey());
}
}
return false;
}
if (this.caseSensitive) {
for (final String elem : this.names) {
if (elem.contentEquals(name)) {
Log.verbose(" - '{}' ==> true", elem);
return true;
}
Log.verbose(" - '{}' == false", elem);
}
} else {
for (final String elem : this.names) {
if (elem.equalsIgnoreCase(name)) {
Log.verbose(" - '{}' ==> true", elem);
return true;
}
Log.verbose(" - '{}' == false", elem);
}
}
return false;
}
public Boolean isManaged() {
return this.managed;
}
public Boolean isOptionnal() {
return this.optionnal;
}
public Boolean isText() {
return this.textMode;
}
public void setAttribute(final Boolean attribute) {
this.attribute = attribute;
}
public void setCanBeSetByConstructor(final boolean canBeSetByConstructor) {
this.canBeSetByConstructor = canBeSetByConstructor;
}
public void setCaseSensitive(final Boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
/**
* 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 void setExistingValue(final Object object, final Object value) throws ExmlBuilderException {
if (this.setter != null) {
this.setter.setValue(object, value);
return;
}
throw new ExmlBuilderException("Property: " + this.names + " have no setter");
}
public void setFactory(final Class<?> factory) {
this.factory = factory;
}
public void setGetter(final IntrospectionPropertyGetter getter) {
this.getter = getter;
}
public void setListName(final String listName) {
this.listName = listName;
}
public void setManaged(final Boolean managed) {
this.managed = managed;
}
public void setNames(final String[] names) {
this.names = names;
}
public void setOptionnal(final Boolean optionnal) {
this.optionnal = optionnal;
}
public void setSetter(final IntrospectionPropertySetter setter) {
this.setter = setter;
}
public void setTextMode(final Boolean isText) {
this.textMode = isText;
}
}

View File

@ -1,43 +0,0 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionPropertyField implements IntrospectionPropertyGetter, IntrospectionPropertySetter {
private final Field fieldDescription;
private final boolean finalValue;
public IntrospectionPropertyField(final Field fieldDescription) {
this.fieldDescription = fieldDescription;
this.finalValue = Modifier.isFinal(fieldDescription.getModifiers());
}
@Override
public Object getValue(final Object object) throws ExmlBuilderException {
try {
return this.fieldDescription.get(object);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
}
}
@Override
public void setValue(final Object object, final Object value) throws ExmlBuilderException {
if (this.finalValue) {
throw new ExmlBuilderException("Can not set value The value is FINAL!!!");
}
try {
this.fieldDescription.set(object, value);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
}
}
}

View File

@ -1,7 +0,0 @@
package org.atriasoft.exml.builder;
import org.atriasoft.exml.exception.ExmlBuilderException;
public interface IntrospectionPropertyGetter {
Object getValue(Object object) throws ExmlBuilderException;
}

View File

@ -1,74 +0,0 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionPropertyMethodGetter implements IntrospectionPropertyGetter {
// private static Class<?>[] getTypefunction(final Method setter, final Method getter) throws Exception {
// Class<?> type = null;
// Class<?> subType = null;
// if (setter == null && getter == null) {
// // impossible case...
// throw new Exception("kjhkhjkj");
// }
// if (getter != null) {
// type = getter.getReturnType();
// if (Enum.class.isAssignableFrom(type)) {
// Log.verbose("Find an enum ...");
// } else {
// Type empppe = getter.getGenericReturnType();
// if (empppe instanceof ParameterizedType plopppppp) {
// Type[] realType = plopppppp.getActualTypeArguments();
// if (realType.length > 0) {
// subType = Class.forName(realType[0].getTypeName());
// }
// }
// }
// }
// if (setter != null) {
// if (type != null && setter.getParameters()[0].getType() != type) {
// throw new Exception("The type of the setter ands the type return by the getter are not the same ...");
// }
// type = setter.getParameters()[0].getType();
// if (List.class.isAssignableFrom(type)) {
// Class<?> internalModelClass = null;
// Type[] empppe = setter.getGenericParameterTypes();
// if (empppe.length > 0) {
// if (empppe[0] instanceof ParameterizedType plopppppp) {
// Type[] realType = plopppppp.getActualTypeArguments();
// if (realType.length > 0) {
// Log.warning(" -->> " + realType[0]);
// internalModelClass = Class.forName(realType[0].getTypeName());
// }
// }
// }
// if (getter!=null && internalModelClass != subType) {
// throw new Exception("The type of the setter and the type return by the getter are not the same ...");
// }
// subType = internalModelClass;
// }
// }
// return new Class<?>[] {type, subType};
// }
//
protected Method getter;
public IntrospectionPropertyMethodGetter(final Method getter) throws Exception {
this.getter = getter;
}
@Override
public Object getValue(final Object object) throws ExmlBuilderException {
if (this.getter == null) {
throw new ExmlBuilderException("no getter availlable");
}
try {
return this.getter.invoke(object);
} catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
e.printStackTrace();
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
}
}
}

View File

@ -1,28 +0,0 @@
package org.atriasoft.exml.builder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.atriasoft.exml.exception.ExmlBuilderException;
public class IntrospectionPropertyMethodSetter implements IntrospectionPropertySetter {
protected Method setter;
public IntrospectionPropertyMethodSetter(final Method setter) throws Exception {
this.setter = setter;
}
@Override
public void setValue(final Object object, final Object value) throws ExmlBuilderException {
if (this.setter == null) {
throw new ExmlBuilderException("no setter availlable");
}
try {
this.setter.invoke(object, value);
} catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ExmlBuilderException("Can not set value ... " + e.getMessage());
}
}
}

View File

@ -1,13 +0,0 @@
package org.atriasoft.exml.builder;
import org.atriasoft.exml.exception.ExmlBuilderException;
public interface IntrospectionPropertySetter {
/**
* 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
*/
void setValue(Object object, Object value) throws ExmlBuilderException;
}

View File

@ -1,14 +0,0 @@
package org.atriasoft.exml.builder;
public record MapKey (ModelType model,
String nodeName,
Class<?> type) {
public MapKey(final ModelType model, final String nodeName, final Class<?> type) {
this.model = model;
this.nodeName = nodeName;
this.type = type;
}
public MapKey(final ModelType model, final Class<?> type) {
this(model, null, type);
}
}

View File

@ -1,7 +0,0 @@
package org.atriasoft.exml.builder;
public enum ModelType {
NORMAL,
ARRAY,
LIST
}

View File

@ -1,6 +1,6 @@
package org.atriasoft.exml.exception;
import org.atriasoft.exml.parser.FilePos;
import org.atriasoft.etk.util.FilePos;
public class ExmlParserError extends ExmlBuilderException {
private static final long serialVersionUID = 1L;

View File

@ -4,15 +4,16 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.atriasoft.aknot.exception.AknotException;
import org.atriasoft.aknot.model.IntrospectionModel;
import org.atriasoft.aknot.model.MapKey;
import org.atriasoft.aknot.model.ModelType;
import org.atriasoft.aknot.pojo.IntrospectionModelFactory;
import org.atriasoft.aknot.pojo.IntrospectionProperty;
import org.atriasoft.etk.Tools;
import org.atriasoft.etk.util.ArraysTools;
import org.atriasoft.exml.builder.IntrospectionModel;
import org.atriasoft.exml.builder.IntrospectionModelFactory;
import org.atriasoft.exml.builder.IntrospectionProperty;
import org.atriasoft.exml.builder.MapKey;
import org.atriasoft.exml.builder.ModelType;
import org.atriasoft.exml.exception.ExmlBuilderException;
import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.parser.Tools;
public class GeneratorIntrospection implements Generator {
// Keep in cache all the object already parsed ==> optimize CPU
@ -24,13 +25,39 @@ public class GeneratorIntrospection implements Generator {
public GeneratorIntrospection(final ModelType model, final Class<?> classType, final String rootNodeName) throws Exception {
this.rootNodeName = rootNodeName;
this.rootClassType = classType;
MapKey key = new MapKey(model, classType);
final MapKey key = new MapKey(model, classType);
// TODO pb if it is a List or an Array ...
this.elements.put(key, IntrospectionModelFactory.createModel(key));
}
IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException {
MapKey key = new MapKey(model, name, classType);
private <T> String autoArrayToString(final Class<T> clazz, final Object inData, final IntrospectionModel model) throws ExmlBuilderException, AknotException {
@SuppressWarnings("unchecked")
final T[] datas = (T[]) inData;
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < datas.length; iii++) {
if (!out.isEmpty()) {
out.append(";");
}
out.append(model.toString(datas[iii]));
}
return out.toString();
}
private <T> String autoListToString(final Class<T> clazz, final Object inData, final IntrospectionModel model) throws ExmlBuilderException, AknotException {
@SuppressWarnings("unchecked")
final List<T> elements1 = (List<T>) inData;
final StringBuilder out = new StringBuilder();
for (final Object elem1 : elements1) {
if (!out.isEmpty()) {
out.append(";");
}
out.append(model.toString(elem1));
}
return out.toString();
}
IntrospectionModel findOrCreate(final ModelType model, final String name, final Class<?> classType) throws ExmlBuilderException, AknotException {
final MapKey key = new MapKey(model, name, classType);
IntrospectionModel out = this.elements.get(key);
if (out != null) {
return out;
@ -46,151 +73,61 @@ public class GeneratorIntrospection implements Generator {
return out;
}
private <T> String autoArrayToString(final Class<T> clazz, final Object inData, final IntrospectionModel model) throws ExmlBuilderException {
@SuppressWarnings("unchecked")
T[] datas = (T[])inData;
StringBuilder out = new StringBuilder();
for(int iii=0; iii<datas.length; iii++) {
if (!out.isEmpty()) {
out.append(";");
}
out.append(model.toString(datas[iii]));
}
return out.toString();
public void generate(final Object root, final StringBuilder tmpp) throws ExmlBuilderException, AknotException {
final IntrospectionModel introspection = findOrCreate(ModelType.NORMAL, null, root.getClass());
generateNode(root, introspection, this.rootNodeName, tmpp, 0);
}
private <T> String autoListToString(final Class<T> clazz, final Object inData, final IntrospectionModel model) throws ExmlBuilderException {
@SuppressWarnings("unchecked")
List<T> elements1 = (List<T>)inData;
StringBuilder out = new StringBuilder();
for (Object elem1: elements1) {
if (!out.isEmpty()) {
out.append(";");
}
out.append(model.toString(elem1));
}
return out.toString();
}
public void generateProperties(final Object data, final IntrospectionModel introspection, final StringBuilder tmpp) throws ExmlBuilderException {
List<IntrospectionProperty> elements = introspection.getAttributes();
if (elements == null) {
return;
}
for (IntrospectionProperty elem : elements) {
if (!elem.canGetValue()) {
continue;
}
Object dataObj = elem.getValue(data);
if (dataObj == null) {
continue;
}
String name = elem.getNames()[0];
Class<?> type = elem.getType();
String dataString = null;
if (type.isArray()) {
Class<?> typeClass = elem.getType().componentType();
if (typeClass.isPrimitive()) {
dataString = ArraysTools.primitivaArrayToSting(dataObj);
} else {
IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, typeClass);
dataString = autoArrayToString(typeClass, dataObj, introspectionSub);
}
} else if (List.class.isAssignableFrom(type)) {
Class<?> typeClass = elem.getSubType();
IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, typeClass);
dataString = autoListToString(typeClass, dataObj, introspectionSub);
} else {
IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, dataObj.getClass());
dataString = introspectionSub.toString(dataObj);
}
if (dataString != null) {
tmpp.append(" ");
tmpp.append(name);
tmpp.append("=\"");
tmpp.append(dataString);
tmpp.append("\"");
}
}
}
public void generateSubNodes(final Object data, final IntrospectionModel introspection, final StringBuilder tmpp, final int indent) throws ExmlBuilderException {
List<IntrospectionProperty> elements = introspection.getNodes();
for (IntrospectionProperty elem : elements) {
if (!elem.canGetValue()) {
continue;
}
Object dataObj = elem.getValue(data);
if (dataObj == null) {
continue;
}
String name = elem.getNames()[0];
Class<?> type = elem.getType();
IntrospectionModel introspectionSub = null;
if (type.isArray()) {
Class<?> typeClass = elem.getType().componentType();
String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.ARRAY, listTreeName, typeClass);
} else if (List.class.isAssignableFrom(type)) {
Class<?> typeClass = elem.getSubType();
String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.LIST, listTreeName, typeClass);
} else {
introspectionSub = findOrCreate(ModelType.NORMAL, null, dataObj.getClass());
}
generateNode(dataObj, introspectionSub, name, tmpp, indent);
}
}
public <T> void generateArrayNode(final Class<T> clazz, final Object data, final IntrospectionModel model, final String nodeName, final StringBuilder tmpp, final int indent) throws ExmlBuilderException {
public <T> void generateArrayNode(final Class<T> clazz, final Object data, final IntrospectionModel model, final String nodeName, final StringBuilder tmpp, final int indent)
throws ExmlBuilderException, AknotException {
//Class<?> clazzData = data.getClass();
if (clazz.isPrimitive()) {
if (clazz == byte.class) {
byte[] datas = (byte[]) data;
for (int iii=0; iii<datas.length; iii++) {
final byte[] datas = (byte[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
} else if (clazz == boolean.class) {
boolean[] datas = (boolean[]) data;
for (int iii=0; iii<datas.length; iii++) {
final boolean[] datas = (boolean[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
} else if (clazz == short.class) {
short[] datas = (short[]) data;
for (int iii=0; iii<datas.length; iii++) {
final short[] datas = (short[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
} else if (clazz == int.class) {
int[] datas = (int[]) data;
for (int iii=0; iii<datas.length; iii++) {
final int[] datas = (int[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
} else if (clazz == long.class) {
long[] datas = (long[]) data;
for (int iii=0; iii<datas.length; iii++) {
final long[] datas = (long[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
} else if (clazz == float.class) {
float[] datas = (float[]) data;
for (int iii=0; iii<datas.length; iii++) {
final float[] datas = (float[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
} else if (clazz == double.class) {
double[] datas = (double[]) data;
for (int iii=0; iii<datas.length; iii++) {
final double[] datas = (double[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
}
return;
}
@SuppressWarnings("unchecked")
T[] datas = (T[]) data;
for (int iii=0; iii<datas.length; iii++) {
final T[] datas = (T[]) data;
for (int iii = 0; iii < datas.length; iii++) {
generateNode(datas[iii], model, nodeName, tmpp, indent);
}
}
public void generateNode(final Object data, final IntrospectionModel model, final String nodeName, final StringBuilder tmpp, final int indent) throws ExmlBuilderException {
public void generateNode(final Object data, final IntrospectionModel model, final String nodeName, final StringBuilder tmpp, final int indent) throws ExmlBuilderException, AknotException {
if (model.isNative()) {
Tools.addIndent(tmpp, indent);
tmpp.append("<");
@ -201,8 +138,8 @@ public class GeneratorIntrospection implements Generator {
tmpp.append(nodeName);
tmpp.append(">");
} else if (model.isArray()) {
List<String> baseName = model.getNodeAvaillable();
IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, model.getClassType());
final List<String> baseName = model.getNodeAvaillable();
final IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, model.getClassType());
if (baseName == null || baseName.size() == 0) {
// mode render : <nodeName>aaa</nodeName><nodeName>bbb</nodeName>
generateArrayNode(model.getClassType(), data, introspectionSub, nodeName, tmpp, indent);
@ -212,7 +149,7 @@ public class GeneratorIntrospection implements Generator {
tmpp.append("<");
tmpp.append(nodeName);
tmpp.append(">");
generateArrayNode(model.getClassType(), data, introspectionSub, baseName.get(0), tmpp, indent+1);
generateArrayNode(model.getClassType(), data, introspectionSub, baseName.get(0), tmpp, indent + 1);
Tools.addIndent(tmpp, indent);
tmpp.append("</");
tmpp.append(nodeName);
@ -220,14 +157,14 @@ public class GeneratorIntrospection implements Generator {
}
Log.error("lkjlk");
} else if (model.isList()) {
List<String> baseName = model.getNodeAvaillable();
final List<String> baseName = model.getNodeAvaillable();
@SuppressWarnings("unchecked")
List<Object> datas = (List<Object>)data;
final List<Object> datas = (List<Object>) data;
if (baseName == null || baseName.size() == 0) {
// mode render : <nodeName>aaa</nodeName><nodeName>bbb</nodeName>
for (Object elem : datas) {
for (final Object elem : datas) {
// note the type can change in List ...
IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, elem.getClass());
final IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, elem.getClass());
generateNode(elem, introspectionSub, nodeName, tmpp, indent);
}
} else {
@ -236,10 +173,10 @@ public class GeneratorIntrospection implements Generator {
tmpp.append("<");
tmpp.append(nodeName);
tmpp.append(">");
for (Object elem : datas) {
for (final Object elem : datas) {
// note the type can change in List ...
IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, elem.getClass());
generateNode(elem, introspectionSub, baseName.get(0), tmpp, indent+1);
final IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, elem.getClass());
generateNode(elem, introspectionSub, baseName.get(0), tmpp, indent + 1);
}
//tmpp.append(model.toString(data));
Tools.addIndent(tmpp, indent);
@ -274,8 +211,74 @@ public class GeneratorIntrospection implements Generator {
}
}
public void generate(final Object root, final StringBuilder tmpp) throws ExmlBuilderException {
IntrospectionModel introspection = findOrCreate(ModelType.NORMAL, null, root.getClass());
generateNode(root, introspection, this.rootNodeName, tmpp, 0);
public void generateProperties(final Object data, final IntrospectionModel introspection, final StringBuilder tmpp) throws ExmlBuilderException, AknotException {
final List<IntrospectionProperty> elements = introspection.getAttributes();
if (elements == null) {
return;
}
for (final IntrospectionProperty elem : elements) {
if (!elem.canGetValue()) {
continue;
}
final Object dataObj = elem.getValue(data);
if (dataObj == null) {
continue;
}
final String name = elem.getNames()[0];
final Class<?> type = elem.getType();
String dataString = null;
if (type.isArray()) {
final Class<?> typeClass = elem.getType().componentType();
if (typeClass.isPrimitive()) {
dataString = ArraysTools.primitivaArrayToSting(dataObj);
} else {
final IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, typeClass);
dataString = autoArrayToString(typeClass, dataObj, introspectionSub);
}
} else if (List.class.isAssignableFrom(type)) {
final Class<?> typeClass = elem.getSubType();
final IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, typeClass);
dataString = autoListToString(typeClass, dataObj, introspectionSub);
} else {
final IntrospectionModel introspectionSub = findOrCreate(ModelType.NORMAL, null, dataObj.getClass());
dataString = introspectionSub.toString(dataObj);
}
if (dataString != null) {
tmpp.append(" ");
tmpp.append(name);
tmpp.append("=\"");
tmpp.append(dataString);
tmpp.append("\"");
}
}
}
public void generateSubNodes(final Object data, final IntrospectionModel introspection, final StringBuilder tmpp, final int indent) throws ExmlBuilderException, AknotException {
final List<IntrospectionProperty> elements = introspection.getNodes();
for (final IntrospectionProperty elem : elements) {
if (!elem.canGetValue()) {
continue;
}
final Object dataObj = elem.getValue(data);
if (dataObj == null) {
continue;
}
final String name = elem.getNames()[0];
final Class<?> type = elem.getType();
IntrospectionModel introspectionSub = null;
if (type.isArray()) {
final Class<?> typeClass = elem.getType().componentType();
final String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.ARRAY, listTreeName, typeClass);
} else if (List.class.isAssignableFrom(type)) {
final Class<?> typeClass = elem.getSubType();
final String listTreeName = elem.getListName();
introspectionSub = findOrCreate(ModelType.LIST, listTreeName, typeClass);
} else {
introspectionSub = findOrCreate(ModelType.NORMAL, null, dataObj.getClass());
}
generateNode(dataObj, introspectionSub, name, tmpp, indent);
}
}
}

View File

@ -5,7 +5,7 @@
*/
package org.atriasoft.exml.model;
import org.atriasoft.exml.parser.FilePos;
import org.atriasoft.etk.util.FilePos;
/**
* Single attribute element

View File

@ -1,185 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2021, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
package org.atriasoft.exml.parser;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
/**
* Position in the file of the original data.
*/
public class FilePos {
private int col; //!< source text colomn
private int line; //!< source Line colomn
/**
* default contructor (set line and col at 0)
*/
public FilePos() {
this.col = 0;
this.line = 0;
}
/**
* initialize constructor
* @param line Line in the file
* @param col Colomn in the file
*/
public FilePos(final int line, final int col) {
this.col = col;
this.line = line;
}
/**
* Addition operator
* @param obj Addition object..
* @return Reference on this
*/
public FilePos add(final FilePos obj) {
if (obj.line == 0) {
this.col += obj.col;
} else {
this.col = obj.col;
this.line += obj.line;
}
return this;
}
/**
* Colomn addition operator
* @param col Number of colomn to add
* @return Reference on this
*/
public FilePos add(final int col) {
this.col += col;
return this;
}
/**
* Check if the value is a new line and update internal property
* @param val Char value to check
* @return true We find a new line
* @return false We NOT find a new line
*/
public boolean check(final Character val) {
this.col++;
if (val == '\n') {
newLine();
return true;
}
return false;
}
/**
* Reset position at 0,0
*/
public void clear() {
this.col = 0;
this.line = 0;
}
@Override
public FilePos clone() {
final FilePos out = new FilePos();
out.col = this.col;
out.line = this.line;
return out;
}
/**
* Decrement the colomn position
* @return Reference on this
*/
public FilePos decrement() {
this.col--;
return this;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof FilePos)) {
return false;
}
final FilePos other = (FilePos) obj;
return this.col == other.col && this.line == other.line;
}
/**
* Get the colomn position
* @return Colomn in number of utf8-char
*/
public int getCol() {
return this.col;
}
/**
* Get the line number position
* @return line ID (start at 0)
*/
public int getLine() {
return this.line;
}
@Override
public int hashCode() {
return super.hashCode() + this.line + this.col;
}
/**
* Increment the colomn position
* @return Reference on this
*/
public FilePos increment() {
this.col++;
return this;
}
/**
* Find a new line & reset colomn at 0
*/
public void newLine() {
this.col = 0;
this.line++;
}
/**
* Asignment operator
* @param obj Object to copy
* @return Reference on this
*/
public FilePos set(final FilePos obj) {
this.col = obj.col;
this.line = obj.line;
return this;
}
/**
* Setter of specific data
* @param line Line in the file
* @param col Colomn in the file
*/
public void set(final int line, final int col) {
this.col = col;
this.line = line;
}
@Override
public String toString() {
String out = "(l=";
out += this.line;
out += ",c=";
out += this.col;
out += ")";
return out;
}
}

View File

@ -1,5 +1,8 @@
package org.atriasoft.exml.parser;
import org.atriasoft.aknot.exception.AknotException;
import org.atriasoft.etk.Tools;
import org.atriasoft.etk.util.FilePos;
import org.atriasoft.exml.builder.Builder;
import org.atriasoft.exml.exception.ExmlException;
import org.atriasoft.exml.exception.ExmlParserError;
@ -14,7 +17,8 @@ public class ParseXml {
this.builder = builder;
}
protected boolean iParseAttribute(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlException {
protected boolean iParseAttribute(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlException, AknotException {
Log.verbose("start parse : 'attribute'");
// search end of the comment :
int lastElementName = pos.value;
@ -105,7 +109,8 @@ public class ParseXml {
return true;
}
protected boolean iParseCDATA(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlException {
protected boolean iParseCDATA(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlException, AknotException {
Log.verbose("start parse : 'text::CDATA'");
// search end of the comment :
for (int iii = pos.value; iii + 2 < data.length(); iii++) {
@ -128,7 +133,8 @@ public class ParseXml {
return false;
}
protected boolean iParseComment(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlException {
protected boolean iParseComment(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlException, AknotException {
Log.verbose("start parse : 'comment'");
final FilePos tmpPos = new FilePos();
final int white = Tools.countWhiteChar(data, pos.value, tmpPos);
@ -162,7 +168,8 @@ public class ParseXml {
return false;
}
protected boolean iParseDeclaration(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlException {
protected boolean iParseDeclaration(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlException, AknotException {
// search end of the comment :
for (int iii = pos.value; iii + 1 < data.length(); iii++) {
Tools.drawElementParsed(data.charAt(iii), filePos);
@ -217,7 +224,7 @@ public class ParseXml {
}
protected boolean iParseElement(final Object parent, final String nameElement, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlException {
throws ExmlException, AknotException {
// note : When start parsing the upper element must have set the value of the element and set the position after this one
// find a normal node ...
for (int iii = pos.value; iii < data.length(); iii++) {
@ -335,7 +342,7 @@ public class ParseXml {
return data.length();
}
protected boolean iParseText(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlException {
protected boolean iParseText(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlException, AknotException {
Log.verbose("start parse : 'text'");
if (this.builder.isPackText(parent)) {
final int endOfText = iParseFindTextPackEnd(data, pos.value);
@ -375,7 +382,7 @@ public class ParseXml {
return false;
}
public Object parse(final String data, final ParsingProperty property) throws ExmlException {
public Object parse(final String data, final ParsingProperty property) throws ExmlException, AknotException {
Log.verbose("Start parsing document (type: string) size=" + data.length());
// came from char == > force in utf8 ...
final FilePos pos = new FilePos(1, 0);
@ -405,7 +412,7 @@ public class ParseXml {
* @throws ExmlException
*/
protected boolean subParseElement(final Object parent, final String nameElement, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlException {
throws ExmlException, AknotException {
//EXMLPARSEELEMENT(" start subParse ... " << pos << " " << filePos);
for (int iii = pos.value; iii < data.length(); iii++) {
filePos.check(data.charAt(iii));

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.atriasoft.etk.Tools;
import org.atriasoft.exml.exception.ExmlParserError;
import org.atriasoft.exml.internal.Log;

View File

@ -1,493 +0,0 @@
package org.atriasoft.exml.parser;
public class Tools {
/**
* add indentation of the string input.
* @param data String where the indentation is done.
* @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");
}
}
/**
* check if an element or attribute is availlable (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \\n\\t\\r and for first char : not -.0123456789).
* @param val Value to check the conformity.
* @param firstChar True if the element check is the first char.
* @return true The value can be a part of attribute name
* @return false The value can NOT be a part of attribute name
*/
public static boolean checkAvaillable(final Character val, final boolean firstChar) {
if (val == '!' || val == '"' || val == '#' || val == '$' || val == '%' || val == '&' || val == '\'' || val == '(' || val == ')' || val == '*' || val == '+' || val == ',' || val == '/'
|| val == ';' || val == '<' || val == '=' || val == '>' || val == '?' || val == '@' || val == '[' || val == '\\' || val == ']' || val == '^' || val == '`' || val == '{' || val == '|'
|| val == '}' || val == '~' || val == ' ' || val == '\n' || val == '\t' || val == '\r') {
return false;
}
if (firstChar) {
if (val == '-' || val == '.' || (val >= '0' && val <= '9')) {
return false;
}
}
return true;
}
public static boolean checkNumber(final Character val, final boolean firstChar) {
if (val == '.' || (val >= '0' && val <= '9')) {
return true;
}
if (firstChar && val == '-') {
return true;
}
return false;
}
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 data Data to parse.
* @param pos Start position in the string.
* @param filePos new poistion of te file to add.
* @return number of white element.
*/
public static int countWhiteChar(final String data, final int pos, final FilePos filePos) {
filePos.clear();
int white = 0;
for (int iii = pos; iii < data.length(); iii++) {
filePos.check(data.charAt(iii));
if (!Tools.isWhiteChar(data.charAt(iii))) {
break;
}
white++;
}
filePos.decrement();
return white;
}
public static String createPosPointer(final String line, final int pos) {
final StringBuilder out = new StringBuilder();
int iii;
for (iii = 0; iii < pos && iii < line.length(); iii++) {
if (line.charAt(iii) == '\t') {
out.append("\t");
} else {
out.append(" ");
}
}
for (; iii < pos; iii++) {
out.append(" ");
}
out.append("^");
return out.toString();
}
// based on this: https://stackoverflow.com/questions/4052840/most-efficient-way-to-make-the-first-character-of-a-string-lower-case
public static String decapitalizeFirst(final String string) {
if (string == null || string.length() == 0) {
return string;
}
final char[] c = string.toCharArray();
c[0] = Character.toLowerCase(c[0]);
return new String(c);
}
/**
* Display the cuurent element that is curently parse.
* @param val Char that is parsed.
* @param filePos Position of the char in the file.
*/
public static void drawElementParsed(final Character val, final FilePos filePos) {
// if (val == '\n') {
// Log.error(filePos + " parse '\\n'");
// } else if (val == '\t') {
// Log.error(filePos + " parse '\\t'");
// } else {
// Log.error(filePos + " parse '" + val + "'");
// }
}
public static String extractLine(final String data, final int pos) {
// search back : '\n'
int startPos = data.lastIndexOf('\n', pos);
if (startPos == pos) {
startPos = 0;
} else {
startPos++;
}
// search forward : '\n'
int stopPos = pos;
if (data.length() == pos) {
stopPos = pos;
} else if (data.charAt(pos) != '\n') {
stopPos = data.indexOf('\n', pos);
if (stopPos == pos) {
stopPos = data.length();
}
}
if (startPos == -1) {
startPos = 0;
} else if (startPos >= data.length()) {
return "";
}
if (stopPos == -1) {
return "";
}
if (stopPos >= data.length()) {
stopPos = data.length();
}
return data.substring(startPos, stopPos);
}
public static boolean isWhiteChar(final Character val) {
if (val == ' ' || val == '\t' || val == '\n' || val == '\r') {
return true;
}
return false;
}
public static Boolean[] parseBooleanClassStringList(String data) {
data = Tools.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) {
data = Tools.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.parseBoolean(str);
}
return out;
}
public static Byte[] parseByteClassStringList(String data) {
data = Tools.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) {
data = Tools.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 Double[] parseDoubleClassStringList(String data) {
data = Tools.cleanNumberList(data);
final String[] dataArray = data.split(";");
final Double[] out = new Double[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Double.parseDouble(str);
}
return out;
}
public static double[] parseDoubleStringList(String data) {
data = Tools.cleanNumberList(data);
final String[] dataArray = data.split(";");
final double[] out = new double[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Double.parseDouble(str);
}
return out;
}
public static Float[] parseFloatClassStringList(String data) {
data = Tools.cleanNumberList(data);
final String[] dataArray = data.split(";");
final Float[] out = new Float[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Float.parseFloat(str);
}
return out;
}
public static float[] parseFloatStringList(String data) {
data = Tools.cleanNumberList(data);
final String[] dataArray = data.split(";");
final float[] out = new float[dataArray.length];
int count = 0;
for (final String str : dataArray) {
out[count++] = Float.parseFloat(str);
}
return out;
}
public static Integer[] parseIntegerClassStringList(String data) {
data = Tools.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) {
data = Tools.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) {
data = Tools.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) {
data = Tools.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) {
data = Tools.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) {
data = Tools.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;" == ">"
// "&amp;" == "&"
// "&apos;" == "'"
// "&quot;" == """
public static String replaceSpecialChar(final String inval) {
String out = inval;
out = out.replace("&lt;", "<");
out = out.replace("&gt;", ">");
out = out.replace("&apos;", "'");
out = out.replace("&quot;", "\"");
out = out.replace("&amp;", "&");
//EXMLERROR("INNN '"<< inval << "' => '" << out << "'");
return out;
}
public static String replaceSpecialCharOut(final String inval) {
String out = inval;
out = out.replace("<", "&lt;");
out = out.replace(">", "&gt;");
out = out.replace("'", "&apos;");
out = out.replace("\"", "&quot;");
out = out.replace("&", "&amp;");
//EXMLERROR("OUTTT '"<< inval << "' => '" << out << "'");
return out;
}
public static String toString(final boolean[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Boolean[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final byte[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Byte[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final double[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Double[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final float[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Float[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final int[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Integer[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final long[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Long[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final short[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
public static String toString(final Short[] data) {
final StringBuilder out = new StringBuilder();
for (int iii = 0; iii < data.length; iii++) {
if (iii != 0) {
out.append(";");
}
out.append(data[iii]);
}
return out.toString();
}
private Tools() {}
}

View File

@ -2,6 +2,7 @@ package org.atriasoft.exml.serializer;
import java.util.List;
import org.atriasoft.etk.Tools;
import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.model.XmlAttribute;
import org.atriasoft.exml.model.XmlAttributeList;
@ -11,7 +12,6 @@ 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.Tools;
public class SerializerXml {
public static void serialize(final XmlNode node, final StringBuilder data, final int indent) {
@ -45,7 +45,7 @@ public class SerializerXml {
private static void serializeComment(final XmlComment comment, final StringBuilder data, final int indent) {
Tools.addIndent(data, indent);
data.append("<!--");
String commentData = comment.getValue();
final String commentData = comment.getValue();
if (commentData != null) {
data.append(comment.getValue());
}
@ -76,7 +76,7 @@ public class SerializerXml {
Log.verbose(" generate : '" + data + "'");
} else {
data.append(">");
for (XmlNode node : nodes) {
for (final XmlNode node : nodes) {
if (node != null) {
SerializerXml.serialize(node, data, indent + 1);
}

View File

@ -2,6 +2,7 @@ package org.atriasoft.exml.serializer;
import java.util.List;
import org.atriasoft.etk.Tools;
import org.atriasoft.exml.generator.Generator;
import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.model.XmlAttribute;
@ -13,7 +14,6 @@ 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) {
@ -75,7 +75,7 @@ public class SerializerXmlIntrospection {
Log.verbose(" generate : '" + data + "'");
} else {
data.append(">\n");
for (XmlNode node : nodes) {
for (final XmlNode node : nodes) {
if (node != null) {
SerializerXmlIntrospection.serialize(node, data, indent + 1);
}
@ -103,6 +103,7 @@ public class SerializerXmlIntrospection {
}
private final Generator generator;
public SerializerXmlIntrospection(final Generator generator) {
this.generator = generator;
}
@ -110,7 +111,5 @@ public class SerializerXmlIntrospection {
public void generate(final Object root, final ParsingProperty property, final StringBuilder tmpp) {
//property.append(Tools.replaceSpecialCharOut(root.getValue()));
}
}

View File

@ -5,10 +5,10 @@
*/
package test.atriasoft.exml;
import org.atriasoft.aknot.exception.AknotException;
import org.atriasoft.exml.Exml;
import org.atriasoft.exml.exception.ExmlException;
import org.atriasoft.exml.model.XmlNode;
import org.junit.jupiter.api.Assertions;
class ExmlLocal {
@ -25,13 +25,17 @@ class ExmlLocal {
root = Exml.parse(input);
if (errorPos == 1) {
Assertions.fail("Must have detected an error");
}
} catch (final AknotException e) {
if (errorPos == 1) {
return;
}
Assertions.fail("Must have NOT detected an AknotException error");
} catch (final ExmlException e) {
if (errorPos == 1) {
return;
}
Assertions.fail("Must have NOT detected an error");
Assertions.fail("Must have NOT detected an ExmlException error");
}
final StringBuilder out = new StringBuilder();
// TODO 2 is for failing in generate ...