[DEV] add ignoring missing and default null in record constructor
This commit is contained in:
parent
4a32ec0b15
commit
ce7b909cb0
@ -99,7 +99,7 @@ public class Exml {
|
||||
}
|
||||
return null;
|
||||
} catch (final ExmlException ex) {
|
||||
//ex.printStackTrace();
|
||||
ex.printStackTrace();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@ -203,7 +203,17 @@ public class Exml {
|
||||
* @return false : An error occured
|
||||
* @return true : Parsing is OK
|
||||
*/
|
||||
public static void store(final Uri uri, final Object root, final String rootNodeName) throws ExmlException, IOException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Exml.generate(root, rootNodeName, builder);
|
||||
Uri.writeAll(uri, builder.toString());
|
||||
}
|
||||
|
||||
public static void store(final Path path, final Object root, final String rootNodeName) throws ExmlException, IOException {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Exml.generate(root, rootNodeName, builder);
|
||||
Files.writeString(path, builder.toString());
|
||||
}
|
||||
/*
|
||||
* public boolean store( Uri _uri){ String createData; if (generate(createData)
|
||||
* == false) { Log.error("Error while creating the XML: " + _uri); return false;
|
||||
|
18
src/org/atriasoft/exml/annotation/XmlDefaultNullValue.java
Normal file
18
src/org/atriasoft/exml/annotation/XmlDefaultNullValue.java
Normal file
@ -0,0 +1,18 @@
|
||||
package org.atriasoft.exml.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ExmlAnnotation
|
||||
public @interface XmlDefaultNullValue {
|
||||
/**
|
||||
* Set the default value at true in the constructor if needed (set at 0 for basic type int, long ...).
|
||||
* @return true if the element are by default at null.
|
||||
*/
|
||||
boolean value() default true;
|
||||
|
||||
}
|
20
src/org/atriasoft/exml/annotation/XmlIgnoreUnknow.java
Normal file
20
src/org/atriasoft/exml/annotation/XmlIgnoreUnknow.java
Normal file
@ -0,0 +1,20 @@
|
||||
package org.atriasoft.exml.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marker annotation that permit to set the default parsing as attributes.
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ExmlAnnotation
|
||||
public @interface XmlIgnoreUnknow {
|
||||
/**
|
||||
* Set the element ignore unknown Nodes.
|
||||
* @return true does not display unknown node.
|
||||
*/
|
||||
boolean value() default true;
|
||||
}
|
@ -9,7 +9,7 @@ import java.lang.annotation.Target;
|
||||
* Marker annotation that force the xml Parser to manage this element (used when the class is mark as @XmldefaultNotManaged).
|
||||
*
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD})
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ExmlAnnotation
|
||||
public @interface XmlManaged {
|
||||
|
@ -7,7 +7,6 @@ import org.atriasoft.eStringSerialize.StringSerializer;
|
||||
import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.exception.ExmlException;
|
||||
import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
|
||||
import org.atriasoft.exml.internal.Log;
|
||||
|
||||
public class BuilderIntrospection implements Builder {
|
||||
@ -55,6 +54,10 @@ public class BuilderIntrospection implements Builder {
|
||||
}
|
||||
typeClass = model.getClassType();
|
||||
} else {
|
||||
if (!introspectionObject.isSubNodeOrPropertyExist(nodeName) && model.isIgnoreUnknown()) {
|
||||
Log.debug("Ignore node: '" + nodeName + "' Does not exist...");
|
||||
return null;
|
||||
}
|
||||
typeClass = introspectionObject.getTypeOfSubNode(nodeName);
|
||||
listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName);
|
||||
}
|
||||
@ -106,6 +109,10 @@ public class BuilderIntrospection implements Builder {
|
||||
}
|
||||
String beanName = model.getBeanName(propertyName);
|
||||
if (beanName == null) {
|
||||
if (model.isIgnoreUnknown()) {
|
||||
Log.debug("Ignore node : '" + propertyName + "'");
|
||||
return;
|
||||
}
|
||||
throw new ExmlAttributeDoesNotExist("The node '" + propertyName + "' Does not exist...");
|
||||
}
|
||||
Class<?> typeClass = model.getTypeOfProperty(propertyName);
|
||||
@ -189,6 +196,7 @@ public class BuilderIntrospection implements Builder {
|
||||
|
||||
@Override
|
||||
public void newElementFinished(final Object parent, final String tmpName, final Object element) throws ExmlException {
|
||||
Log.debug("new element fionished : ==> " + tmpName);
|
||||
if (parent == null || element == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -8,10 +8,15 @@ import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
|
||||
public abstract class IntrospectionModel {
|
||||
protected static final Boolean DEFAULT_ATTRIBUTE = false;
|
||||
protected static final Boolean DEFAULT_IGNORE_UNBKNOWN = false;
|
||||
protected static final Boolean DEFAULT_DEFAULT_NULL_VALUE = false;
|
||||
protected static final Boolean DEFAULT_CASE_SENSITIVE = true;
|
||||
protected static final Boolean DEFAULT_MANAGED = true;
|
||||
protected static final Boolean DEFAULT_OPTIONAL = false;
|
||||
|
||||
protected boolean defaultNullValue = false;
|
||||
protected boolean ignoreUnknown = false;
|
||||
|
||||
protected final Class<?> classType;
|
||||
|
||||
public List<IntrospectionProperty> getNodes() {
|
||||
@ -78,8 +83,14 @@ public abstract class IntrospectionModel {
|
||||
public boolean isEnum() {
|
||||
return this.classType.isEnum();
|
||||
}
|
||||
public String getBeanName(String nodeName) {
|
||||
public String getBeanName(final String nodeName) {
|
||||
return nodeName;
|
||||
}
|
||||
protected boolean isIgnoreUnknown() {
|
||||
return this.ignoreUnknown;
|
||||
}
|
||||
protected boolean isDefaultNullValue() {
|
||||
return this.defaultNullValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
private final List<ConstructorModel> constructors = new ArrayList<>();
|
||||
private final List<IntrospectionProperty> elements = new ArrayList<>();
|
||||
|
||||
public String getBeanName(String nodeName) {
|
||||
@Override
|
||||
public String getBeanName(final String nodeName) {
|
||||
for (IntrospectionProperty elem : this.elements) {
|
||||
if (elem.isCompatible(nodeName)) {
|
||||
return elem.getBeanName();
|
||||
@ -483,6 +484,10 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
prop.setSetter(modifier);
|
||||
}
|
||||
}
|
||||
this.ignoreUnknown = ReflectTools.getIsIgnoreUnknown(classType, IntrospectionModel.DEFAULT_IGNORE_UNBKNOWN);
|
||||
|
||||
this.defaultNullValue = ReflectTools.getIsDefaultNullValue(classType, IntrospectionModel.DEFAULT_DEFAULT_NULL_VALUE);
|
||||
|
||||
// Set only at the end ==> no need before...
|
||||
final Boolean isDefaultAttribute = ReflectTools.getIsDefaultAttribute(classType, IntrospectionModel.DEFAULT_ATTRIBUTE);
|
||||
for (IntrospectionProperty prop : this.elements) {
|
||||
@ -540,6 +545,12 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
Log.warning(" optionnal: " + prop.isOptionnal());
|
||||
Log.warning(" constructor: " + prop.isCanBeSetByConstructor());
|
||||
Log.warning(" get/set: " + prop.canGetValue() + " / " + prop.canSetValue());
|
||||
Log.warning(" type: " + prop.getType().getCanonicalName());
|
||||
if (prop.getSubType() != null) {
|
||||
Log.warning(" sub-type: " + prop.getSubType().getCanonicalName());
|
||||
} else {
|
||||
Log.warning(" sub-type: null");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -629,25 +640,43 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
Object tmp = null;
|
||||
// STEP 1: try to create the object with provided parameter (if a constructor exist....)
|
||||
if (!this.constructors.isEmpty()) {
|
||||
Object[] inputs = null;
|
||||
ConstructorModel betterModel = null;
|
||||
int lastEmpty = Integer.MAX_VALUE;
|
||||
// try to find the constructor that fit with parameters ...
|
||||
for (ConstructorModel elem : this.constructors) {
|
||||
int offset = this.isSubClass?1:0;
|
||||
Object[] inputs = new Object[elem.values().length+offset];
|
||||
inputs[0] = null;
|
||||
Object[] inputsTmp = new Object[elem.values().length+offset];
|
||||
inputsTmp[0] = null;
|
||||
int empty = 0;
|
||||
for (int iii=0; iii<elem.values().length; iii++) {
|
||||
Object valueToInject = properties.get(elem.values()[iii]);
|
||||
if (valueToInject == null) {
|
||||
List<Object> tmppp = nodes.get(elem.values()[iii]);
|
||||
if (tmppp != null && tmppp.size() >=1) {
|
||||
if (tmppp != null) {
|
||||
if (List.class == findBeanNodeDescription(elem.values()[iii]).getType() ) {
|
||||
valueToInject = tmppp;
|
||||
} else if (tmppp.size() >=1) {
|
||||
valueToInject = tmppp.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (valueToInject == null) {
|
||||
inputs = null;
|
||||
break;
|
||||
empty++;
|
||||
inputsTmp[iii+offset] = null;
|
||||
continue;
|
||||
}
|
||||
inputs[iii+offset] = valueToInject;
|
||||
inputsTmp[iii+offset] = valueToInject;
|
||||
}
|
||||
if (lastEmpty > empty) {
|
||||
inputs = inputsTmp;
|
||||
betterModel = elem;
|
||||
lastEmpty = empty;
|
||||
}
|
||||
}
|
||||
if (betterModel != null) {
|
||||
if (isDefaultNullValue() || lastEmpty == 0) {
|
||||
ConstructorModel elem = betterModel;
|
||||
if (inputs != null) {
|
||||
// here we find our constructor...
|
||||
try {
|
||||
@ -689,7 +718,7 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
properties.remove(elem.values()[iii]);
|
||||
nodes.remove(elem.values()[iii]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -733,6 +762,29 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
protected IntrospectionProperty findBeanNodeDescription(final String propertyBeanName) throws ExmlBuilderException {
|
||||
for (final IntrospectionProperty prop : this.elements) {
|
||||
if (prop.isAttribute()) {
|
||||
continue;
|
||||
}
|
||||
if (prop.getBeanName().equals(propertyBeanName)) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected IntrospectionProperty findBeanPropertyDescription(final String propertyBeanName) throws ExmlBuilderException {
|
||||
for (final IntrospectionProperty prop : this.elements) {
|
||||
if (!prop.isAttribute()) {
|
||||
continue;
|
||||
}
|
||||
if (prop.getBeanName().equals(propertyBeanName)) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected IntrospectionProperty findNodeDescription(final String propertyName) throws ExmlBuilderException {
|
||||
for (final IntrospectionProperty prop : this.elements) {
|
||||
if (prop.isAttribute()) {
|
||||
@ -768,11 +820,11 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
//return data.stream().map(clazz::cast).toArray(new T[data.size()]);//java.lang.reflect.Array.newInstance((propMethode.getSubType(), tmpp.size()));
|
||||
}
|
||||
|
||||
private void setValue(final Object data, final String name, final Object value) throws ExmlBuilderException {
|
||||
Log.error(" Set value ='" + name + "' propertyValue='" + value + "' " + value.getClass().getCanonicalName());
|
||||
private void setValue(final Object data, final String beanName, final Object value) throws ExmlBuilderException {
|
||||
Log.error(" Set value ='" + beanName + "' propertyValue='" + value + "' " + value.getClass().getCanonicalName());
|
||||
{
|
||||
// by default use setter to set the property
|
||||
final IntrospectionProperty propMethode = findNodeDescription(name);
|
||||
final IntrospectionProperty propMethode = findBeanNodeDescription(beanName);
|
||||
if (propMethode != null && propMethode.canSetValue()) {
|
||||
Log.verbose(" ==> find '" + Arrays.toString(propMethode.getNames()) + " type=" + propMethode.getType() + " sub-type=" + propMethode.getSubType() );
|
||||
if (propMethode.getType().isAssignableFrom(value.getClass())) {
|
||||
@ -823,7 +875,7 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
}
|
||||
// try with direct field
|
||||
{
|
||||
final IntrospectionProperty propField = findPropertyDescription(name);
|
||||
final IntrospectionProperty propField = findBeanPropertyDescription(beanName);
|
||||
if (propField != null && propField.canSetValue()) {
|
||||
Log.verbose(" ==> find '" + Arrays.toString(propField.getNames()) + " type=" + propField.getType() + " sub-type=" + propField.getSubType() );
|
||||
if (propField.getType().isAssignableFrom(value.getClass())) {
|
||||
@ -889,49 +941,49 @@ public class IntrospectionModelComplex extends IntrospectionModel {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ExmlBuilderException("can not find the field '" + name + "'");
|
||||
throw new ExmlBuilderException("can not find the field '" + beanName + "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect a subNode, and ask the type of the node at the parent Class
|
||||
* @param nodeName Name of the node
|
||||
* @param nodeBeanName Name of the node (bean name access ==> not the XML name)
|
||||
* @return Class of the node to create
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getTypeOfSubNode(final String nodeName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeName + "'");
|
||||
final IntrospectionProperty propMethode = findNodeDescription(nodeName);
|
||||
public Class<?> getTypeOfSubNode(final String nodeBeanName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeBeanName + "'");
|
||||
final IntrospectionProperty propMethode = findBeanNodeDescription(nodeBeanName);
|
||||
if (propMethode != null && propMethode.canSetValue()) {
|
||||
Log.error(" ==> find '" + propMethode.getNames());
|
||||
return propMethode.getType();
|
||||
}
|
||||
throw new ExmlBuilderException("can not find the field '" + nodeName + "' availlable: " + getNodeAvaillable());
|
||||
throw new ExmlBuilderException("can not find the field '" + nodeBeanName + "' availlable: " + getNodeAvaillable());
|
||||
}
|
||||
@Override
|
||||
public Class<?> getTypeOfSubNodeList(final String nodeName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeName + "'");
|
||||
final IntrospectionProperty propMethode = findNodeDescription(nodeName);
|
||||
public Class<?> getTypeOfSubNodeList(final String nodeBeanName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeBeanName + "'");
|
||||
final IntrospectionProperty propMethode = findBeanNodeDescription(nodeBeanName);
|
||||
if (propMethode != null && propMethode.canSetValue()) {
|
||||
Log.error(" ==> find '" + propMethode.getNames());
|
||||
return propMethode.getSubType();
|
||||
}
|
||||
throw new ExmlBuilderException("can not find the field '" + nodeName + "' availlable: " + getNodeAvaillable());
|
||||
throw new ExmlBuilderException("can not find the field '" + nodeBeanName + "' availlable: " + getNodeAvaillable());
|
||||
}
|
||||
@Override
|
||||
public String getTreeNameOfSubNode(final String nodeName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeName + "'");
|
||||
final IntrospectionProperty propMethode = findNodeDescription(nodeName);
|
||||
public String getTreeNameOfSubNode(final String nodeBeanName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeBeanName + "'");
|
||||
final IntrospectionProperty propMethode = findBeanNodeDescription(nodeBeanName);
|
||||
if (propMethode != null && propMethode.canSetValue()) {
|
||||
Log.error(" ==> find '" + propMethode.getNames());
|
||||
return propMethode.getListName();
|
||||
}
|
||||
throw new ExmlBuilderException("can not find the field '" + nodeName + "'");
|
||||
throw new ExmlBuilderException("can not find the field '" + nodeBeanName + "'");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<?> getTypeOfProperty(final String nodeName) throws ExmlBuilderException {
|
||||
Log.error(" nodeType='" + nodeName + "'");
|
||||
Log.error("nodeType='" + nodeName + "'");
|
||||
final IntrospectionProperty propField = findPropertyDescription(nodeName);
|
||||
if (propField != null && propField.canSetValue()) {
|
||||
Log.error(" ==> find '" + propField.getNames());
|
||||
|
@ -30,48 +30,57 @@ public class IntrospectionObject {
|
||||
}
|
||||
|
||||
public void putProperty(final String propertyName, final Object propertyValue) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(propertyName);
|
||||
final String beanName = this.modelInterface.getBeanName(propertyName);
|
||||
if (this.properties.containsKey(beanName)) {
|
||||
throw new ExmlBuilderException("Property have multiple values ==> impossible case; A Node must contain only 1 attibutes");
|
||||
}
|
||||
this.properties.put(beanName, propertyValue);
|
||||
}
|
||||
|
||||
public boolean isSubNodeOrPropertyExist(final String nodeName) {
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect a subNode, and ask the type of the node at the parent Class
|
||||
* @param nodeName Name of the node
|
||||
* @return Class of the node to create
|
||||
*/
|
||||
public Class<?> getTypeOfSubNode(final String nodeName) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(nodeName);
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
|
||||
}
|
||||
return this.modelInterface.getTypeOfSubNode(beanName);
|
||||
}
|
||||
public Class<?> getTypeOfSubNodeSubType(final String nodeName) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(nodeName);
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
|
||||
}
|
||||
return this.modelInterface.getTypeOfSubNodeList(beanName);
|
||||
}
|
||||
public String getTreeNameOfSubNode(final String nodeName) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(nodeName);
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
|
||||
}
|
||||
return this.modelInterface.getTreeNameOfSubNode(beanName);
|
||||
}
|
||||
|
||||
public Class<?> getTypeOfProperty(final String nodeName) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(nodeName);
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
|
||||
}
|
||||
return this.modelInterface.getTypeOfProperty(beanName);
|
||||
}
|
||||
public Class<?> getTypeOfSubProperty(final String nodeName) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(nodeName);
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
|
||||
}
|
||||
@ -87,7 +96,11 @@ public class IntrospectionObject {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addObject(final String nodeName, final Object value) throws ExmlException {
|
||||
final String beanName = modelInterface.getBeanName(nodeName);
|
||||
if (value == null) {
|
||||
// specific case when a List is empty <links></links> but define for a specific list ==> need no action
|
||||
return;
|
||||
}
|
||||
final String beanName = this.modelInterface.getBeanName(nodeName);
|
||||
if (beanName == null) {
|
||||
throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.atriasoft.exml.builder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.atriasoft.eStringSerialize.StringSerializer;
|
||||
@ -111,17 +112,22 @@ public final class IntrospectionProperty {
|
||||
* @return true if the element is compatible, false otherwise
|
||||
*/
|
||||
public boolean isCompatible(final String name) {
|
||||
Log.warning("Check compatible : '" + name + "' in " + Arrays.toString(this.names));
|
||||
if (this.caseSensitive) {
|
||||
for (final String elem : this.names) {
|
||||
if (elem.contentEquals(name)) {
|
||||
Log.warning(" - '" + elem + "' ==> true");
|
||||
return true;
|
||||
}
|
||||
Log.warning(" - '" + elem + "' == false");
|
||||
}
|
||||
} else {
|
||||
for (final String elem : this.names) {
|
||||
if (elem.equalsIgnoreCase(name)) {
|
||||
Log.warning(" - '" + elem + "' ==> true");
|
||||
return true;
|
||||
}
|
||||
Log.warning(" - '" + elem + "' == false");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -9,7 +9,7 @@ import io.scenarium.logger.LogLevel;
|
||||
import io.scenarium.logger.Logger;
|
||||
|
||||
public class Log {
|
||||
private static final boolean FORCE = true;
|
||||
private static final boolean FORCE = false;
|
||||
private static final String LIB_NAME = "exml";
|
||||
private static final String LIB_NAME_DRAW = Logger.getDrawableName(Log.LIB_NAME);
|
||||
private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.CRITICAL);
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.atriasoft.exml.parser;
|
||||
|
||||
import org.atriasoft.exml.builder.Builder;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.exception.ExmlException;
|
||||
import org.atriasoft.exml.exception.ExmlParserError;
|
||||
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||
@ -487,7 +486,6 @@ public class ParseXml {
|
||||
if (data.charAt(jjj) == '>') {
|
||||
pos.value = jjj;
|
||||
filePos.add(tmpPos);
|
||||
Log.todo("End of node: '" + nameElement + "' ==> need add build result to parent and create object ...");
|
||||
this.builder.endElement(parent);
|
||||
return true;
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import org.atriasoft.exml.annotation.XmlCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultAttibute;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultManaged;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultNullValue;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultOptional;
|
||||
import org.atriasoft.exml.annotation.XmlIgnoreUnknow;
|
||||
import org.atriasoft.exml.annotation.XmlList;
|
||||
import org.atriasoft.exml.annotation.XmlManaged;
|
||||
import org.atriasoft.exml.annotation.XmlName;
|
||||
@ -82,7 +84,7 @@ public class ReflectTools {
|
||||
return new Class<?>[] {type, subType};
|
||||
}
|
||||
|
||||
public static Class<?>[] getTypeParameterfunction(Constructor<?> elem, int paramId) throws ClassNotFoundException {
|
||||
public static Class<?>[] getTypeParameterfunction(final Constructor<?> elem, final int paramId) throws ClassNotFoundException {
|
||||
Class<?> type = null;
|
||||
Class<?> subType = null;
|
||||
|
||||
@ -90,12 +92,13 @@ public class ReflectTools {
|
||||
if (List.class.isAssignableFrom(type)) {
|
||||
Class<?> internalModelClass = null;
|
||||
Type[] empppe = elem.getGenericParameterTypes();
|
||||
if (empppe.length > 0) {
|
||||
if (empppe[0] instanceof ParameterizedType plopppppp) {
|
||||
if (empppe.length > paramId) {
|
||||
if (empppe[paramId] instanceof ParameterizedType plopppppp) {
|
||||
Type[] realType = plopppppp.getActualTypeArguments();
|
||||
if (realType.length > paramId) {
|
||||
Log.warning(" -->> " + realType[paramId]);
|
||||
internalModelClass = Class.forName(realType[paramId].getTypeName());
|
||||
//Log.info("ppplllppp: " + realType.length);
|
||||
if (realType.length > 0) {
|
||||
Log.warning(" -->> " + realType[0]);
|
||||
internalModelClass = Class.forName(realType[0].getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,6 +160,26 @@ public class ReflectTools {
|
||||
}
|
||||
return ((XmlDefaultAttibute) annotation[0]).value();
|
||||
}
|
||||
public static Boolean getIsIgnoreUnknown(final Class<?> classType, final Boolean defaultValue) throws ExmlBuilderException {
|
||||
final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlIgnoreUnknow.class);
|
||||
if (annotation.length == 0) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new ExmlBuilderException("Must not have more than 1 element @XmlIgnoreUnknow on " + classType.getClass().getCanonicalName());
|
||||
}
|
||||
return ((XmlIgnoreUnknow) annotation[0]).value();
|
||||
}
|
||||
public static Boolean getIsDefaultNullValue(final Class<?> classType, final Boolean defaultValue) throws ExmlBuilderException {
|
||||
final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultNullValue.class);
|
||||
if (annotation.length == 0) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new ExmlBuilderException("Must not have more than 1 element @XmlDefaultNullValue on " + classType.getClass().getCanonicalName());
|
||||
}
|
||||
return ((XmlDefaultNullValue) annotation[0]).value();
|
||||
}
|
||||
|
||||
public static Boolean getIsDefaultManaged(final Class<?> classType, final Boolean defaultValue) throws ExmlBuilderException {
|
||||
final Annotation[] annotation = classType.getDeclaredAnnotationsByType(XmlDefaultManaged.class);
|
||||
|
@ -6,8 +6,9 @@
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.exception.ExmlException;
|
||||
import org.atriasoft.exml.model.XmlNode;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
class ExmlLocal {
|
||||
@ -26,7 +27,7 @@ class ExmlLocal {
|
||||
Assertions.fail("Must have detected an error");
|
||||
return;
|
||||
}
|
||||
} catch (final ExmlBuilderException e) {
|
||||
} catch (final ExmlException e) {
|
||||
if (errorPos == 1) {
|
||||
return;
|
||||
}
|
||||
|
@ -12,9 +12,8 @@ import org.atriasoft.exml.annotation.XmlDefaultAttibute;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlName;
|
||||
import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
|
||||
import org.atriasoft.exml.exception.ExmlException;
|
||||
import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
|
||||
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -7,10 +7,6 @@ package test.atriasoft.exml;
|
||||
|
||||
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.annotation.XmlManaged;
|
||||
import org.atriasoft.exml.annotation.XmlCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultAttibute;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultManaged;
|
||||
import org.atriasoft.exml.annotation.XmlManaged;
|
||||
import org.atriasoft.exml.annotation.XmlName;
|
||||
|
@ -9,7 +9,6 @@ package test.atriasoft.exml;
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.annotation.XmlAttribute;
|
||||
import org.atriasoft.exml.annotation.XmlCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultAttibute;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlName;
|
||||
|
||||
@ -579,6 +578,55 @@ public class ExmlTestIntrospectionDecoratorNames {
|
||||
Assertions.assertEquals(-98885, root.getPFinalValueS());
|
||||
Assertions.assertEquals(-8754, root.getPFinalValueT());
|
||||
}
|
||||
public class ChangingNames {
|
||||
private String value1RataPlouf;
|
||||
@XmlName("value2")
|
||||
public String value2Ballet;
|
||||
private String value3RataPlouf;
|
||||
@XmlAttribute
|
||||
@XmlName("value4")
|
||||
public String value4Ballet;
|
||||
|
||||
@XmlName("value1")
|
||||
public String getValue1RataPlouf() {
|
||||
return this.value1RataPlouf;
|
||||
}
|
||||
|
||||
public void setValue1RataPlouf(final String value1RataPlouf) {
|
||||
this.value1RataPlouf = value1RataPlouf;
|
||||
}
|
||||
@XmlAttribute
|
||||
@XmlName("value3")
|
||||
public String getValue3RataPlouf() {
|
||||
return this.value3RataPlouf;
|
||||
}
|
||||
|
||||
public void setValue3RataPlouf(final String value3RataPlouf) {
|
||||
this.value3RataPlouf = value3RataPlouf;
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testChangingNames() {
|
||||
ChangingNames elem = new ChangingNames();
|
||||
elem.value2Ballet = "55";
|
||||
elem.value4Ballet = "78";
|
||||
elem.setValue1RataPlouf("51");
|
||||
elem.setValue3RataPlouf("24");
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Assertions.assertDoesNotThrow(() -> Exml.generate(elem, ExmlTestIntrospectionObject.NODE_NAME, builder));
|
||||
String dataTest = builder.toString();
|
||||
Log.warning("data generated: " + builder.toString());
|
||||
Assertions.assertEquals("<elem value3=\"24\" value4=\"78\">\n"
|
||||
+ " <value1>51</value1>\n"
|
||||
+ " <value2>55</value2>\n"
|
||||
+ "</elem>", dataTest);
|
||||
|
||||
final ChangingNames root = Assertions.assertDoesNotThrow(() -> Exml.parseOne(dataTest, ChangingNames.class, ExmlTestIntrospectionObject.NODE_NAME));
|
||||
Assertions.assertEquals("55", root.value2Ballet);
|
||||
Assertions.assertEquals("78", root.value4Ballet);
|
||||
Assertions.assertEquals("51", root.getValue1RataPlouf());
|
||||
Assertions.assertEquals("24", root.getValue3RataPlouf());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,10 @@ package test.atriasoft.exml;
|
||||
|
||||
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.annotation.XmlAttribute;
|
||||
import org.atriasoft.exml.annotation.XmlCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultAttibute;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultCaseSensitive;
|
||||
import org.atriasoft.exml.annotation.XmlDefaultOptional;
|
||||
import org.atriasoft.exml.annotation.XmlName;
|
||||
import org.atriasoft.exml.annotation.XmlOptional;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -6,7 +6,7 @@
|
||||
package test.atriasoft.exml;
|
||||
|
||||
import org.atriasoft.exml.Exml;
|
||||
import org.atriasoft.exml.exception.ExmlBuilderException;
|
||||
import org.atriasoft.exml.exception.ExmlException;
|
||||
import org.atriasoft.exml.exception.ExmlParserErrorMulti;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
@ -24,7 +24,7 @@ public class ExmlTestIntrospectionGenerate {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() throws ExmlParserErrorMulti, ExmlBuilderException {
|
||||
public void test1() throws ExmlParserErrorMulti, ExmlException {
|
||||
ClassPublicMemberOnly elem = new ClassPublicMemberOnly();
|
||||
elem.memberArrayBoolean = new boolean[] {false, true};
|
||||
elem.memberArrayBooleanClass = new Boolean[] {false, true, true};
|
||||
@ -54,7 +54,7 @@ public class ExmlTestIntrospectionGenerate {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() throws ExmlParserErrorMulti, ExmlBuilderException {
|
||||
public void test2() throws ExmlParserErrorMulti, ExmlException {
|
||||
ClassPublicMethodOnly elem = new ClassPublicMethodOnly();
|
||||
elem.setMemberArrayBoolean ( new boolean[] {false, true});
|
||||
elem.setMemberArrayBooleanClass ( new Boolean[] {false, true, true});
|
||||
@ -85,7 +85,7 @@ public class ExmlTestIntrospectionGenerate {
|
||||
|
||||
|
||||
@Test
|
||||
public void test3() throws ExmlParserErrorMulti, ExmlBuilderException {
|
||||
public void test3() throws ExmlParserErrorMulti, ExmlException {
|
||||
ClassPublicMethodeNode elem = new ClassPublicMethodeNode();
|
||||
elem.setMemberArrayBoolean ( new boolean[] {false, true});
|
||||
elem.setMemberArrayBooleanClass ( new Boolean[] {false, true, true});
|
||||
|
Loading…
x
Reference in New Issue
Block a user