exml/src/org/atriasoft/exml/builder/IntrospectionProperty.java

207 lines
6.1 KiB
Java

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