[DEV] correct somes bugs

This commit is contained in:
Edouard DUPIN 2021-03-29 00:17:00 +02:00
parent f81392846a
commit c1ef21754d
27 changed files with 657 additions and 689 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false"> <fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
<fileset name="all" enabled="true" check-config-name="ewol" local="false"> <fileset name="all" enabled="true" check-config-name="Ewol" local="false">
<file-match-pattern match-pattern="." include-pattern="true"/> <file-match-pattern match-pattern="." include-pattern="true"/>
</fileset> </fileset>
</fileset-config> </fileset-config>

14
exml.iml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/src" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="etk" exported="" />
<orderEntry type="library" scope="TEST" name="org.junit.jupiter:junit-jupiter-api:5.7.1" level="project" />
</component>
</module>

View File

@ -26,22 +26,23 @@ public class Exml {
/** /**
* Display the Document on console * Display the Document on console
*/ */
public static void display() { public static void display(final XmlElement node) {
final StringBuilder tmpp = new StringBuilder(); final StringBuilder tmpp = new StringBuilder();
//iGenerate(tmpp, 0); Exml.generate(node, tmpp);
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 StringBuilder data) {
// TODO: ... // TODO ...
} }
/** /**
* Generate a string that contain the created XML * Generate a string that contain the created XML
*
* @param data Data where the xml is stored * @param data Data where the xml is stored
*/ */
public static void generate(final XmlNode root, final StringBuilder data) { public static void generate(final XmlNode root, final StringBuilder data) {
if (root.isElement() == false || ((XmlElement) root).getValue().isEmpty() == false) { if (!root.isElement() || !((XmlElement) root).getValue().isEmpty()) {
SerializerXml.serialize(root, data, 0); SerializerXml.serialize(root, data, 0);
} else { } else {
SerializerXml.serializeRoot((XmlElement) root, data); SerializerXml.serializeRoot((XmlElement) root, data);
@ -57,7 +58,7 @@ public class Exml {
return (XmlElement) parser.parse(data, property); return (XmlElement) parser.parse(data, property);
} }
public static <TYPE> TYPE[] parse(final String data, final Class<TYPE> classType, final String rootNodeName) throws ExmlBuilderException, ExmlParserErrorMulti { public static <T> T[] parse(final String data, final Class<T> classType, final String rootNodeName) throws ExmlBuilderException, ExmlParserErrorMulti {
Builder builder; Builder builder;
try { try {
builder = new BuilderIntrospection(classType, rootNodeName); builder = new BuilderIntrospection(classType, rootNodeName);
@ -73,71 +74,46 @@ public class Exml {
final IntrospectionObject introspectionObject = (IntrospectionObject) parser.parse(data, property); final IntrospectionObject introspectionObject = (IntrospectionObject) parser.parse(data, property);
final Object listRet = introspectionObject.getData(); final Object listRet = introspectionObject.getData();
if (listRet != null && listRet instanceof List) { if (listRet != null && listRet instanceof List) {
final List<TYPE> rootList = (List<TYPE>) listRet; final List<T> rootList = (List<T>) listRet;
final TYPE[] strarr = (TYPE[]) Array.newInstance(classType, 0); final T[] strarr = (T[]) Array.newInstance(classType, 0);
return rootList.toArray(strarr); return rootList.toArray(strarr);
} else {
return null;
} }
return null;
} }
/** /**
* Load the file that might contain the xml * Load the file that might contain the xml
* @param[in] _uri URI of the xml *
* @param _uri URI of the xml
* @return false : An error occured * @return false : An error occured
* @return true : Parsing is OK * @return true : Parsing is OK
*/ */
/* /*
public boolean load( Uri _uri){ * public boolean load( Uri _uri){ // Start loading the XML :
// Start loading the XML : * EXML_VERBOSE("open file (xml) " + _uri); clear(); auto fileIo =
EXML_VERBOSE("open file (xml) " + _uri); * uri::get(_uri); if (fileIo == null) { Log.error("File Does not exist : " +
clear(); * _uri); return false; } if (fileIo->open(io::OpenMode::Read) == false) {
auto fileIo = uri::get(_uri); * Log.error("Can not open (r) the file : " + _uri); return false; } // load
if (fileIo == null) { * data from the file: String tmpDataUnicode = fileIo->readAllString(); // close
Log.error("File Does not exist : " + _uri); * the file: fileIo->close(); // parse the data: boolean ret =
return false; * parse(tmpDataUnicode); //Display(); return ret; }
}
if (fileIo->open(io::OpenMode::Read) == false) {
Log.error("Can not open (r) the file : " + _uri);
return false;
}
// load data from the file:
String tmpDataUnicode = fileIo->readAllString();
// close the file:
fileIo->close();
// parse the data:
boolean ret = parse(tmpDataUnicode);
//Display();
return ret;
}
*/ */
/** /**
* Store the Xml in the file * Store the Xml in the file
* @param[in] _uri URI of the xml *
* @param _uri URI of the xml
* @return false : An error occured * @return false : An error occured
* @return true : Parsing is OK * @return true : Parsing is OK
*/ */
/* /*
public boolean store( Uri _uri){ * public boolean store( Uri _uri){ String createData; if (generate(createData)
String createData; * == false) { Log.error("Error while creating the XML: " + _uri); return false;
if (generate(createData) == false) { * } auto fileIo = uri::get(_uri); if (fileIo == null) {
Log.error("Error while creating the XML: " + _uri); * Log.error("Can not create the uri: " + _uri); return false; } if
return false; * (fileIo->open(io::OpenMode::Write) == false) {
} * Log.error("Can not open (r) the file : " + _uri); return false; }
auto fileIo = uri::get(_uri); * fileIo->writeAll(createData); fileIo->close(); return true; }
if (fileIo == null) {
Log.error("Can not create the uri: " + _uri);
return false;
}
if (fileIo->open(io::OpenMode::Write) == false) {
Log.error("Can not open (r) the file : " + _uri);
return false;
}
fileIo->writeAll(createData);
fileIo->close();
return true;
}
*/ */
private Exml() {} private Exml() {}
} }

View File

@ -12,7 +12,7 @@ import java.lang.annotation.Target;
* Exml annotations generically, and in future also for * Exml annotations generically, and in future also for
* passing other generic annotation configuration. * passing other generic annotation configuration.
*/ */
@Target({ ElementType.ANNOTATION_TYPE }) @Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface ExmlAnnotation { public @interface ExmlAnnotation {
// for now, a pure tag annotation, no parameters // for now, a pure tag annotation, no parameters

View File

@ -8,7 +8,7 @@ import java.lang.annotation.Target;
/** /**
* Marker annotation that permit to set the default parsing as attributes. * Marker annotation that permit to set the default parsing as attributes.
*/ */
@Target({ ElementType.TYPE }) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation @ExmlAnnotation
public @interface XmlDefaultAttibute { public @interface XmlDefaultAttibute {

View File

@ -8,7 +8,7 @@ import java.lang.annotation.Target;
/** /**
* Marker annotation that permit to select if the parsing is case sensitive or not. * Marker annotation that permit to select if the parsing is case sensitive or not.
*/ */
@Target({ ElementType.TYPE }) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation @ExmlAnnotation
public @interface XmlDefaultCaseSensitive { public @interface XmlDefaultCaseSensitive {

View File

@ -9,7 +9,7 @@ import java.lang.annotation.Target;
* Marker annotation that set the element are not managed by default. Need to add @XmlManaged to be enable. * Marker annotation that set the element are not managed by default. Need to add @XmlManaged to be enable.
* *
*/ */
@Target({ ElementType.TYPE }) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation @ExmlAnnotation
public @interface XmlDefaultManaged { public @interface XmlDefaultManaged {

View File

@ -9,7 +9,7 @@ import java.lang.annotation.Target;
* Marker annotation that set the element not found are ignored. * Marker annotation that set the element not found are ignored.
* *
*/ */
@Target({ ElementType.TYPE }) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ExmlAnnotation @ExmlAnnotation
public @interface XmlDefaultOptional { public @interface XmlDefaultOptional {

View File

@ -17,8 +17,7 @@ public class BuilderGeneric implements Builder {
@Override @Override
public void newComment(final Object element, final String comment) throws ExmlBuilderException { public void newComment(final Object element, final String comment) throws ExmlBuilderException {
if (element instanceof XmlElement) { if (element instanceof XmlElement elem) {
final XmlElement elem = (XmlElement) element;
elem.append(new XmlComment(comment)); elem.append(new XmlComment(comment));
return; return;
} }
@ -27,8 +26,7 @@ public class BuilderGeneric implements Builder {
@Override @Override
public Object newDeclaration(final Object parent, final String text) throws ExmlBuilderException { public Object newDeclaration(final Object parent, final String text) throws ExmlBuilderException {
if (parent instanceof XmlElement) { if (parent instanceof XmlElement elem) {
final XmlElement elem = (XmlElement) parent;
final XmlDeclaration dec = new XmlDeclaration(text); final XmlDeclaration dec = new XmlDeclaration(text);
elem.append(dec); elem.append(dec);
return dec; return dec;
@ -38,8 +36,7 @@ public class BuilderGeneric implements Builder {
@Override @Override
public Object newElement(final Object parent, final String nodeName) throws ExmlBuilderException { public Object newElement(final Object parent, final String nodeName) throws ExmlBuilderException {
if (parent instanceof XmlElement) { if (parent instanceof XmlElement elem) {
final XmlElement elem = (XmlElement) parent;
final XmlElement eee = new XmlElement(nodeName); final XmlElement eee = new XmlElement(nodeName);
elem.append(eee); elem.append(eee);
return eee; return eee;
@ -49,8 +46,7 @@ public class BuilderGeneric implements Builder {
@Override @Override
public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlBuilderException { public void newProperty(final Object element, final String propertyName, final String propertyValue) throws ExmlBuilderException {
if (element instanceof XmlAttributeList) { if (element instanceof XmlAttributeList attr) {
final XmlAttributeList attr = (XmlAttributeList) element;
attr.appendAttribute(new XmlAttribute(propertyName, propertyValue)); attr.appendAttribute(new XmlAttribute(propertyName, propertyValue));
return; return;
} }
@ -64,8 +60,7 @@ public class BuilderGeneric implements Builder {
@Override @Override
public void newText(final Object parent, final String text) throws ExmlBuilderException { public void newText(final Object parent, final String text) throws ExmlBuilderException {
if (parent instanceof XmlElement) { if (parent instanceof XmlElement attr) {
final XmlElement attr = (XmlElement) parent;
attr.append(new XmlText(text)); attr.append(new XmlText(text));
return; return;
} }

View File

@ -20,20 +20,20 @@ import org.atriasoft.exml.internal.Log;
import org.atriasoft.exml.parser.Tools; import org.atriasoft.exml.parser.Tools;
public class IntrospectionData { public class IntrospectionData {
private static final Boolean DEFAULT_CASE_SENSITIVE = true;
private static final Boolean DEFAULT_MANAGED = true; private static final Boolean DEFAULT_MANAGED = true;
private static final Boolean DEFAULT_OPTIONAL = false; private static final Boolean DEFAULT_OPTIONAL = false;
private static final Boolean DEFAULT_CASE_SENSITIVE = true;
final Class<?> classType; final Class<?> classType;
private final List<IntrospectionProperty> properties = new ArrayList<>();
private final List<IntrospectionProperty> methods = new ArrayList<>(); private final List<IntrospectionProperty> methods = new ArrayList<>();
private final List<IntrospectionProperty> properties = new ArrayList<>();
public IntrospectionData(final Class<?> classType) throws Exception { public IntrospectionData(final Class<?> classType) throws Exception {
this.classType = classType; this.classType = classType;
final Boolean isDefaultManaged = getIsDefaultManaged(classType, DEFAULT_MANAGED); final Boolean isDefaultManaged = getIsDefaultManaged(classType, IntrospectionData.DEFAULT_MANAGED);
final Boolean isDefaultOptional = getIsDefaultOptional(classType, DEFAULT_OPTIONAL); final Boolean isDefaultOptional = getIsDefaultOptional(classType, IntrospectionData.DEFAULT_OPTIONAL);
final Boolean isDefaultCaseSensitive = getIsDefaultCaseSensitive(classType, DEFAULT_CASE_SENSITIVE); final Boolean isDefaultCaseSensitive = getIsDefaultCaseSensitive(classType, IntrospectionData.DEFAULT_CASE_SENSITIVE);
Log.verbose("Introspect class: '" + classType.getCanonicalName() + "'"); Log.verbose("Introspect class: '" + classType.getCanonicalName() + "'");
final Constructor<?>[] constructors = this.classType.getConstructors(); final Constructor<?>[] constructors = this.classType.getConstructors();
Log.verbose(" Constructors: (" + constructors.length + ")"); Log.verbose(" Constructors: (" + constructors.length + ")");
@ -47,8 +47,8 @@ public class IntrospectionData {
final Boolean isOptionnal = getIsOptional(elem, isDefaultOptional); final Boolean isOptionnal = getIsOptional(elem, isDefaultOptional);
final String[] names = getNames(elem, Tools.decapitalizeFirst(elem.getName())); final String[] names = getNames(elem, Tools.decapitalizeFirst(elem.getName()));
final Boolean caseSensitive = getIsCaseSensitive(elem, isDefaultCaseSensitive); final Boolean caseSensitive = getIsCaseSensitive(elem, isDefaultCaseSensitive);
// TODO: check if property does not already exist ... // TODO check if property does not already exist ...
if (isManaged == true) { if (isManaged) {
this.properties.add(new IntrospectionPropertyField(elem, names, caseSensitive, isOptionnal)); this.properties.add(new IntrospectionPropertyField(elem, names, caseSensitive, isOptionnal));
} }
Log.verbose(" - " + elem.toGenericString()); Log.verbose(" - " + elem.toGenericString());
@ -56,7 +56,7 @@ public class IntrospectionData {
final Method[] methodsTmp = this.classType.getMethods(); final Method[] methodsTmp = this.classType.getMethods();
// filter getX setX isX // filter getX setX isX
final List<Method> methods = List.of(methodsTmp).stream().filter(o -> { final List<Method> methods = List.of(methodsTmp).stream().filter(o -> {
if (o.getName().contentEquals("getClass") == true) { if (o.getName().contentEquals("getClass")) {
return false; return false;
} }
if (o.getName().startsWith("get")) { if (o.getName().startsWith("get")) {
@ -113,15 +113,9 @@ public class IntrospectionData {
// void setXxx(XXX elem); // void setXxx(XXX elem);
// [bB]oolean isXxx(); // [bB]oolean isXxx();
final List<Method> methodsGet = methods.stream().filter(o -> { final List<Method> methodsGet = methods.stream().filter(o -> o.getName().startsWith("get")).collect(Collectors.toList());
return o.getName().startsWith("get"); final List<Method> methodsSet = methods.stream().filter(o -> o.getName().startsWith("set")).collect(Collectors.toList());
}).collect(Collectors.toList()); final List<Method> methodsIs = methods.stream().filter(o -> o.getName().startsWith("is")).collect(Collectors.toList());
final List<Method> methodsSet = methods.stream().filter(o -> {
return o.getName().startsWith("set");
}).collect(Collectors.toList());
final List<Method> methodsIs = methods.stream().filter(o -> {
return o.getName().startsWith("is");
}).collect(Collectors.toList());
// associate methods by pair. // associate methods by pair.
final List<OrderData> elements = new ArrayList<>(); final List<OrderData> elements = new ArrayList<>();
@ -218,7 +212,7 @@ public class IntrospectionData {
} else { } else {
Log.info(" getter: null"); Log.info(" getter: null");
} }
if (isManaged == true) { if (isManaged) {
this.methods.add(new IntrospectionPropertyMethod(elem.setter, elem.getter, names, isCaseSensitive, isOptionnal)); this.methods.add(new IntrospectionPropertyMethod(elem.setter, elem.getter, names, isCaseSensitive, isOptionnal));
} }
} }
@ -238,7 +232,7 @@ public class IntrospectionData {
protected IntrospectionProperty findMethodDescription(final String propertyName) throws Exception { protected IntrospectionProperty findMethodDescription(final String propertyName) throws Exception {
for (final IntrospectionProperty prop : this.methods) { for (final IntrospectionProperty prop : this.methods) {
if (prop.isCompatible(propertyName) == true) { if (prop.isCompatible(propertyName)) {
return prop; return prop;
} }
} }
@ -247,7 +241,7 @@ public class IntrospectionData {
protected IntrospectionProperty findPropertyDescription(final String propertyName) throws Exception { protected IntrospectionProperty findPropertyDescription(final String propertyName) throws Exception {
for (final IntrospectionProperty prop : this.properties) { for (final IntrospectionProperty prop : this.properties) {
if (prop.isCompatible(propertyName) == true) { if (prop.isCompatible(propertyName)) {
return prop; return prop;
} }
} }
@ -358,9 +352,8 @@ public class IntrospectionData {
if (annotation.length == 0) { if (annotation.length == 0) {
if (defaultValue == null) { if (defaultValue == null) {
return null; return null;
} else {
return new String[] { defaultValue };
} }
return new String[] { defaultValue };
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new Exception("Must not hame more that ");
@ -376,7 +369,7 @@ public class IntrospectionData {
if (elem == null) { if (elem == null) {
throw new Exception("Set null String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString()); throw new Exception("Set null String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString());
} }
if (elem.isEmpty() == true) { if (elem.isEmpty()) {
throw new Exception("Set empty String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString()); throw new Exception("Set empty String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString());
} }
} }
@ -388,9 +381,8 @@ public class IntrospectionData {
if (annotation.length == 0) { if (annotation.length == 0) {
if (defaultValue == null) { if (defaultValue == null) {
return null; return null;
} else {
return new String[] { defaultValue };
} }
return new String[] { defaultValue };
} }
if (annotation.length > 1) { if (annotation.length > 1) {
throw new Exception("Must not hame more that "); throw new Exception("Must not hame more that ");
@ -406,7 +398,7 @@ public class IntrospectionData {
if (elem == null) { if (elem == null) {
throw new Exception("Set null String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString()); throw new Exception("Set null String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString());
} }
if (elem.isEmpty() == true) { if (elem.isEmpty()) {
throw new Exception("Set empty String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString()); throw new Exception("Set empty String in list of value in decorator @XmlName is not availlable on: " + element.toGenericString());
} }
} }
@ -417,14 +409,14 @@ public class IntrospectionData {
//Log.error(" propertyName='" + propertyName + "' propertyValue='" + propertyValue + "' "); //Log.error(" propertyName='" + propertyName + "' propertyValue='" + propertyValue + "' ");
// by default use setter to set the property // by default use setter to set the property
final IntrospectionProperty propMethode = findMethodDescription(propertyName); final IntrospectionProperty propMethode = findMethodDescription(propertyName);
if (propMethode != null && propMethode.cansetValue() == true) { if (propMethode != null && propMethode.cansetValue()) {
//Log.error(" ==> find '" + propMethode.getNames()); //Log.error(" ==> find '" + propMethode.getNames());
propMethode.setValue(data, propertyValue); propMethode.setValue(data, propertyValue);
return; return;
} }
// try with direct field // try with direct field
final IntrospectionProperty propField = findPropertyDescription(propertyName); final IntrospectionProperty propField = findPropertyDescription(propertyName);
if (propField != null && propField.cansetValue() == true) { if (propField != null && propField.cansetValue()) {
//Log.error(" ==> find '" + propField.getNames()); //Log.error(" ==> find '" + propField.getNames());
propField.setValue(data, propertyValue); propField.setValue(data, propertyValue);
return; return;
@ -435,9 +427,9 @@ public class IntrospectionData {
} }
class OrderData { class OrderData {
public Method getter = null;
public final String name; public final String name;
public Method setter = null; public Method setter = null;
public Method getter = null;
public OrderData(final String name) { public OrderData(final String name) {
this.name = name; this.name = name;

View File

@ -1,10 +1,10 @@
package org.atriasoft.exml.builder; package org.atriasoft.exml.builder;
public abstract class IntrospectionProperty { public abstract class IntrospectionProperty {
protected final Class<?> type;
protected final String[] names;
protected final Boolean caseSensitive; protected final Boolean caseSensitive;
protected final Boolean isOptionnal; protected final Boolean isOptionnal;
protected final String[] names;
protected final Class<?> type;
public IntrospectionProperty(final Class<?> type, final String[] names, final Boolean caseSensitive, final Boolean isOptionnal) { public IntrospectionProperty(final Class<?> type, final String[] names, final Boolean caseSensitive, final Boolean isOptionnal) {
this.type = type; this.type = type;
@ -32,16 +32,16 @@ public abstract class IntrospectionProperty {
} }
public boolean isCompatible(String name) { public boolean isCompatible(String name) {
if (this.caseSensitive == true) { if (this.caseSensitive) {
for (final String elem : this.names) { for (final String elem : this.names) {
if (elem.contentEquals(name) == true) { if (elem.contentEquals(name)) {
return true; return true;
} }
} }
} else { } else {
name = name.toLowerCase(); name = name.toLowerCase();
for (final String elem : this.names) { for (final String elem : this.names) {
if (elem.toLowerCase().contentEquals(name) == true) { if (elem.toLowerCase().contentEquals(name)) {
return true; return true;
} }
} }

View File

@ -12,9 +12,9 @@ import org.atriasoft.exml.parser.FilePos;
*/ */
public class XmlAttribute { public class XmlAttribute {
protected String name; //!< Name of the attribute
protected FilePos pos; //!< position in the read file (null if the file is not parsed); protected FilePos pos; //!< position in the read file (null if the file is not parsed);
protected String value; //!< value of the node (for element this is the name, for text it is the inside text ...); protected String value; //!< value of the node (for element this is the name, for text it is the inside text ...);
protected String name; //!< Name of the attribute
public XmlAttribute() { public XmlAttribute() {
this.pos = null; this.pos = null;
@ -22,25 +22,25 @@ public class XmlAttribute {
this.name = ""; this.name = "";
} }
public XmlAttribute(final String _name) { public XmlAttribute(final String name) {
this.name = _name; this.name = name;
this.value = ""; this.value = "";
} }
/** /**
* Constructor * Constructor
* @param[in] _name Name of the attribute. * @param _name Name of the attribute.
* @param[in] _value Value of the attribute. * @param _value Value of the attribute.
*/ */
public XmlAttribute(final String _name, final String _value) { public XmlAttribute(final String name, final String value) {
this.name = _name; this.name = name;
this.value = _value; this.value = value;
} }
public XmlAttribute(final XmlAttribute _obj) { public XmlAttribute(final XmlAttribute obj) {
this.pos = null; this.pos = null;
this.value = _obj.value; this.value = obj.value;
this.name = _obj.name; this.name = obj.name;
} }
public void clear() { public void clear() {
@ -58,7 +58,7 @@ public class XmlAttribute {
*/ */
public String getName() { public String getName() {
return this.name; return this.name;
}; }
/** /**
* get the current element Value. * get the current element Value.
@ -66,21 +66,21 @@ public class XmlAttribute {
*/ */
public String getValue() { public String getValue() {
return this.value; return this.value;
}; }
/** /**
* set the name of the attribute * set the name of the attribute
* @param[in] _name New name of the attribute * @param _name New name of the attribute
*/ */
public void setName(final String _name) { public void setName(final String name) {
this.name = _name; this.name = name;
} }
/** /**
* set the value of the node. * set the value of the node.
* @param[in] _value New value of the node. * @param _value New value of the node.
*/ */
public final void setValue(final String _value) { public final void setValue(final String value) {
this.value = _value; this.value = value;
}
} }
};

View File

@ -20,57 +20,55 @@ import org.atriasoft.exml.internal.Log;
public abstract class XmlAttributeList extends XmlNode { public abstract class XmlAttributeList extends XmlNode {
protected List<XmlAttribute> listAttribute = new ArrayList<>(); //!< list of all attribute; protected List<XmlAttribute> listAttribute = new ArrayList<>(); //!< list of all attribute;
public XmlAttributeList() { public XmlAttributeList() {}
super();
};
/** /**
* Constructor * Constructor
* @param[in] _value Node value; * @param value Node value;
*/ */
public XmlAttributeList(final String _value) { public XmlAttributeList(final String value) {
super(_value); super(value);
} }
/** /**
* Add attribute on the List * Add attribute on the List
* @param[in] _attr Pointer on the attribute * @param attr Pointer on the attribute
*/ */
public void appendAttribute(final XmlAttribute _attr) { public void appendAttribute(final XmlAttribute attr) {
if (_attr == null) { if (attr == null) {
Log.error("Try to set an empty node"); Log.error("Try to set an empty node");
return; return;
} }
for (int iii = 0; iii < this.listAttribute.size(); iii++) { for (int iii = 0; iii < this.listAttribute.size(); iii++) {
if (this.listAttribute.get(iii) == _attr) { if (this.listAttribute.get(iii) == attr) {
Log.error("Try to add a node that is already added before !!!"); Log.error("Try to add a node that is already added before !!!");
return; return;
} }
if (this.listAttribute.get(iii).getName().contentEquals(_attr.getName()) == true) { if (this.listAttribute.get(iii).getName().contentEquals(attr.getName())) {
Log.error("Try to add a node that is already added before (same name)"); Log.error("Try to add a node that is already added before (same name)");
return; return;
} }
} }
this.listAttribute.add(_attr); this.listAttribute.add(attr);
} }
@Override @Override
public void clear() { public void clear() {
super.clear(); super.clear();
this.listAttribute.clear(); this.listAttribute.clear();
}; }
/** /**
* Check if an attribute exist or not with his name. * Check if an attribute exist or not with his name.
* @param[in] _name Attribute Name. * @param name Attribute Name.
* @return true if the attribute exist or False * @return true if the attribute exist or False
*/ */
public boolean existAttribute(final String _name) { public boolean existAttribute(final String name) {
if (_name.length() == 0) { if (name.length() == 0) {
return false; return false;
} }
for (int iii = 0; iii < this.listAttribute.size(); ++iii) { for (int iii = 0; iii < this.listAttribute.size(); ++iii) {
if (this.listAttribute.get(iii) != null && this.listAttribute.get(iii).getName().contentEquals(_name) == true) { if (this.listAttribute.get(iii) != null && this.listAttribute.get(iii).getName().contentEquals(name)) {
return true; return true;
} }
} }
@ -79,33 +77,45 @@ public abstract class XmlAttributeList extends XmlNode {
/** /**
* Get attribute whith his ID * Get attribute whith his ID
* @param[in] _id Identifier of the attribute 0<= _id < sizeAttribute() * @param id Identifier of the attribute 0<= id < sizeAttribute()
* @return Pointer on the attribute or NULL * @return Pointer on the attribute or NULL
* @throws ExmlAttributeDoesNotExist The attribute does not exist. * @throws ExmlAttributeDoesNotExist The attribute does not exist.
*/ */
public XmlAttribute getAttr(final int _id) throws ExmlAttributeDoesNotExist { public XmlAttribute getAttr(final int id) throws ExmlAttributeDoesNotExist {
if (_id < 0 || _id >= this.listAttribute.size()) { if (id < 0 || id >= this.listAttribute.size()) {
throw new ExmlAttributeDoesNotExist("Attribute does not exist: " + _id + "/" + this.listAttribute.size()); throw new ExmlAttributeDoesNotExist("Attribute does not exist: " + id + "/" + this.listAttribute.size());
} }
return this.listAttribute.get(_id); return this.listAttribute.get(id);
} }
/** /**
* get the attribute value with searching in the List with his name * get the attribute value with searching in the List with his name
* @param[in] _name Attribute Name. * @param name Attribute Name.
* @return Value of the attribute or no data in the string * @return Value of the attribute or no data in the string
* @throws ExmlAttributeDoesNotExist The attribute does not exist. * @throws ExmlAttributeDoesNotExist The attribute does not exist.
*/ */
public String getAttribute(final String _name) throws ExmlAttributeDoesNotExist { public String getAttribute(final String name) throws ExmlAttributeDoesNotExist {
if (_name.length() == 0) { if (name.length() == 0) {
throw new ExmlAttributeDoesNotExist("Attribute can not have empty name"); throw new ExmlAttributeDoesNotExist("Attribute can not have empty name");
} }
for (int iii = 0; iii < this.listAttribute.size(); iii++) { for (final XmlAttribute xmlAttribute : this.listAttribute) {
if (this.listAttribute.get(iii) != null && this.listAttribute.get(iii).getName().contentEquals(_name) == true) { if (xmlAttribute != null && xmlAttribute.getName().contentEquals(name)) {
return this.listAttribute.get(iii).getValue(); return xmlAttribute.getValue();
} }
} }
throw new ExmlAttributeDoesNotExist("Attribute does not exist: " + _name + " in " + this.listAttribute.size() + " attributes"); throw new ExmlAttributeDoesNotExist("Attribute does not exist: " + name + " in " + this.listAttribute.size() + " attributes");
}
public String getAttribute(final String name, final String defaultValue) {
if (name.length() == 0) {
return defaultValue;
}
for (final XmlAttribute xmlAttribute : this.listAttribute) {
if (xmlAttribute != null && xmlAttribute.getName().contentEquals(name)) {
return xmlAttribute.getValue();
}
}
return defaultValue;
} }
public List<XmlAttribute> getAttributes() { public List<XmlAttribute> getAttributes() {
@ -114,23 +124,23 @@ public abstract class XmlAttributeList extends XmlNode {
/** /**
* get attribute whith his ID * get attribute whith his ID
* @param[in] _id Identifier of the attribute 0<= _id < sizeAttribute() * @param id Identifier of the attribute 0<= id < sizeAttribute()
* @return Name and value of the attribute * @return Name and value of the attribute
* @throws ExmlAttributeDoesNotExist The attribute does not exist. * @throws ExmlAttributeDoesNotExist The attribute does not exist.
*/ */
public Pair<String, String> getAttrPair(final int _id) throws ExmlAttributeDoesNotExist { public Pair<String, String> getAttrPair(final int id) throws ExmlAttributeDoesNotExist {
final XmlAttribute att = getAttr(_id); final XmlAttribute att = getAttr(id);
return new Pair<String, String>(att.getName(), att.getValue()); return new Pair<String, String>(att.getName(), att.getValue());
} }
/** /**
* Remove an attribute form the list * Remove an attribute form the list
* @param[in] _name Name of the attribute * @param name Name of the attribute
* @return true The attribute has been removed * @return true The attribute has been removed
* @return false An error occured. * @return false An error occured.
*/ */
public boolean removeAttribute(final String _name) { public boolean removeAttribute(final String name) {
if (_name.length() == 0) { if (name.length() == 0) {
return false; return false;
} }
for (final ListIterator<XmlAttribute> iter = this.listAttribute.listIterator(); iter.hasNext();) { for (final ListIterator<XmlAttribute> iter = this.listAttribute.listIterator(); iter.hasNext();) {
@ -139,7 +149,7 @@ public abstract class XmlAttributeList extends XmlNode {
iter.remove(); iter.remove();
continue; continue;
} }
if (element.getName().contentEquals(_name) == true) { if (element.getName().contentEquals(name)) {
iter.remove(); iter.remove();
return true; return true;
} }
@ -149,19 +159,19 @@ public abstract class XmlAttributeList extends XmlNode {
/** /**
* Set A new attribute or replace data of the previous one * Set A new attribute or replace data of the previous one
* @param[in] _name Name of the attribute * @param name Name of the attribute
* @param[in] _value Value of the attribute * @param value Value of the attribute
*/ */
public void setAttribute(final String _name, final String _value) { public void setAttribute(final String name, final String value) {
// check if attribute already det : // check if attribute already det :
for (int iii = 0; iii < this.listAttribute.size(); ++iii) { for (int iii = 0; iii < this.listAttribute.size(); ++iii) {
if (this.listAttribute.get(iii) != null && this.listAttribute.get(iii).getName().contentEquals(_name) == true) { if (this.listAttribute.get(iii) != null && this.listAttribute.get(iii).getName().contentEquals(name)) {
// update the value : // update the value :
this.listAttribute.get(iii).setValue(_value); this.listAttribute.get(iii).setValue(value);
return; return;
} }
} }
final XmlAttribute attr = new XmlAttribute(_name, _value); final XmlAttribute attr = new XmlAttribute(name, value);
this.listAttribute.add(attr); this.listAttribute.add(attr);
} }

View File

@ -11,15 +11,14 @@ package org.atriasoft.exml.model;
public class XmlComment extends XmlNode { public class XmlComment extends XmlNode {
public XmlComment() { public XmlComment() {
super();
} }
/** /**
* Constructor * Constructor
* @param[in] _value comment value * @param _value comment value
*/ */
public XmlComment(final String _value) { public XmlComment(final String value) {
super(_value); super(value);
} }
public XmlComment(final XmlComment obj) { public XmlComment(final XmlComment obj) {
@ -36,4 +35,4 @@ public class XmlComment extends XmlNode {
return XmlNodeType.COMMENT; return XmlNodeType.COMMENT;
} }
}; }

View File

@ -13,33 +13,33 @@ import org.atriasoft.exml.internal.Log;
public class XmlDeclaration extends XmlAttributeList { public class XmlDeclaration extends XmlAttributeList {
public XmlDeclaration() { public XmlDeclaration() {
super(""); super("");
}; }
/** /**
* Constructor * Constructor
* @param[in] _name name of the declaration (xml, xml:xxxx ...) * @param name name of the declaration (xml, xml:xxxx ...)
*/ */
public XmlDeclaration(final String _name) { public XmlDeclaration(final String name) {
super(_name); super(name);
} }
public XmlDeclaration(final String _version, final String _format, final boolean _standalone) { public XmlDeclaration(final String version, final String format, final boolean standalone) {
super("xml"); super("xml");
if (_version.isEmpty() != true) { if (!version.isEmpty()) {
setAttribute("version", _version); setAttribute("version", version);
} }
if (_format.contentEquals("UTF-8")) { if (format.contentEquals("UTF-8")) {
setAttribute("encoding", "UTF-8"); setAttribute("encoding", "UTF-8");
} else { } else {
Log.error("Actually does not supported other charset than UTF8"); Log.error("Actually does not supported other charset than UTF8");
setAttribute("encoding", "UTF-8"); setAttribute("encoding", "UTF-8");
} }
if (_standalone == true) { if (standalone) {
setAttribute("standalone", "true"); setAttribute("standalone", "true");
} else { } else {
setAttribute("standalone", "true"); setAttribute("standalone", "true");
} }
}; }
public XmlDeclaration(final XmlDeclaration obj) { public XmlDeclaration(final XmlDeclaration obj) {
super(obj.value); super(obj.value);

View File

@ -29,15 +29,14 @@ public class XmlElement extends XmlAttributeList {
* Constructor * Constructor
*/ */
public XmlElement() { public XmlElement() {
super(); }
};
/** /**
* Constructor * Constructor
* @param[in] _value Element name; * @param value Element name;
*/ */
public XmlElement(final String _value) { public XmlElement(final String value) {
super(_value); super(value);
} }
@ -49,31 +48,31 @@ public class XmlElement extends XmlAttributeList {
for (final XmlNode elem : obj.listSub) { for (final XmlNode elem : obj.listSub) {
this.listSub.add(elem.clone()); this.listSub.add(elem.clone());
} }
}; }
/** /**
* add a node at the element (not Attribute (move in the attribute automaticly). * add a node at the element (not Attribute (move in the attribute automaticly).
* @param[in] _node Pointer of the node to add. * @param node Pointer of the node to add.
*/ */
public void append(final XmlNode _node) { public void append(final XmlNode node) {
if (_node == null) { if (node == null) {
Log.error("Try to set an empty node"); Log.error("Try to set an empty node");
return; return;
} }
for (int iii = 0; iii < this.listSub.size(); iii++) { for (int iii = 0; iii < this.listSub.size(); iii++) {
if (this.listSub.get(iii) == _node) { if (this.listSub.get(iii) == node) {
Log.error("Try to add a node that is already added before !!!"); Log.error("Try to add a node that is already added before !!!");
return; return;
} }
} }
this.listSub.add(_node); this.listSub.add(node);
} }
@Override @Override
public void clear() { public void clear() {
super.clear(); super.clear();
this.listSub.clear(); this.listSub.clear();
}; }
@Override @Override
public XmlElement clone() throws CloneNotSupportedException { public XmlElement clone() throws CloneNotSupportedException {
@ -82,11 +81,11 @@ public class XmlElement extends XmlAttributeList {
/** /**
* get the Node pointer of the element id. * get the Node pointer of the element id.
* @param[in] _id Id of the element. * @param id Id of the element.
* @return true if the Node exist. * @return true if the Node exist.
*/ */
public boolean existNode(final int _id) { public boolean existNode(final int id) {
if (_id < 0 || _id >= this.listSub.size()) { if (id < 0 || id >= this.listSub.size()) {
return false; return false;
} }
return true; return true;
@ -94,15 +93,15 @@ public class XmlElement extends XmlAttributeList {
/** /**
* get an element with his name (work only with Element) * get an element with his name (work only with Element)
* @param[in] _name Name of the element that is requested * @param name Name of the element that is requested
* @return true if the Node exist. * @return true if the Node exist.
*/ */
public boolean existNode(final String _name) { public boolean existNode(final String name) {
if (_name.isEmpty() == true) { if (name.isEmpty()) {
return false; return false;
} }
for (int iii = 0; iii < this.listSub.size(); iii++) { for (int iii = 0; iii < this.listSub.size(); iii++) {
if (this.listSub.get(iii) != null && this.listSub.get(iii).getValue().contentEquals(_name) == true) { if (this.listSub.get(iii) != null && this.listSub.get(iii).getValue().contentEquals(name)) {
if (this.listSub.get(iii) == null) { if (this.listSub.get(iii) == null) {
return false; return false;
} }
@ -114,33 +113,33 @@ public class XmlElement extends XmlAttributeList {
/** /**
* get the Node pointer of the element id. * get the Node pointer of the element id.
* @param[in] _id Id of the element. * @param id Id of the element.
* @return Pointer on node. * @return Pointer on node.
* @throws ExmlNodeDoesNotExist The Node does not exist * @throws ExmlNodeDoesNotExist The Node does not exist
*/ */
public XmlNode getNode(final int _id) throws ExmlNodeDoesNotExist { public XmlNode getNode(final int id) throws ExmlNodeDoesNotExist {
if (_id < 0 || _id >= this.listSub.size()) { if (id < 0 || id >= this.listSub.size()) {
throw new ExmlNodeDoesNotExist("Node does not exist: " + _id + "/" + this.listSub.size()); throw new ExmlNodeDoesNotExist("Node does not exist: " + id + "/" + this.listSub.size());
} }
return this.listSub.get(_id); return this.listSub.get(id);
} }
/** /**
* get an element with his name (work only with Element) * get an element with his name (work only with Element)
* @param[in] _name Name of the element that is requested * @param name Name of the element that is requested
* @return Pointer on the node. * @return Pointer on the node.
* @throws ExmlNodeDoesNotExist The Node does not exist * @throws ExmlNodeDoesNotExist The Node does not exist
*/ */
public XmlNode getNode(final String _name) throws ExmlNodeDoesNotExist { public XmlNode getNode(final String name) throws ExmlNodeDoesNotExist {
if (_name.isEmpty() == true) { if (name.isEmpty()) {
throw new ExmlNodeDoesNotExist("Node can not have empty name in " + this.listAttribute.size() + " nodes"); throw new ExmlNodeDoesNotExist("Node can not have empty name in " + this.listAttribute.size() + " nodes");
} }
for (int iii = 0; iii < this.listSub.size(); iii++) { for (int iii = 0; iii < this.listSub.size(); iii++) {
if (this.listSub.get(iii) != null && this.listSub.get(iii).getValue().contentEquals(_name) == true) { if (this.listSub.get(iii) != null && this.listSub.get(iii).getValue().contentEquals(name)) {
return this.listSub.get(iii); return this.listSub.get(iii);
} }
} }
throw new ExmlNodeDoesNotExist("Node does not exist: '" + _name + "' in " + this.listAttribute.size()); throw new ExmlNodeDoesNotExist("Node does not exist: '" + name + "' in " + this.listAttribute.size());
} }
/** /**
@ -180,23 +179,23 @@ public class XmlElement extends XmlAttributeList {
/** /**
* get the type of the element id. * get the type of the element id.
* @param[in] _id Id of the element. * @param id Id of the element.
* @return the Current type of the element or typeUnknow. * @return the Current type of the element or typeUnknow.
* @throws ExmlNodeDoesNotExist The Node does not exist * @throws ExmlNodeDoesNotExist The Node does not exist
*/ */
public XmlNodeType getType(final int _id) throws ExmlNodeDoesNotExist { public XmlNodeType getType(final int id) throws ExmlNodeDoesNotExist {
if (_id < 0 || _id >= this.listSub.size()) { if (id < 0 || id >= this.listSub.size()) {
throw new ExmlNodeDoesNotExist("Node does not exist: " + _id + "/" + this.listSub.size()); throw new ExmlNodeDoesNotExist("Node does not exist: " + id + "/" + this.listSub.size());
} }
return this.listSub.get(_id).getType(); return this.listSub.get(id).getType();
} }
/** /**
* Remove all element with this name * Remove all element with this name
* @param[in] _nodeName Name of nodes to remove. * @param nodeName Name of nodes to remove.
*/ */
public void remove(final String _nodeName) { public void remove(final String nodeName) {
if (_nodeName == "") { if (nodeName.isEmpty()) {
return; return;
} }
for (final ListIterator<XmlNode> iter = this.listSub.listIterator(); iter.hasNext();) { for (final ListIterator<XmlNode> iter = this.listSub.listIterator(); iter.hasNext();) {
@ -205,7 +204,7 @@ public class XmlElement extends XmlAttributeList {
iter.remove(); iter.remove();
continue; continue;
} }
if (element.getValue().contentEquals(_nodeName) == true) { if (element.getValue().contentEquals(nodeName)) {
iter.remove(); iter.remove();
} }
} }
@ -219,4 +218,4 @@ public class XmlElement extends XmlAttributeList {
return this.listSub.size(); return this.listSub.size();
} }
}; }

View File

@ -19,10 +19,10 @@ public abstract class XmlNode {
/** /**
* Basic element of a xml structure * Basic element of a xml structure
* @param[in] _value value of the node * @param value value of the node
*/ */
public XmlNode(final String _value) { public XmlNode(final String value) {
setValue(_value); setValue(value);
} }
/** /**
@ -85,13 +85,13 @@ public abstract class XmlNode {
/** /**
* set the value of the node. * set the value of the node.
* @param[in] _value New value of the node. * @param value New value of the node.
*/ */
public final void setValue(final String _value) { public final void setValue(final String value) {
if (_value.isEmpty() == true || _value.isBlank() == true) { if (value.isEmpty() || value.isBlank()) {
this.value = null; this.value = null;
} else { } else {
this.value = _value; this.value = value;
} }
} }

View File

@ -13,14 +13,14 @@ public class XmlText extends XmlNode {
/** /**
* Constructor * Constructor
*/ */
public XmlText() {}; public XmlText() {}
/** /**
* Constructor * Constructor
* @param[in] _data String data of the current Text * @param data String data of the current Text
*/ */
public XmlText(final String _data) { public XmlText(final String data) {
super(_data); super(data);
} }
/** /**
@ -42,4 +42,4 @@ public class XmlText extends XmlNode {
return XmlNodeType.TEXT; return XmlNodeType.TEXT;
} }
}; }

View File

@ -28,48 +28,48 @@ public class FilePos {
/** /**
* initialize constructor * initialize constructor
* @param[in] _line Line in the file * @param line Line in the file
* @param[in] _col Colomn in the file * @param col Colomn in the file
*/ */
public FilePos(final int _line, final int _col) { public FilePos(final int line, final int col) {
this.col = _col; this.col = col;
this.line = _line; this.line = line;
} }
/** /**
* Addition operator * Addition operator
* @param[in] _obj Addition object.. * @param obj Addition object..
* @return Reference on this * @return Reference on this
*/ */
public FilePos add(final FilePos _obj) { public FilePos add(final FilePos obj) {
if (_obj.line == 0) { if (obj.line == 0) {
this.col += _obj.col; this.col += obj.col;
} else { } else {
this.col = _obj.col; this.col = obj.col;
this.line += _obj.line; this.line += obj.line;
} }
return this; return this;
} }
/** /**
* Colomn addition operator * Colomn addition operator
* @param[in] _col Number of colomn to add * @param col Number of colomn to add
* @return Reference on this * @return Reference on this
*/ */
public FilePos add(final int _col) { public FilePos add(final int col) {
this.col += _col; this.col += col;
return this; return this;
} }
/** /**
* Check if the value is a new line and update internal property * Check if the value is a new line and update internal property
* @param[in] _val Char value to check * @param val Char value to check
* @return true We find a new line * @return true We find a new line
* @return false We NOT find a new line * @return false We NOT find a new line
*/ */
public boolean check(final Character _val) { public boolean check(final Character val) {
this.col++; this.col++;
if (_val == '\n') { if (val == '\n') {
newLine(); newLine();
return true; return true;
} }
@ -153,23 +153,23 @@ public class FilePos {
/** /**
* Asignment operator * Asignment operator
* @param[in] _obj Object to copy * @param obj Object to copy
* @return Reference on this * @return Reference on this
*/ */
public FilePos set(final FilePos _obj) { public FilePos set(final FilePos obj) {
this.col = _obj.col; this.col = obj.col;
this.line = _obj.line; this.line = obj.line;
return this; return this;
} }
/** /**
* Setter of specific data * Setter of specific data
* @param[in] _line Line in the file * @param line Line in the file
* @param[in] _col Colomn in the file * @param col Colomn in the file
*/ */
public void set(final int _line, final int _col) { public void set(final int line, final int col) {
this.col = _col; this.col = col;
this.line = _line; this.line = line;
} }
@Override @Override
@ -182,4 +182,4 @@ public class FilePos {
return out; return out;
} }
}; }

View File

@ -14,21 +14,19 @@ public class ParseXml {
this.builder = builder; this.builder = builder;
} }
protected boolean iParseAttribute(final Object parent, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException { protected boolean iParseAttribute(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException {
Log.verbose("start parse : 'attribute'"); Log.verbose("start parse : 'attribute'");
final FilePos pos = _filePos.clone();
// search end of the comment : // search end of the comment :
int lastElementName = _pos.value; int lastElementName = pos.value;
for (int iii = _pos.value; iii < _data.length(); iii++) { for (int iii = pos.value; iii < data.length(); iii++) {
_filePos.check(_data.charAt(iii)); filePos.check(data.charAt(iii));
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (Tools.checkAvaillable(_data.charAt(iii), false) == true) { if (!Tools.checkAvaillable(data.charAt(iii), false)) {
lastElementName = iii;
} else {
break; break;
} }
lastElementName = iii;
} }
String name = _data.substring(_pos.value, lastElementName + 1); String name = data.substring(pos.value, lastElementName + 1);
if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) { if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) {
name = name.toLowerCase(); name = name.toLowerCase();
} else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) { } else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) {
@ -40,48 +38,47 @@ public class ParseXml {
String value = ""; String value = "";
// count white space : // count white space :
final FilePos tmpPos = new FilePos(); final FilePos tmpPos = new FilePos();
int white = Tools.countWhiteChar(_data, lastElementName + 1, tmpPos); int white = Tools.countWhiteChar(data, lastElementName + 1, tmpPos);
_filePos.add(tmpPos); filePos.add(tmpPos);
if (lastElementName + white + 1 >= _data.length()) { if (lastElementName + white + 1 >= data.length()) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, lastElementName + white + 1), _filePos, " parse an xml end with an attribute parsing...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, lastElementName + white + 1), filePos, " parse an xml end with an attribute parsing..."));
return false; return false;
} }
if (_data.charAt(lastElementName + white + 1) != '=') { if (data.charAt(lastElementName + white + 1) != '=') {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, lastElementName + white + 1), _filePos, " error attribute parsing == > missing '=' ...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, lastElementName + white + 1), filePos, " error attribute parsing == > missing '=' ..."));
return false; return false;
} }
white += Tools.countWhiteChar(_data, lastElementName + white + 2, tmpPos); white += Tools.countWhiteChar(data, lastElementName + white + 2, tmpPos);
_filePos.add(tmpPos); filePos.add(tmpPos);
if (lastElementName + white + 2 >= _data.length()) { if (lastElementName + white + 2 >= data.length()) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, lastElementName + white + 2), _filePos, " parse an xml end with an attribute parsing...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, lastElementName + white + 2), filePos, " parse an xml end with an attribute parsing..."));
return false; return false;
} }
boolean simpleQuoteCase = false; boolean simpleQuoteCase = false;
if (_data.charAt(lastElementName + white + 2) == '\'') { // ' if (data.charAt(lastElementName + white + 2) == '\'') { // '
simpleQuoteCase = true; simpleQuoteCase = true;
} }
if (_data.charAt(lastElementName + white + 2) != '"' && _data.charAt(lastElementName + white + 2) != '\'') { // ' if (data.charAt(lastElementName + white + 2) != '"' && data.charAt(lastElementName + white + 2) != '\'') { // '
// parse with no element " == > direct value separate with space ... // parse with no element " == > direct value separate with space ...
_filePos.increment(); filePos.increment();
int lastAttributePos = lastElementName + white + 2; int lastAttributePos = lastElementName + white + 2;
for (int iii = lastElementName + white + 2; iii < _data.length(); iii++) { for (int iii = lastElementName + white + 2; iii < data.length(); iii++) {
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (_filePos.check(_data.charAt(iii)) == true) { if (filePos.check(data.charAt(iii))) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, iii), _filePos, "unexpected '\\n' in an attribute parsing")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, iii), filePos, "unexpected '\\n' in an attribute parsing"));
return false; return false;
} }
if (_data.charAt(iii) != ' ' && _data.charAt(iii) != '/' && _data.charAt(iii) != '?' && _data.charAt(iii) != '>') { if ((data.charAt(iii) == ' ') || (data.charAt(iii) == '/') || (data.charAt(iii) == '?') || (data.charAt(iii) == '>')) {
lastAttributePos = iii + 1;
} else {
break; break;
} }
lastAttributePos = iii + 1;
} }
value = _data.substring(lastElementName + white + 2, lastAttributePos); value = data.substring(lastElementName + white + 2, lastAttributePos);
//EXML_PARSE_ATTRIBUTE(pos << " attribute : " << name << "=\"" << value << "\""); //EXMLPARSEATTRIBUTE(pos << " attribute : " << name << "=\"" << value << "\"");
_pos.value = lastAttributePos - 1; pos.value = lastAttributePos - 1;
try { try {
this.builder.newProperty(parent, name, value); this.builder.newProperty(parent, name, value);
} catch (final Exception e) { } catch (final Exception e) {
@ -91,20 +88,19 @@ public class ParseXml {
return true; return true;
} }
int lastAttributePos = lastElementName + white + 3; int lastAttributePos = lastElementName + white + 3;
for (int iii = lastElementName + white + 3; iii < _data.length(); iii++) { for (int iii = lastElementName + white + 3; iii < data.length(); iii++) {
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
_filePos.check(_data.charAt(iii)); filePos.check(data.charAt(iii));
if ((_data.charAt(iii) != '"' && simpleQuoteCase == false) || (_data.charAt(iii) != '\'' && simpleQuoteCase == true)) { // ' if (((data.charAt(iii) == '"') || simpleQuoteCase) && ((data.charAt(iii) == '\'') || !simpleQuoteCase)) {
lastAttributePos = iii + 1;
} else {
break; break;
} }
lastAttributePos = iii + 1;
} }
value = _data.substring(lastElementName + white + 3, lastAttributePos); value = data.substring(lastElementName + white + 3, lastAttributePos);
//EXML_PARSE_ATTRIBUTE(pos << " attribute : " << name << "=\"" << value << "\""); //EXMLPARSEATTRIBUTE(pos << " attribute : " << name << "=\"" << value << "\"");
_pos.value = lastAttributePos; pos.value = lastAttributePos;
try { try {
this.builder.newProperty(parent, name, value); this.builder.newProperty(parent, name, value);
} catch (final Exception e) { } catch (final Exception e) {
@ -114,178 +110,170 @@ public class ParseXml {
return true; return true;
} }
protected boolean iParseCDATA(final Object parent, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException { protected boolean iParseCDATA(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException {
Log.verbose("start parse : 'text::CDATA'"); Log.verbose("start parse : 'text::CDATA'");
final FilePos pos = _filePos.clone();
// search end of the comment : // search end of the comment :
for (int iii = _pos.value; iii + 2 < _data.length(); iii++) { for (int iii = pos.value; iii + 2 < data.length(); iii++) {
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (_filePos.check(_data.charAt(iii)) == true) { if (filePos.check(data.charAt(iii))) {
continue; continue;
} }
if (_data.charAt(iii) == ']' && _data.charAt(iii + 1) == ']' && _data.charAt(iii + 2) == '>') { if (data.charAt(iii) == ']' && data.charAt(iii + 1) == ']' && data.charAt(iii + 2) == '>') {
// find end of value: // find end of value:
_filePos.add(2); filePos.add(2);
final String valueCData = _data.substring(_pos.value, iii); final String valueCData = data.substring(pos.value, iii);
Log.verbose(" find text CDATA '" + valueCData + "'"); Log.verbose(" find text CDATA '" + valueCData + "'");
_pos.value = iii + 2; pos.value = iii + 2;
this.builder.newText(parent, valueCData); this.builder.newText(parent, valueCData);
return true; return true;
} }
} }
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "text CDATA got end of file without finding end node")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "text CDATA got end of file without finding end node"));
_pos.value = _data.length(); pos.value = data.length();
return false; return false;
} }
protected boolean iParseComment(final Object parent, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException { protected boolean iParseComment(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException {
Log.verbose("start parse : 'comment'"); Log.verbose("start parse : 'comment'");
final FilePos pos = _filePos;
final FilePos tmpPos = new FilePos(); final FilePos tmpPos = new FilePos();
final int white = Tools.countWhiteChar(_data, _pos.value, tmpPos); final int white = Tools.countWhiteChar(data, pos.value, tmpPos);
_filePos.add(tmpPos); filePos.add(tmpPos);
// search end of the comment : // search end of the comment :
for (int iii = _pos.value + white; iii + 2 < _data.length(); iii++) { for (int iii = pos.value + white; iii + 2 < data.length(); iii++) {
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (_filePos.check(_data.charAt(iii)) == true) { if (filePos.check(data.charAt(iii))) {
continue; continue;
} }
if (_data.charAt(iii) == '-' && _data.charAt(iii + 1) == '-' && _data.charAt(iii + 2) == '>') { if (data.charAt(iii) == '-' && data.charAt(iii + 1) == '-' && data.charAt(iii + 2) == '>') {
_filePos.add(2); filePos.add(2);
// search whitespace : // search whitespace :
int newEnd = iii; int newEnd = iii;
for (int jjj = iii - 1; jjj > _pos.value; jjj--) { for (int jjj = iii - 1; jjj > pos.value; jjj--) {
if (Tools.isWhiteChar(_data.charAt(jjj)) == true) { if (!Tools.isWhiteChar(data.charAt(jjj))) {
newEnd = jjj;
} else {
break; break;
} }
newEnd = jjj;
} }
// find end of value: // find end of value:
final String value2 = _data.substring(_pos.value + white, newEnd); final String value2 = data.substring(pos.value + white, newEnd);
Log.verbose(" find comment '" + value2 + "'"); Log.verbose(" find comment '" + value2 + "'");
this.builder.newComment(parent, value2); this.builder.newComment(parent, value2);
_pos.value = iii + 2; pos.value = iii + 2;
return true; return true;
} }
} }
_pos.value = _data.length(); pos.value = data.length();
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "comment got end of file without finding end node")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "comment got end of file without finding end node"));
return false; return false;
} }
protected boolean iParseDeclaration(final Object parent, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) protected boolean iParseDeclaration(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException {
throws ExmlBuilderException {
final FilePos pos = _filePos;
// search end of the comment : // search end of the comment :
for (int iii = _pos.value; iii + 1 < _data.length(); iii++) { for (int iii = pos.value; iii + 1 < data.length(); iii++) {
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (_filePos.check(_data.charAt(iii)) == true) { if (filePos.check(data.charAt(iii))) {
continue; continue;
} }
if (_data.charAt(iii) == '>' || _data.charAt(iii) == '<') { if (data.charAt(iii) == '>' || data.charAt(iii) == '<') {
// an error occured : // an error occured :
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, " find '>' or '<' instead of '?>'")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, " find '>' or '<' instead of '?>'"));
return false; return false;
} }
if (_data.charAt(iii) == '?' && _data.charAt(iii + 1) == '>') { if (data.charAt(iii) == '?' && data.charAt(iii + 1) == '>') {
_filePos.increment(); filePos.increment();
// find end of declaration: // find end of declaration:
_pos.value = iii + 1; pos.value = iii + 1;
return true; return true;
} }
if (Tools.checkAvaillable(_data.charAt(iii), true) == true) { if (Tools.checkAvaillable(data.charAt(iii), true)) {
// we find an attibute ==> parse it: // we find an attibute ==> parse it:
_pos.value = iii; pos.value = iii;
if (iParseAttribute(parent, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseAttribute(parent, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
continue; continue;
} }
} }
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Text got end of file without finding end node")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Text got end of file without finding end node"));
_pos.value = _data.length(); pos.value = data.length();
return false; return false;
} }
protected boolean iParseElement(final Object parent, final String nameElement, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) protected boolean iParseElement(final Object parent, final String nameElement, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlBuilderException { throws ExmlBuilderException {
// note : When start parsing the upper element must have set the value of the element and set the position after this one // note : When start parsing the upper element must have set the value of the element and set the position after this one
final FilePos pos = _filePos.clone();
// find a normal node ... // find a normal node ...
for (int iii = _pos.value; iii < _data.length(); iii++) { for (int iii = pos.value; iii < data.length(); iii++) {
_filePos.check(_data.charAt(iii)); filePos.check(data.charAt(iii));
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (_data.charAt(iii) == '>') { if (data.charAt(iii) == '>') {
// we find the end ... // we find the end ...
_pos.value = iii + 1; pos.value = iii + 1;
return subParseElement(parent, nameElement, _data, _pos, _filePos, parsingProperty); return subParseElement(parent, nameElement, data, pos, filePos, parsingProperty);
} }
if (_data.charAt(iii) == '/') { if (data.charAt(iii) == '/') {
// standalone node or error... // standalone node or error...
if (iii + 1 >= _data.length()) { if (iii + 1 >= data.length()) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find end of files ... == > bad case")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find end of files ... == > bad case"));
return false; return false;
} }
// TODO : Can have white spaces .... // TODO : Can have white spaces ....
if (_data.charAt(iii + 1) == '>') { if (data.charAt(iii + 1) == '>') {
_pos.value = iii + 1; pos.value = iii + 1;
return true; return true;
} }
// error // error
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find / without > char ...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find / without > char ..."));
return false; return false;
} }
if (Tools.checkAvaillable(_data.charAt(iii), true) == true) { if (Tools.checkAvaillable(data.charAt(iii), true)) {
// we find an attibute ==> parse it: // we find an attibute ==> parse it:
_pos.value = iii; pos.value = iii;
if (iParseAttribute(parent, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseAttribute(parent, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
continue; continue;
} }
if (Tools.isWhiteChar(_data.charAt(iii)) == false) { if (!Tools.isWhiteChar(data.charAt(iii))) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, iii), _filePos, "Find an unknow element : '" + _data.charAt(iii) + "'")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, iii), filePos, "Find an unknow element : '" + data.charAt(iii) + "'"));
return false; return false;
} }
} }
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos,
"Unexpecting end of parsing exml::internal::Element : '" + nameElement + "' == > check if the '/>' is set or the end of element")); "Unexpecting end of parsing exml::internal::Element : '" + nameElement + "' == > check if the '/>' is set or the end of element"));
return false; return false;
} }
protected boolean iParseText(final Object parent, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException { protected boolean iParseText(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws ExmlBuilderException {
Log.verbose("start parse : 'text'"); Log.verbose("start parse : 'text'");
final FilePos pos = _filePos.clone();
// search end of the comment : // search end of the comment :
for (int iii = _pos.value; iii < _data.length(); iii++) { for (int iii = pos.value; iii < data.length(); iii++) {
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
if (_filePos.check(_data.charAt(iii)) == true) { if (filePos.check(data.charAt(iii))) {
continue; continue;
} }
if (_data.charAt(iii) == '>' || _data.charAt(iii) == '<') { if (data.charAt(iii) == '>' || data.charAt(iii) == '<') {
// search whitespace : // search whitespace :
int newEnd = iii; int newEnd = iii;
for (int jjj = iii - 1; jjj > _pos.value; --jjj) { for (int jjj = iii - 1; jjj > pos.value; --jjj) {
if (Tools.isWhiteChar(_data.charAt(jjj)) == true) { if (!Tools.isWhiteChar(data.charAt(jjj))) {
newEnd = jjj;
} else {
break; break;
} }
newEnd = jjj;
} }
// find end of value: // find end of value:
String valueText = _data.substring(_pos.value, newEnd); String valueText = data.substring(pos.value, newEnd);
Log.verbose("find text '" + valueText + "'"); Log.verbose("find text '" + valueText + "'");
_pos.value = iii - 1; pos.value = iii - 1;
valueText = Tools.replaceSpecialChar(valueText); valueText = Tools.replaceSpecialChar(valueText);
this.builder.newText(parent, valueText); this.builder.newText(parent, valueText);
return true; return true;
} }
} }
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Text got end of file without finding end node")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Text got end of file without finding end node"));
_pos.value = _data.length(); pos.value = data.length();
return false; return false;
} }
@ -297,8 +285,8 @@ public class ParseXml {
final Object rootNode = this.builder.newRoot(); final Object rootNode = this.builder.newRoot();
subParseElement(rootNode, null, data, parsePos, pos, property); subParseElement(rootNode, null, data, parsePos, pos, property);
if (property.isErrorDetected() == true) { if (property.isErrorDetected()) {
if (property.isThrowOnError() == true) { if (property.isThrowOnError()) {
throw new ExmlParserErrorMulti("Parsing error multiple error detected", property.getErrors()); throw new ExmlParserErrorMulti("Parsing error multiple error detected", property.getErrors());
} }
return null; return null;
@ -308,58 +296,57 @@ public class ParseXml {
/** /**
* Parse sub node string * Parse sub node string
* @param[in] _data all file string data * @param data all file string data
* @param[in,out] _pos Position to start parsing in the file and return the end of parsing * @param pos Position to start parsing in the file and return the end of parsing
* @param[in] _caseSensitive Case sensitive parsing (usefull for html) * @param caseSensitive Case sensitive parsing (usefull for html)
* @param[in] _filePos Current File position of the parsing * @param filePos Current File position of the parsing
* @param[in] _doc Document base reference * @param doc Document base reference
* @param[in] _mainNode if true, this is the first root node * @param mainNode if true, this is the first root node
* @return true parsing is done OK * @return true parsing is done OK
* @return false An error appear in the parsing * @return false An error appear in the parsing
*/ */
protected boolean subParseElement(final Object parent, final String nameElement, final String _data, final PositionParsing _pos, final FilePos _filePos, final ParsingProperty parsingProperty) protected boolean subParseElement(final Object parent, final String nameElement, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty)
throws ExmlBuilderException { throws ExmlBuilderException {
//EXML_PARSE_ELEMENT(" start subParse ... " << _pos << " " << _filePos); //EXMLPARSEELEMENT(" start subParse ... " << pos << " " << filePos);
for (int iii = _pos.value; iii < _data.length(); iii++) { for (int iii = pos.value; iii < data.length(); iii++) {
_filePos.check(_data.charAt(iii)); filePos.check(data.charAt(iii));
Tools.drawElementParsed(_data.charAt(iii), _filePos); Tools.drawElementParsed(data.charAt(iii), filePos);
final FilePos tmpPos = new FilePos(); final FilePos tmpPos = new FilePos();
if (_data.charAt(iii) == '<') { if (data.charAt(iii) == '<') {
final int white = Tools.countWhiteChar(_data, iii + 1, tmpPos); final int white = Tools.countWhiteChar(data, iii + 1, tmpPos);
if (iii + white + 1 >= _data.length()) { if (iii + white + 1 >= data.length()) {
_filePos.add(tmpPos); filePos.add(tmpPos);
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<' char == > invalide XML")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "End file with '<' char == > invalide XML"));
_pos.value = iii + white; pos.value = iii + white;
return false; return false;
} }
// Detect type of the element: // Detect type of the element:
if (_data.charAt(iii + white + 1) == '>') { if (data.charAt(iii + white + 1) == '>') {
_filePos.add(tmpPos); filePos.add(tmpPos);
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find '>' with no element in the element...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find '>' with no element in the element..."));
_pos.value = iii + white + 1; pos.value = iii + white + 1;
return false; return false;
} }
if (_data.charAt(iii + white + 1) == '?') { if (data.charAt(iii + white + 1) == '?') {
tmpPos.increment(); tmpPos.increment();
// TODO : white space ... // TODO : white space ...
if (Tools.checkAvaillable(_data.charAt(iii + white + 2), true) == false) { if (!Tools.checkAvaillable(data.charAt(iii + white + 2), true)) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find unavaillable name in the Declaration node...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find unavaillable name in the Declaration node..."));
_pos.value = iii + white + 1; pos.value = iii + white + 1;
return false; return false;
} }
//EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'"); //EXMLDEBUG("Generate node name : '" << data[iii+1] << "'");
int endPosName = iii + white + 1; int endPosName = iii + white + 1;
// generate element name ... // generate element name ...
for (int jjj = iii + white + 2; jjj < _data.length(); jjj++) { for (int jjj = iii + white + 2; jjj < data.length(); jjj++) {
if (Tools.checkAvaillable(_data.charAt(jjj), false) == true) { if (!Tools.checkAvaillable(data.charAt(jjj), false)) {
// we find the end ...
endPosName = jjj;
} else {
break; break;
} }
tmpPos.check(_data.charAt(jjj)); // we find the end ...
endPosName = jjj;
tmpPos.check(data.charAt(jjj));
} }
String tmpname = _data.substring(iii + white + 2, endPosName + 1); String tmpname = data.substring(iii + white + 2, endPosName + 1);
if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) { if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) {
tmpname = tmpname.toLowerCase(); tmpname = tmpname.toLowerCase();
} else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) { } else if (parsingProperty.getStoreMode() == StoreMode.UPPERCASE) {
@ -367,135 +354,133 @@ public class ParseXml {
} }
// Find declaration marker // Find declaration marker
final Object declaration = this.builder.newDeclaration(parent, tmpname); final Object declaration = this.builder.newDeclaration(parent, tmpname);
_filePos.add(tmpPos); filePos.add(tmpPos);
_pos.value = endPosName + 1; pos.value = endPosName + 1;
Log.verbose("start parse : 'declaration' : '" + tmpname + "'"); Log.verbose("start parse : 'declaration' : '" + tmpname + "'");
if (iParseDeclaration(declaration, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseDeclaration(declaration, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
continue; continue;
} }
if (_data.charAt(iii + white + 1) == '!') { if (data.charAt(iii + white + 1) == '!') {
tmpPos.increment(); tmpPos.increment();
// Find special block element // Find special block element
if (iii + white + 2 >= _data.length()) { if (iii + white + 2 >= data.length()) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<!' chars == > invalide XML")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "End file with '<!' chars == > invalide XML"));
return false; return false;
} }
if (_data.charAt(iii + white + 2) == '-') { if (data.charAt(iii + white + 2) == '-') {
tmpPos.increment(); tmpPos.increment();
if (iii + white + 3 >= _data.length()) { if (iii + white + 3 >= data.length()) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<!-' chars == > invalide XML")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "End file with '<!-' chars == > invalide XML"));
return false; return false;
} }
if (_data.charAt(iii + white + 3) != '-') { if (data.charAt(iii + white + 3) != '-') {
parsingProperty parsingProperty
.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Element parse with '<!-" + _data.charAt(iii + 3) + "' chars == > invalide XML")); .createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Element parse with '<!-" + data.charAt(iii + 3) + "' chars == > invalide XML"));
return false; return false;
} }
tmpPos.increment(); tmpPos.increment();
// find comment: // find comment:
_pos.value = iii + white + 4; pos.value = iii + white + 4;
_filePos.add(tmpPos); filePos.add(tmpPos);
if (iParseComment(parent, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseComment(parent, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
} else if (_data.charAt(iii + white + 2) == '[') { } else if (data.charAt(iii + white + 2) == '[') {
tmpPos.increment(); tmpPos.increment();
if (iii + white + 8 >= _data.length()) { if (iii + white + 8 >= data.length()) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<![' chars == > invalide XML")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "End file with '<![' chars == > invalide XML"));
return false; return false;
} }
if (_data.charAt(iii + white + 3) != 'C' || _data.charAt(iii + white + 4) != 'D' || _data.charAt(iii + white + 5) != 'A' || _data.charAt(iii + white + 6) != 'T' if (data.charAt(iii + white + 3) != 'C' || data.charAt(iii + white + 4) != 'D' || data.charAt(iii + white + 5) != 'A' || data.charAt(iii + white + 6) != 'T'
|| _data.charAt(iii + white + 7) != 'A' || _data.charAt(iii + white + 8) != '[') { || data.charAt(iii + white + 7) != 'A' || data.charAt(iii + white + 8) != '[') {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos,
"Element parse with '<![" + _data.charAt(iii + white + 3) + _data.charAt(iii + white + 4) + _data.charAt(iii + white + 5) + _data.charAt(iii + white + 6) "Element parse with '<![" + data.charAt(iii + white + 3) + data.charAt(iii + white + 4) + data.charAt(iii + white + 5) + data.charAt(iii + white + 6)
+ _data.charAt(iii + white + 7) + _data.charAt(iii + white + 8) + "' chars == > invalide XML")); + data.charAt(iii + white + 7) + data.charAt(iii + white + 8) + "' chars == > invalide XML"));
return false; return false;
} }
tmpPos.add(6); tmpPos.add(6);
// find text: // find text:
_pos.value = iii + 9 + white; pos.value = iii + 9 + white;
_filePos.add(tmpPos); filePos.add(tmpPos);
if (iParseCDATA(parent, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseCDATA(parent, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
} else { } else {
parsingProperty parsingProperty
.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End file with '<!" + _data.charAt(iii + white + 2) + "' chars == > invalide XML")); .createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "End file with '<!" + data.charAt(iii + white + 2) + "' chars == > invalide XML"));
return false; return false;
} }
continue; continue;
} }
if (_data.charAt(iii + white + 1) == '/') { if (data.charAt(iii + white + 1) == '/') {
tmpPos.increment(); tmpPos.increment();
//EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'"); //EXMLDEBUG("Generate node name : '" << data[iii+1] << "'");
int endPosName = iii + white + 1; int endPosName = iii + white + 1;
// generate element name ... // generate element name ...
for (int jjj = iii + white + 2; jjj < _data.length(); jjj++) { for (int jjj = iii + white + 2; jjj < data.length(); jjj++) {
if (Tools.checkAvaillable(_data.charAt(jjj), false) == true) { if (!Tools.checkAvaillable(data.charAt(jjj), false)) {
// we find the end ...
endPosName = jjj;
} else {
break; break;
} }
tmpPos.check(_data.charAt(jjj)); // we find the end ...
endPosName = jjj;
tmpPos.check(data.charAt(jjj));
} }
final String tmpname = _data.substring(iii + white + 2, endPosName + 1); final String tmpname = data.substring(iii + white + 2, endPosName + 1);
String tmpnameCheck = tmpname; String tmpnameCheck = tmpname;
String nameElementCheck = nameElement; String nameElementCheck = nameElement;
if (parsingProperty.getCaseSensitive() == true) { if (parsingProperty.getCaseSensitive()) {
tmpnameCheck = tmpname.toLowerCase(); tmpnameCheck = tmpname.toLowerCase();
nameElementCheck = nameElement.toLowerCase(); nameElementCheck = nameElement.toLowerCase();
} }
if (tmpnameCheck.contentEquals(nameElementCheck) == true) { if (!tmpnameCheck.contentEquals(nameElementCheck)) {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "End node error : '" + tmpname + "' != '" + nameElement + "'"));
return false;
}
// find end of node : // find end of node :
// find > element ... // find > element ...
for (int jjj = endPosName + 1; jjj < _data.length(); jjj++) { for (int jjj = endPosName + 1; jjj < data.length(); jjj++) {
Tools.drawElementParsed(_data.charAt(jjj), _filePos); Tools.drawElementParsed(data.charAt(jjj), filePos);
if (tmpPos.check(_data.charAt(jjj)) == true) { if (tmpPos.check(data.charAt(jjj))) {
continue; continue;
} }
if (_data.charAt(jjj) == '>') { if (data.charAt(jjj) == '>') {
_pos.value = jjj; pos.value = jjj;
_filePos.add(tmpPos); filePos.add(tmpPos);
return true; return true;
} else if (_data.charAt(jjj) != '\r' && _data.charAt(jjj) != ' ' && _data.charAt(jjj) != '\t') { }
_filePos.add(tmpPos); if (data.charAt(jjj) != '\r' && data.charAt(jjj) != ' ' && data.charAt(jjj) != '\t') {
parsingProperty.createError( filePos.add(tmpPos);
new ExmlParserError(Tools.extractLine(_data, jjj), _filePos, "End node error : have data inside end node other than [ \\n\\t\\r] " + nameElement + "'")); parsingProperty
.createError(new ExmlParserError(Tools.extractLine(data, jjj), filePos, "End node error : have data inside end node other than [ \\n\\t\\r] " + nameElement + "'"));
return false; return false;
} }
} }
} else {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "End node error : '" + tmpname + "' != '" + nameElement + "'"));
return false;
} }
} if (data.charAt(iii + white + 1) == '>') {
if (_data.charAt(iii + white + 1) == '>') {
// end of something == > this is really bad // end of something == > this is really bad
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find '>' chars == > invalide XML")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find '>' chars == > invalide XML"));
return false; return false;
} }
if (Tools.checkAvaillable(_data.charAt(iii + white + 1), true) == true) { if (Tools.checkAvaillable(data.charAt(iii + white + 1), true)) {
tmpPos.increment(); tmpPos.increment();
Log.debug("Generate node name : '" + _data.charAt(iii + 1) + "'"); Log.debug("Generate node name : '" + data.charAt(iii + 1) + "'");
int endPosName = iii + white + 1; int endPosName = iii + white + 1;
// generate element name ... // generate element name ...
for (int jjj = iii + white + 2; jjj < _data.length(); jjj++) { for (int jjj = iii + white + 2; jjj < data.length(); jjj++) {
if (Tools.checkAvaillable(_data.charAt(jjj), false) == true) { if (!Tools.checkAvaillable(data.charAt(jjj), false)) {
// we find the end ...
endPosName = jjj;
} else {
break; break;
} }
tmpPos.check(_data.charAt(jjj)); // we find the end ...
endPosName = jjj;
tmpPos.check(data.charAt(jjj));
} }
String tmpname = _data.substring(iii + white + 1, endPosName + 1); String tmpname = data.substring(iii + white + 1, endPosName + 1);
final String tmpnameOriginal = tmpname; final String tmpnameOriginal = tmpname;
if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) { if (parsingProperty.getStoreMode() == StoreMode.LOWERCASE) {
tmpname = tmpname.toLowerCase(); tmpname = tmpname.toLowerCase();
@ -512,42 +497,41 @@ public class ParseXml {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
_pos.value = endPosName + 1; pos.value = endPosName + 1;
_filePos.add(tmpPos); filePos.add(tmpPos);
Log.verbose("start parse : 'element' named='" + tmpname + "'"); Log.verbose("start parse : 'element' named='" + tmpname + "'");
if (iParseElement(element, tmpnameOriginal, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseElement(element, tmpnameOriginal, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
continue; continue;
} }
_filePos.add(tmpPos); filePos.add(tmpPos);
// here we have an error : // here we have an error :
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find an ununderstanding element : '" + _data.charAt(iii + white + 1) + "'")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find an ununderstanding element : '" + data.charAt(iii + white + 1) + "'"));
return false; return false;
} else { }
if (_data.charAt(iii) == '>') { if (data.charAt(iii) == '>') {
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Find elemement '>' == > no reason to be here ...")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Find elemement '>' == > no reason to be here ..."));
return false; return false;
} }
// might to be data text ... // might to be data text ...
if (_data.charAt(iii) == '\n' || _data.charAt(iii) == ' ' || _data.charAt(iii) == '\t' || _data.charAt(iii) == '\r') { if (data.charAt(iii) == '\n' || data.charAt(iii) == ' ' || data.charAt(iii) == '\t' || data.charAt(iii) == '\r') {
// empty spaces == > nothing to do .... // empty spaces == > nothing to do ....
} else { } else {
// find data == > parse it... // find data == > parse it...
_pos.value = iii; pos.value = iii;
_filePos.add(tmpPos); filePos.add(tmpPos);
if (iParseText(parent, _data, _pos, _filePos, parsingProperty) == false) { if (!iParseText(parent, data, pos, filePos, parsingProperty)) {
return false; return false;
} }
iii = _pos.value; iii = pos.value;
}
} }
} }
if (nameElement == null) { if (nameElement == null) {
return true; return true;
} }
parsingProperty.createError(new ExmlParserError(Tools.extractLine(_data, _pos.value), _filePos, "Did not find end of the Element : '" + nameElement + "'")); parsingProperty.createError(new ExmlParserError(Tools.extractLine(data, pos.value), filePos, "Did not find end of the Element : '" + nameElement + "'"));
return false; return false;
} }
} }

View File

@ -10,16 +10,16 @@ import org.atriasoft.exml.internal.Log;
public class ParsingProperty { public class ParsingProperty {
/// check the case sensitive of the nodes (end marker) and attribute (duplicates) /// check the case sensitive of the nodes (end marker) and attribute (duplicates)
private boolean caseSensitive = true; private boolean caseSensitive = true;
// Mode to store the Element name or the Attibute name
private StoreMode storeMode = StoreMode.NORMAL;
/// write error when not throw on error.
private boolean writeError = false;
/// throw when an error when it is detected (if permissive XML it throw only at the end of parsing).
private boolean throwOnError = true;
/// Permissive XML parsing (allows some errors must not be critical).
private boolean permisiveXML = false;
// List of all error detected // List of all error detected
private final List<ExmlParserError> errors = new ArrayList<>(); private final List<ExmlParserError> errors = new ArrayList<>();
/// Permissive XML parsing (allows some errors must not be critical).
private boolean permisiveXML = false;
// Mode to store the Element name or the Attibute name
private StoreMode storeMode = StoreMode.NORMAL;
/// throw when an error when it is detected (if permissive XML it throw only at the end of parsing).
private boolean throwOnError = true;
/// write error when not throw on error.
private boolean writeError = false;
/** /**
* Constructor * Constructor
@ -48,23 +48,23 @@ public class ParsingProperty {
*/ */
public boolean createError(final ExmlParserError error) throws ExmlParserError { public boolean createError(final ExmlParserError error) throws ExmlParserError {
// need display the error // need display the error
if (this.writeError == true) { if (this.writeError) {
displayError(error); displayError(error);
} }
// need throw the error // need throw the error
if (this.throwOnError == true && this.permisiveXML == false) { if (this.throwOnError && !this.permisiveXML) {
throw error; throw error;
} }
// Keep it in case // Keep it in case
this.errors.add(error); this.errors.add(error);
return this.permisiveXML == false; return !this.permisiveXML;
} }
/** /**
* Request Display in log all the errors. * Request Display in log all the errors.
*/ */
public void displayError() { public void displayError() {
this.errors.forEach(o -> displayError(o)); this.errors.forEach(this::displayError);
} }
/** /**
@ -113,7 +113,7 @@ public class ParsingProperty {
* @return true if some error are stored. * @return true if some error are stored.
*/ */
public boolean isErrorDetected() { public boolean isErrorDetected() {
return this.errors.isEmpty() == false; return !this.errors.isEmpty();
} }
/** /**
@ -134,18 +134,18 @@ public class ParsingProperty {
/** /**
* Enable or diasable the case sensitive (must be done before the call of parsing) * Enable or diasable the case sensitive (must be done before the call of parsing)
* @param[in] _val true if enable; false else. * @param val true if enable; false else.
*/ */
public void setCaseSensitive(final boolean _val) { public void setCaseSensitive(final boolean val) {
this.caseSensitive = _val; this.caseSensitive = val;
} }
/** /**
* Set the display of the error when detected. * Set the display of the error when detected.
* @param[in] _value true: display error, false not display error (get it at end) * @param value true: display error, false not display error (get it at end)
*/ */
public void setDisplayError(final boolean _value) { public void setDisplayError(final boolean value) {
this.writeError = _value; this.writeError = value;
} }
/** /**

View File

@ -3,31 +3,30 @@ package org.atriasoft.exml.parser;
public class Tools { public class Tools {
/** /**
* add indentation of the string input. * add indentation of the string input.
* @param[in,out] _data String where the indentation is done. * @param data String where the indentation is done.
* @param[in] _indent Number of tab to add at the string. * @param indent Number of tab to add at the string.
*/ */
public static void addIndent(final StringBuilder _data, final int _indent) { public static void addIndent(final StringBuilder data, final int indent) {
for (int iii = 0; iii < _indent; iii++) { for (int iii = 0; iii < indent; iii++) {
_data.append("\t"); data.append("\t");
} }
} }
/** /**
* check if an element or attribute is availlable (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \\n\\t\\r and for first char : not -.0123456789). * check if an element or attribute is availlable (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \\n\\t\\r and for first char : not -.0123456789).
* @param[in] _val Value to check the conformity. * @param val Value to check the conformity.
* @param[in] _firstChar True if the element check is the first char. * @param firstChar True if the element check is the first char.
* @return true The value can be a part of attribute name * @return true The value can be a part of attribute name
* @return false The value can NOT 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) { public static boolean checkAvaillable(final Character val, final boolean firstChar) {
if (_val == '!' || _val == '"' || _val == '#' || _val == '$' || _val == '%' || _val == '&' || _val == '\'' // ' 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 == '?' || val == '@' || val == '['
|| _val == '[' || _val == '\\' || _val == ']' || _val == '^' || _val == '`' || _val == '{' || _val == '|' || _val == '}' || _val == '~' || _val == ' ' || _val == '\n' || _val == '\t' || val == '\\' || val == ']' || val == '^' || val == '`' || val == '{' || val == '|' || val == '}' || val == '~' || val == ' ' || val == '\n' || val == '\t' || val == '\r') {
|| _val == '\r') {
return false; return false;
} }
if (_firstChar == true) { if (firstChar) {
if (_val == '-' || _val == '.' || (_val >= '0' && _val <= '9')) { if (val == '-' || val == '.' || (val >= '0' && val <= '9')) {
return false; return false;
} }
} }
@ -40,37 +39,36 @@ public class Tools {
/** /**
* count the number of white char in the string from the specify position (stop at the first element that is not a white char) * count the number of white char in the string from the specify position (stop at the first element that is not a white char)
* @param[in] _data Data to parse. * @param data Data to parse.
* @param[in] _pos Start position in the string. * @param pos Start position in the string.
* @param[out] _filePos new poistion of te file to add. * @param filePos new poistion of te file to add.
* @return number of white element. * @return number of white element.
*/ */
public static int countWhiteChar(final String _data, final int _pos, final FilePos _filePos) { public static int countWhiteChar(final String data, final int pos, final FilePos filePos) {
_filePos.clear(); filePos.clear();
int white = 0; int white = 0;
for (int iii = _pos; iii < _data.length(); iii++) { for (int iii = pos; iii < data.length(); iii++) {
_filePos.check(_data.charAt(iii)); filePos.check(data.charAt(iii));
if (Tools.isWhiteChar(_data.charAt(iii)) == true) { if (!Tools.isWhiteChar(data.charAt(iii))) {
white++;
} else {
break; break;
} }
white++;
} }
_filePos.decrement(); filePos.decrement();
return white; return white;
} }
public static String createPosPointer(final String _line, final int _pos) { public static String createPosPointer(final String line, final int pos) {
String out = ""; String out = "";
int iii; int iii;
for (iii = 0; iii < _pos && iii < _line.length(); iii++) { for (iii = 0; iii < pos && iii < line.length(); iii++) {
if (_line.charAt(iii) == '\t') { if (line.charAt(iii) == '\t') {
out += "\t"; out += "\t";
} else { } else {
out += " "; out += " ";
} }
} }
for (; iii < _pos; iii++) { for (; iii < pos; iii++) {
out += " "; out += " ";
} }
out += "^"; out += "^";
@ -82,41 +80,41 @@ public class Tools {
if (string == null || string.length() == 0) { if (string == null || string.length() == 0) {
return string; return string;
} }
final char c[] = string.toCharArray(); final char[] c = string.toCharArray();
c[0] = Character.toLowerCase(c[0]); c[0] = Character.toLowerCase(c[0]);
return new String(c); return new String(c);
} }
/** /**
* Display the cuurent element that is curently parse. * Display the cuurent element that is curently parse.
* @param[in] _val Char that is parsed. * @param val Char that is parsed.
* @param[in] _filePos Position of the char in the file. * @param filePos Position of the char in the file.
*/ */
public static void drawElementParsed(final Character _val, final FilePos _filePos) { public static void drawElementParsed(final Character val, final FilePos filePos) {
// if (_val == '\n') { // if (val == '\n') {
// Log.debug(_filePos + " parse '\\n'"); // Log.debug(filePos + " parse '\\n'");
// } else if (_val == '\t') { // } else if (val == '\t') {
// Log.debug(_filePos + " parse '\\t'"); // Log.debug(filePos + " parse '\\t'");
// } else { // } else {
// Log.debug(_filePos + " parse '" + _val + "'"); // Log.debug(filePos + " parse '" + val + "'");
// } // }
} }
public static String extractLine(final String data, final int _pos) { public static String extractLine(final String data, final int pos) {
// search back : '\n' // search back : '\n'
int startPos = data.lastIndexOf('\n', _pos); int startPos = data.lastIndexOf('\n', pos);
if (startPos == _pos) { if (startPos == pos) {
startPos = 0; startPos = 0;
} else { } else {
startPos++; startPos++;
} }
// search forward : '\n' // search forward : '\n'
int stopPos = _pos; int stopPos = pos;
if (data.length() == _pos) { if (data.length() == pos) {
stopPos = _pos; stopPos = pos;
} else if (data.charAt(_pos) != '\n') { } else if (data.charAt(pos) != '\n') {
stopPos = data.indexOf('\n', _pos); stopPos = data.indexOf('\n', pos);
if (stopPos == _pos) { if (stopPos == pos) {
stopPos = data.length(); stopPos = data.length();
} }
} }
@ -127,22 +125,23 @@ public class Tools {
} }
if (stopPos == -1) { if (stopPos == -1) {
return ""; return "";
} else if (stopPos >= data.length()) { }
if (stopPos >= data.length()) {
stopPos = data.length(); stopPos = data.length();
} }
return data.substring(startPos, stopPos); return data.substring(startPos, stopPos);
} }
public static boolean isWhiteChar(final Character _val) { public static boolean isWhiteChar(final Character val) {
if (_val == ' ' || _val == '\t' || _val == '\n' || _val == '\r') { if (val == ' ' || val == '\t' || val == '\n' || val == '\r') {
return true; return true;
} }
return false; return false;
} }
public static Boolean[] parseBooleanClassStringList(String data) { // throws NumberFormatException public static Boolean[] parseBooleanClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final Boolean[] out = new Boolean[dataArray.length]; final Boolean[] out = new Boolean[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -152,19 +151,19 @@ public class Tools {
} }
public static boolean[] parseBooleanStringList(String data) { // throws NumberFormatException public static boolean[] parseBooleanStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final boolean[] out = new boolean[dataArray.length]; final boolean[] out = new boolean[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
out[count++] = Boolean.valueOf(str); out[count++] = Boolean.parseBoolean(str);
} }
return out; return out;
} }
public static Byte[] parseByteClassStringList(String data) { // throws NumberFormatException public static Byte[] parseByteClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final Byte[] out = new Byte[dataArray.length]; final Byte[] out = new Byte[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -174,8 +173,8 @@ public class Tools {
} }
public static byte[] parseByteStringList(String data) { // throws NumberFormatException public static byte[] parseByteStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final byte[] out = new byte[dataArray.length]; final byte[] out = new byte[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -185,8 +184,8 @@ public class Tools {
} }
public static Integer[] parseIntegerClassStringList(String data) { // throws NumberFormatException public static Integer[] parseIntegerClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final Integer[] out = new Integer[dataArray.length]; final Integer[] out = new Integer[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -196,8 +195,8 @@ public class Tools {
} }
public static int[] parseIntegerStringList(String data) { // throws NumberFormatException public static int[] parseIntegerStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final int[] out = new int[dataArray.length]; final int[] out = new int[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -207,8 +206,8 @@ public class Tools {
} }
public static Long[] parseLongClassStringList(String data) { // throws NumberFormatException public static Long[] parseLongClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final Long[] out = new Long[dataArray.length]; final Long[] out = new Long[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -218,8 +217,8 @@ public class Tools {
} }
public static long[] parseLongStringList(String data) { // throws NumberFormatException public static long[] parseLongStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final long[] out = new long[dataArray.length]; final long[] out = new long[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -229,8 +228,8 @@ public class Tools {
} }
public static Short[] parseShortClassStringList(String data) { // throws NumberFormatException public static Short[] parseShortClassStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final Short[] out = new Short[dataArray.length]; final Short[] out = new Short[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -240,8 +239,8 @@ public class Tools {
} }
public static short[] parseShortStringList(String data) { // throws NumberFormatException public static short[] parseShortStringList(String data) { // throws NumberFormatException
data = cleanNumberList(data); data = Tools.cleanNumberList(data);
final String dataArray[] = data.split(";"); final String[] dataArray = data.split(";");
final short[] out = new short[dataArray.length]; final short[] out = new short[dataArray.length];
int count = 0; int count = 0;
for (final String str : dataArray) { for (final String str : dataArray) {
@ -256,25 +255,25 @@ public class Tools {
// "&amp;" == "&" // "&amp;" == "&"
// "&apos;" == "'" // "&apos;" == "'"
// "&quot;" == """ // "&quot;" == """
public static String replaceSpecialChar(final String _inval) { public static String replaceSpecialChar(final String inval) {
final String out = _inval; String out = inval;
out.replace("&lt;", "<"); out = out.replace("&lt;", "<");
out.replace("&gt;", ">"); out = out.replace("&gt;", ">");
out.replace("&apos;", "'"); out = out.replace("&apos;", "'");
out.replace("&quot;", "\""); out = out.replace("&quot;", "\"");
out.replace("&amp;", "&"); out = out.replace("&amp;", "&");
//EXML_ERROR("INNN '"<< _inval << "' => '" << out << "'"); //EXMLERROR("INNN '"<< inval << "' => '" << out << "'");
return out; return out;
} }
public static String replaceSpecialCharOut(final String _inval) { public static String replaceSpecialCharOut(final String inval) {
final String out = _inval; String out = inval;
out.replace("<", "&lt;"); out = out.replace("<", "&lt;");
out.replace(">", "&gt;"); out = out.replace(">", "&gt;");
out.replace("'", "&apos;"); out = out.replace("'", "&apos;");
out.replace("\"", "&quot;"); out = out.replace("\"", "&quot;");
out.replace("&", "&amp;"); out = out.replace("&", "&amp;");
//EXML_ERROR("OUTTT '"<< _inval << "' => '" << out << "'"); //EXMLERROR("OUTTT '"<< inval << "' => '" << out << "'");
return out; return out;
} }

View File

@ -14,16 +14,15 @@ import org.atriasoft.exml.model.XmlText;
import org.atriasoft.exml.parser.Tools; import org.atriasoft.exml.parser.Tools;
public class SerializerXml { public class SerializerXml {
public static void serialize(final XmlNode node, final StringBuilder data, final int indent) { public static void serialize(final XmlNode node, final StringBuilder data, final int indent) {
if (node instanceof XmlElement) { if (node instanceof XmlElement) {
serializeElement((XmlElement) node, data, indent); SerializerXml.serializeElement((XmlElement) node, data, indent);
} else if (node instanceof XmlText) { } else if (node instanceof XmlText) {
serializeText((XmlText) node, data, indent); SerializerXml.serializeText((XmlText) node, data, indent);
} else if (node instanceof XmlDeclaration) { } else if (node instanceof XmlDeclaration) {
serializeDeclaration((XmlDeclaration) node, data, indent); SerializerXml.serializeDeclaration((XmlDeclaration) node, data, indent);
} else if (node instanceof XmlComment) { } else if (node instanceof XmlComment) {
serializeComment((XmlComment) node, data, indent); SerializerXml.serializeComment((XmlComment) node, data, indent);
} else { } else {
// TODO throw an error ... // TODO throw an error ...
} }
@ -39,7 +38,7 @@ public class SerializerXml {
private static void serializeAttributeList(final XmlAttributeList list, final StringBuilder data, final int indent) { private static void serializeAttributeList(final XmlAttributeList list, final StringBuilder data, final int indent) {
for (int iii = 0; iii < list.getAttributes().size(); iii++) { for (int iii = 0; iii < list.getAttributes().size(); iii++) {
serializeAttribute(list.getAttributes().get(iii), data, indent); SerializerXml.serializeAttribute(list.getAttributes().get(iii), data, indent);
} }
} }
@ -54,7 +53,7 @@ public class SerializerXml {
Tools.addIndent(data, indent); Tools.addIndent(data, indent);
data.append("<?"); data.append("<?");
data.append(declaration.getValue()); data.append(declaration.getValue());
serializeAttributeList(declaration, data, indent); SerializerXml.serializeAttributeList(declaration, data, indent);
data.append("?>\n"); data.append("?>\n");
} }
@ -64,19 +63,19 @@ public class SerializerXml {
Tools.addIndent(data, indent); Tools.addIndent(data, indent);
data.append("<"); data.append("<");
data.append(element.getValue()); data.append(element.getValue());
serializeAttributeList(element, data, indent); SerializerXml.serializeAttributeList(element, data, indent);
final List<XmlNode> nodes = element.getNodes(); final List<XmlNode> nodes = element.getNodes();
if (nodes.size() > 0) { if (nodes.size() > 0) {
if (nodes.size() == 1 && nodes.get(0) != null && nodes.get(0).getType() == XmlNodeType.TEXT && ((XmlText) nodes.get(0)).countLines() == 1) { if (nodes.size() == 1 && nodes.get(0) != null && nodes.get(0).getType() == XmlNodeType.TEXT && ((XmlText) nodes.get(0)).countLines() == 1) {
data.append(">"); data.append(">");
serialize(nodes.get(0), data, 0); SerializerXml.serialize(nodes.get(0), data, 0);
Log.verbose(" generate : '" + data + "'"); Log.verbose(" generate : '" + data + "'");
} else { } else {
data.append(">\n"); data.append(">\n");
for (int iii = 0; iii < nodes.size(); iii++) { for (XmlNode node : nodes) {
if (nodes.get(iii) != null) { if (node != null) {
serialize(nodes.get(iii), data, indent + 1); SerializerXml.serialize(node, data, indent + 1);
} }
} }
Tools.addIndent(data, indent); Tools.addIndent(data, indent);
@ -92,7 +91,7 @@ public class SerializerXml {
public static void serializeRoot(final XmlElement root, final StringBuilder data) { public static void serializeRoot(final XmlElement root, final StringBuilder data) {
for (int iii = 0; iii < root.getNodes().size(); iii++) { for (int iii = 0; iii < root.getNodes().size(); iii++) {
final XmlNode node = root.getNodes().get(iii); final XmlNode node = root.getNodes().get(iii);
serialize(node, data, 0); SerializerXml.serialize(node, data, 0);
} }
} }
@ -109,4 +108,6 @@ public class SerializerXml {
return true; return true;
} }
*/ */
private SerializerXml() {}
} }

View File

@ -11,37 +11,36 @@ import org.atriasoft.exml.model.XmlNode;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
class ExmlLocal { class ExmlLocal {
// _errorPos : -1 : no error , 1 : parsing error, 2 generation error, 3 comparaison error ???? // errorPos : -1 : no error , 1 : parsing error, 2 generation error, 3 comparaison error ????
public static void test(final String _ref, final String _input, final int _errorPos) { public static void test(final String ref, final String input, final int errorPos) {
test(_ref, _input, _errorPos, false); ExmlLocal.test(ref, input, errorPos, false);
} }
public static void test(final String _ref, final String _input, final int _errorPos, final boolean _caseInSensitive) { public static void test(final String ref, final String input, final int errorPos, final boolean caseInSensitive) {
//doc.setCaseSensitive(!_caseInSensitive); //doc.setCaseSensitive(!caseInSensitive);
Log.verbose("parse : \n" + _input); Log.verbose("parse : \n" + input);
XmlNode root = null; XmlNode root = null;
try { try {
root = Exml.parse(_input); root = Exml.parse(input);
if (_errorPos == 1) { if (errorPos == 1) {
Assertions.fail("Must have detected an error"); Assertions.fail("Must have detected an error");
return; return;
} }
} catch (final ExmlBuilderException e) { } catch (final ExmlBuilderException e) {
if (_errorPos == 1) { if (errorPos == 1) {
return; return;
} else { }
Assertions.fail("Must have NOT detected an error"); Assertions.fail("Must have NOT detected an error");
} }
}
final StringBuilder out = new StringBuilder(); final StringBuilder out = new StringBuilder();
// TODO: 2 is for failing in generate ... // TODO 2 is for failing in generate ...
Exml.generate(root, out); Exml.generate(root, out);
final String data = out.toString(); final String data = out.toString();
if (_errorPos == 3) { if (errorPos == 3) {
Assertions.assertNotEquals(_ref, data); Assertions.assertNotEquals(ref, data);
return;
} else {
Assertions.assertEquals(_ref, data);
} }
Assertions.assertEquals(ref, data);
} }
private ExmlLocal() {}
} }

View File

@ -20,7 +20,7 @@ public class ExmlTestAttribute {
} }
@Test @Test
public void AttributeElementNotExist() { public void attributeElementNotExist() {
final XmlElement myElement = new XmlElement("NodeName"); final XmlElement myElement = new XmlElement("NodeName");
Assertions.assertThrows(ExmlAttributeDoesNotExist.class, () -> myElement.getAttr(65465465)); Assertions.assertThrows(ExmlAttributeDoesNotExist.class, () -> myElement.getAttr(65465465));
} }

View File

@ -3,26 +3,26 @@ package test.atriasoft.exml.introspection;
import org.atriasoft.exml.annotation.XmlName; import org.atriasoft.exml.annotation.XmlName;
public class ClassPublicMemberOnly { public class ClassPublicMemberOnly {
@XmlName(value = { "jhkjhhkj" })
public byte memberByte;
public short memberShort;
public int memberInteger;
public long memberLong;
public boolean memberBoolean;
public Byte memberByteClass;
public Short memberShortClass;
public Integer memberIntegerClass;
public Long memberLongClass;
public Boolean memberBooleanClass;
public String memberStringClass;
public byte[] memberArrayByte;
public short[] memberArrayShort;
public int[] memberArrayInteger;
public long[] memberArrayLong;
public boolean[] memberArrayBoolean; public boolean[] memberArrayBoolean;
public Byte[] memberArrayByteClass;
public Short[] memberArrayShortClass;
public Integer[] memberArrayIntegerClass;
public Long[] memberArrayLongClass;
public Boolean[] memberArrayBooleanClass; public Boolean[] memberArrayBooleanClass;
public byte[] memberArrayByte;
public Byte[] memberArrayByteClass;
public int[] memberArrayInteger;
public Integer[] memberArrayIntegerClass;
public long[] memberArrayLong;
public Long[] memberArrayLongClass;
public short[] memberArrayShort;
public Short[] memberArrayShortClass;
public boolean memberBoolean;
public Boolean memberBooleanClass;
@XmlName(value = "jhkjhhkj")
public byte memberByte;
public Byte memberByteClass;
public int memberInteger;
public Integer memberIntegerClass;
public long memberLong;
public Long memberLongClass;
public short memberShort;
public Short memberShortClass;
public String memberStringClass;
} }

View File

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