Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.ioc.commons.utils.XMLUtil Maven / Gradle / Ivy
package org.ioc.commons.utils;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Class for parsing a XML to a bean and vice versa.
*
* Instructions for using xml2bean:
*
* Create a bean having attributes with the same name of the tags and generate
* getters & setters of it.
*
* An XML like:
*
*
* {@code
*
*
* FOO1
* bar1
* baz1
*
*
* FOO2
* bar2
* baz2
*
*
* }
*
*
* will require two beans like this:
*
*
* {@code
* public class Workareas {
* private List workareas = new ArrayList();
*
* public List getWorkareas() {
* return workareas;
* }
*
* public void setWorkareas(List workareas) {
* this.workareas = workareas;
* }
* }
*
* public class Workarea {
* private WorkareaType type;
* private String id;
* private String name;
*
* // Getters & Setters of attributes
* }
*
* public enum WorkareaType {
* FOO1, FOO2;
* }
* }
*
*
* @author Jesús Lunar Pérez
*/
public class XMLUtil {
/**
* Logger for this class
*/
private static final FormatterLogger logger = FormatterLogger.getLogger(XMLUtil.class);
public static class XMLUtilException extends Exception {
/**
* Serial number
*/
private static final long serialVersionUID = 5118145977808353316L;
public XMLUtilException(String message) {
super(message);
}
public XMLUtilException(String message, Throwable cause) {
super(message, cause);
}
}
private XMLUtil() {
// Static use only
}
private static String dateTimeFormat = "dd/MM/yyyy HH:mm:ss";
private static String dateFormat = "dd/MM/yyyy";
private static NumberFormat numberFormat = null;
public static interface XMLNewBeanFactory {
public Object getNewInstance(String nombreTag, String defaultPackageName);
}
public static interface XMLProcessingVisitor {
String visit(String nodeText, Class> parameterType);
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public static @interface XMLUtilTagName {
String value();
}
/**
* Used to mark bean fields which we want to convert them into XML
* attributes instead of child nodes.
*
* ONLY valid for primtive types.
*
* @author Jesús Lunar Pérez
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public static @interface Attribute {
}
public static void xml2Bean(Element tag, Object bean, boolean log) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException, XMLUtilException,
ClassNotFoundException, SecurityException, NoSuchFieldException {
xml2Bean(tag, bean, log, (XMLProcessingVisitor) null);
}
public static void xml2Bean(Element tag, Object bean, boolean log,
XMLProcessingVisitor xmlCalcOperationOnProcessingVisitor) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException,
SecurityException, NoSuchFieldException, XMLUtilException {
xml2Bean(tag, bean, log, (XMLNewBeanFactory) null, xmlCalcOperationOnProcessingVisitor);
}
public static void xml2Bean(Element tag, Object bean, boolean log, XMLNewBeanFactory newBeanFactory)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, SecurityException, NoSuchFieldException {
xml2Bean(tag, bean, log, newBeanFactory, null);
}
public static void xml2Bean(Element tag, Object bean, boolean log, XMLNewBeanFactory newBeanFactory,
XMLProcessingVisitor xmlCalcOperationOnProcessingVisitor) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException, XMLUtilException,
ClassNotFoundException, SecurityException, NoSuchFieldException {
StringBuffer logb = new StringBuffer();
xml2Bean(tag, bean, log, logb, newBeanFactory, xmlCalcOperationOnProcessingVisitor);
if (log) {
logger.info(logb.toString());
}
}
public static void xml2Bean(Element tag, Object bean, int level, Package parentPackage, boolean log)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, SecurityException, NoSuchFieldException {
xml2Bean(tag, bean, 1, parentPackage, log, null);
}
public static void xml2Bean(Element tag, Object bean, int level, Package parentPackage, boolean log,
XMLNewBeanFactory newBeanFactory) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, InstantiationException, XMLUtilException, ClassNotFoundException,
SecurityException, NoSuchFieldException {
StringBuffer logb = new StringBuffer();
xml2Bean(tag, bean, level, parentPackage, log, logb, newBeanFactory, null);
if (log) {
logger.info(logb.toString());
}
}
protected static void xml2Bean(Element tag, Object bean, boolean log, StringBuffer logb,
XMLNewBeanFactory newBeanFactory) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, InstantiationException, XMLUtilException, ClassNotFoundException,
SecurityException, NoSuchFieldException {
xml2Bean(tag, bean, log, logb, newBeanFactory, (XMLProcessingVisitor) null);
}
protected static void xml2Bean(Element tag, Object bean, boolean log, StringBuffer logb,
XMLNewBeanFactory newBeanFactory, XMLProcessingVisitor xmlCalcOperationOnProcessingVisitor)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, SecurityException, NoSuchFieldException {
xml2Bean(tag, bean, 1, bean.getClass().getPackage(), log, logb, newBeanFactory,
xmlCalcOperationOnProcessingVisitor);
}
@SuppressWarnings("unchecked")
protected static void xml2Bean(Element tag, Object bean, int level, Package parentPackage, boolean log,
StringBuffer logb, XMLNewBeanFactory newBeanFactory, XMLProcessingVisitor processingVisitor)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, SecurityException, NoSuchFieldException {
StringBuffer tabs = new StringBuffer();
for (int n = 0; n < level; n++) {
tabs.append("\t");
}
boolean isList = bean instanceof List>;
NodeList tagChildList = tag.getChildNodes();
if (log) {
logb.append(
tabs + "<" + tag.getTagName() + "> "
+ (isList ? "(list)" : "(bean) children=" + tagChildList.getLength())).append('\n');
}
/**
* Rellenamos los atributos
*/
NamedNodeMap attributes = tag.getAttributes();
setAttributes(bean, attributes, level, log, logb, processingVisitor);
if (!isList) {
/**
* Rellenamos los tags hijo
*/
setTagChildren(bean, tagChildList, level, parentPackage, log, logb, newBeanFactory, processingVisitor);
} else {
List lista = (List) bean;
int length = tagChildList.getLength();
if (length > 0) {
for (int i = 0; i < length; i++) {
Node nodoHijo = tagChildList.item(i);
if (nodoHijo instanceof Element) {
Element tagHijo = (Element) nodoHijo;
if (parentPackage == null) {
String txt = tagHijo.getTextContent();
lista.add(txt);
if (log) {
logb.append(tabs + "\t" + txt).append('\n');
}
} else {
String nombreTag = tagHijo.getTagName();
Class> superClass = bean.getClass();
Type type = superClass.getGenericSuperclass();
Type[] typeArguments = null;
while (typeArguments == null && (superClass = superClass.getSuperclass()) != null) {
if ((type instanceof ParameterizedType)) {
typeArguments = ((ParameterizedType) type).getActualTypeArguments();
}
}
String packageName = null;
if (typeArguments != null) {
/**
* In a list we only have a unique parameter
* type
*/
Type typeArgument = typeArguments[0];
if (typeArgument instanceof Class>) {
packageName = ((Class>) typeArgument).getPackage().getName();
}
}
if (packageName == null) {
packageName = parentPackage.getName();
}
String className = packageName + "." + capitalize(nombreTag);
Object newInstance = getInstance(nombreTag, className, packageName, newBeanFactory);
xml2Bean(tagHijo, newInstance, log, logb, newBeanFactory, processingVisitor);
lista.add(newInstance);
}
}
}
} else {
String tagName = tag.getTagName();
throw new XMLUtilException(String.format(
"The tag <%s> is related to a List thus it must necessarily contain children elements.",
tagName));
}
}
}
protected static Object getInstance(String tagName, String className, String defaultPackageName,
XMLNewBeanFactory factory) throws ClassNotFoundException, IllegalAccessException, XMLUtilException {
Object newInstance = null;
if (factory != null && (newInstance = factory.getNewInstance(tagName, defaultPackageName)) != null) {
return newInstance;
}
Class> childClass = Class.forName(className);
try {
newInstance = childClass.newInstance();
return newInstance;
} catch (InstantiationException e) {
throw new XMLUtilException(
String.format(
"Unable to get a new instance for class/interface %s. Initialize bean attributes by default or use the parameter %s at the call.",
childClass, XMLNewBeanFactory.class.getSimpleName()), e);
}
}
private static String capitalize(String string) {
StringBuffer sb = new StringBuffer(string);
if (string.length() != 0) {
char ch = sb.charAt(0);
if (ch >= 97 && ch <= 122) {
ch -= 32;
}
sb.setCharAt(0, ch);
}
return sb.toString();
}
protected static void setAttributes(Object bean, NamedNodeMap attributes, int nivel, boolean log,
StringBuffer logb, XMLProcessingVisitor processingVisitor) throws XMLUtilException, IllegalAccessException,
InvocationTargetException {
for (int i = 0; i < attributes.getLength(); i++) {
Node attribute = attributes.item(i);
String property = attribute.getNodeName();
String value = attribute.getNodeValue();
Method[] methods = bean.getClass().getMethods();
/**
* Setting the attribute
*/
for (Method metodo : methods) {
String methodName = metodo.getName();
boolean esSetterPropiedad = methodName.equalsIgnoreCase("set" + property);
boolean tieneUnArgumento = (metodo.getParameterTypes().length == 1);
if (!esSetterPropiedad || !tieneUnArgumento) {
continue;
}
Class> parameterType = metodo.getParameterTypes()[0];
Object valorSetter = null;
if (processingVisitor != null) {
value = processingVisitor.visit(value, parameterType);
}
if (parameterType.equals(Double.class) || parameterType.equals(double.class)) {
try {
valorSetter = (numberFormat != null) ? numberFormat.parse(value) : Double.valueOf(value);
} catch (NumberFormatException | ParseException e) {
throw new XMLUtilException(Format.substitute(
"Cannot parse value '{0}' of type '{1}' using number formatted given", value,
parameterType), e);
}
} else if (parameterType.equals(Float.class) || parameterType.equals(float.class)) {
try {
valorSetter = (numberFormat != null) ? numberFormat.parse(value) : Float.valueOf(value);
} catch (NumberFormatException | ParseException e) {
throw new XMLUtilException(Format.substitute(
"Cannot parse value '{0}' of type '{1}' using number formatted given", value,
parameterType), e);
}
} else if (parameterType.equals(Boolean.class) || parameterType.equals(boolean.class)) {
valorSetter = Boolean.valueOf(value);
} else if (parameterType.equals(Integer.class) || parameterType.equals(int.class)) {
valorSetter = Integer.valueOf(value);
} else if (parameterType.equals(String.class)) {
valorSetter = value;
} else {
throw new XMLUtilException("An attribute cannot be loaded on method '" + methodName
+ "' because of it has an unknow type. Type: " + parameterType.getSimpleName());
}
StringBuffer tabs = new StringBuffer();
for (int n = 0; n < nivel; n++) {
tabs.append("\t");
}
if (log) {
logb.append(tabs + " " + property + "=" + valorSetter).append('\n');
}
metodo.invoke(bean, valorSetter);
break;
}
}
}
protected static void setTagChildren(Object bean, NodeList tagsHijo, int nivel, Package paquetePadre, boolean log,
StringBuffer logb, XMLNewBeanFactory newBeanFactory, XMLProcessingVisitor processingVisitor)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, SecurityException, NoSuchFieldException {
StringBuffer tabs = new StringBuffer();
for (int n = 0; n < nivel; n++) {
tabs.append("\t");
}
for (int i = 0; i < tagsHijo.getLength(); i++) {
Node nodo = tagsHijo.item(i);
if (nodo instanceof Element) {
Element tagHijo = (Element) nodo;
String propiedad = tagHijo.getNodeName();
String valorTextoTag = tagHijo.getTextContent();
Method[] metodos = bean.getClass().getMethods();
/**
* Setting the tag text
*/
boolean setterFound = false;
for (Method metodo : metodos) {
boolean esSetterPropiedad = metodo.getName().equalsIgnoreCase("set" + propiedad);
boolean tieneUnArgumento = (metodo.getParameterTypes().length == 1);
if (!esSetterPropiedad || !tieneUnArgumento) {
continue;
}
setterFound = true;
Class> parameterType = metodo.getParameterTypes()[0];
Object valorSetter = null;
if (processingVisitor != null) {
valorTextoTag = processingVisitor.visit(valorTextoTag, parameterType);
}
if (parameterType.equals(Double.class) || parameterType.equals(double.class)) {
try {
valorSetter = (numberFormat != null) ? numberFormat.parse(valorTextoTag) : Double
.valueOf(valorTextoTag);
} catch (ParseException e) {
throw new XMLUtilException(Format.substitute(
"Cannot parse value '{0}' of type '{1}' using number formatted given",
valorTextoTag, parameterType), e);
}
if (log) {
logb.append(tabs + " Double " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Boolean.class) || parameterType.equals(boolean.class)) {
valorSetter = Boolean.valueOf(valorTextoTag);
if (log) {
logb.append(tabs + " Boolean " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Float.class) || parameterType.equals(float.class)) {
try {
valorSetter = (numberFormat != null) ? numberFormat.parse(valorTextoTag) : Float
.valueOf(valorTextoTag);
} catch (ParseException e) {
throw new XMLUtilException(Format.substitute(
"Cannot parse value '{0}' of type '{1}' using number formatted given",
valorTextoTag, parameterType), e);
}
if (log) {
logb.append(tabs + " Float " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Long.class) || parameterType.equals(long.class)) {
valorSetter = Long.valueOf(valorTextoTag);
if (log) {
logb.append(tabs + " Long " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Integer.class) || parameterType.equals(int.class)) {
valorSetter = Integer.valueOf(valorTextoTag);
if (log) {
logb.append(tabs + " Integer " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Short.class) || parameterType.equals(short.class)) {
valorSetter = Short.valueOf(valorTextoTag);
if (log) {
logb.append(tabs + " Short " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Character.class) || parameterType.equals(char.class)) {
valorSetter = Character.valueOf(valorTextoTag.charAt(0));
if (log) {
logb.append(tabs + " Character " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(Byte.class) || parameterType.equals(byte.class)) {
valorSetter = Byte.valueOf(valorTextoTag);
if (log) {
logb.append(tabs + " Byte " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.equals(String.class)) {
valorSetter = valorTextoTag;
if (log) {
logb.append(tabs + " String " + propiedad + "=" + valorSetter).append('\n');
}
} else if (parameterType.isAssignableFrom(List.class)) {
if (log) {
logb.append(tabs + " List " + propiedad + "= ...").append('\n');
}
Type tipoGenerico = metodo.getGenericParameterTypes()[0];
if (tipoGenerico instanceof ParameterizedType
&& ((ParameterizedType) tipoGenerico).getActualTypeArguments()[0].equals(String.class)) {
valorSetter = new ArrayList();
xml2Bean(tagHijo, valorSetter, nivel + 1, null, log, logb, newBeanFactory,
processingVisitor);
} else {
if (tipoGenerico instanceof ParameterizedType) {
Type typeArg = ((ParameterizedType) tipoGenerico).getActualTypeArguments()[0];
Class> classArg = (Class>) typeArg;
paquetePadre = classArg.getPackage();
}
valorSetter = new ArrayList();
xml2Bean(tagHijo, valorSetter, nivel + 1, paquetePadre, log, logb, newBeanFactory,
processingVisitor);
}
} else if (Enum.class.isAssignableFrom(parameterType)) {
Field f = parameterType.getDeclaredField(valorTextoTag);
valorSetter = f.get(null);
if (log) {
logb.append(tabs + " Enum " + propiedad + "=" + valorSetter).append('\n');
}
} else {
if (log) {
logb.append(tabs + " " + parameterType + " " + propiedad).append('\n');
}
valorSetter = parameterType.newInstance();
xml2Bean(tagHijo, valorSetter, nivel + 1, paquetePadre, log, logb, newBeanFactory,
processingVisitor);
}
metodo.invoke(bean, valorSetter);
}
if (!setterFound) {
if (log) {
logb.append(tabs + " Unable to find a setter for property '" + propiedad
+ "' inside the class " + bean.getClass());
}
}
}
}
}
public static boolean indentXml(StringBuffer xmlStr) {
logger.debug("indentXml(StringBuffer) - start"); //$NON-NLS-1$
try {
DocumentBuilder newDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlStr.toString()));
Document root = newDocumentBuilder.parse(is);
StringWriter stringWriter = indentXml(root);
if (stringWriter == null) {
return false;
}
xmlStr.setLength(0);
xmlStr.append(stringWriter.toString());
logger.debug("indentXml(StringBuffer) - end"); //$NON-NLS-1$
return true;
} catch (SAXException e) {
logger.warn(e, "Error trying to indent XML. Let's continue...");
} catch (IOException e) {
logger.warn(e, "Error trying to indent XML. Let's continue...");
} catch (ParserConfigurationException e) {
logger.warn(e, "Error trying to indent XML. Let's continue...");
}
logger.debug("indentXml(StringBuffer) - end"); //$NON-NLS-1$
return false;
}
public static StringWriter indentXml(Document root) {
try {
// Write file
DOMSource domsource = new DOMSource(root);
StringWriter stringWriter = new StringWriter(1024);
StreamResult output = new StreamResult(stringWriter); // new
// Set up
TransformerFactory transfabrik = TransformerFactory.newInstance();
Transformer sTransformer;
sTransformer = transfabrik.newTransformer();
sTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
sTransformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
sTransformer.transform(domsource, output);
return stringWriter;
} catch (TransformerConfigurationException e) {
logger.warn(e, "Error trying to indent XML. Let's continue...");
return null;
} catch (TransformerException e) {
logger.warn(e, "Error trying to indent XML. Let's continue...");
return null;
}
}
public static Document bean2xml(Object bean) throws IllegalArgumentException, UnsupportedEncodingException,
IllegalAccessException, InvocationTargetException, InstantiationException, XMLUtilException,
ClassNotFoundException, ParserConfigurationException, TransformerException {
return bean2xml(bean, false);
}
public static Document bean2xml(Object bean, boolean dateWithTime) throws IllegalArgumentException,
UnsupportedEncodingException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, ParserConfigurationException, TransformerException {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
bean2xml(bean, null, doc, dateWithTime, 0, new HashMap());
return doc;
}
public static byte[] bean2xml(boolean indent, Object bean, boolean salidaEnUTF8) throws IllegalArgumentException,
UnsupportedEncodingException, IllegalAccessException, InvocationTargetException, InstantiationException,
XMLUtilException, ClassNotFoundException, ParserConfigurationException, TransformerException {
return bean2xml(indent, bean, salidaEnUTF8, false);
}
public static byte[] bean2xml(boolean indent, Object bean, boolean salidaEnUTF8, boolean dateWithTime)
throws IllegalArgumentException, UnsupportedEncodingException, IllegalAccessException,
InvocationTargetException, InstantiationException, XMLUtilException, ClassNotFoundException,
ParserConfigurationException, TransformerException {
Document doc = bean2xml(bean, dateWithTime);
byte[] xmlString = DOM2String(doc, salidaEnUTF8, indent);
return xmlString;
}
protected static Element bean2xml(Object bean, Element parent, Document doc, boolean dateWithTime, int deep,
Map processedObjects) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, InstantiationException, XMLUtilException, ClassNotFoundException,
ParserConfigurationException {
if (processedObjects != null) {
/**
* Si se ha mostrado a un nivel más profundo, se muestra otra vez.
* Si no, se omite.
*/
if (processedObjects.containsKey(bean)) {
int objectDeep = processedObjects.get(bean);
if (deep > objectDeep) {
return null;
}
}
processedObjects.put(bean, deep);
}
Class> clazz = bean.getClass();
String rootName = null;
String clazzName = clazz.getName();
XMLUtilTagName tagNameAnnot = clazz.getAnnotation(XMLUtilTagName.class);
if (tagNameAnnot != null) {
rootName = tagNameAnnot.value();
} else {
rootName = getSimpleClassName(clazzName);
}
try {
Element root = doc.createElement(rootName);
if (parent != null) {
parent.appendChild(root);
} else {
doc.appendChild(root);
}
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String methodName = method.getName();
if ((methodName.startsWith("get") || methodName.startsWith("is"))
&& method.getParameterTypes().length == 0 && !methodName.equals("getClass")) {
Object result = method.invoke(bean, (Object[]) null);
String propertyName = methodName.startsWith("get") ? Format.decapitalize(methodName.replaceFirst(
"get", "")) : Format.decapitalize(methodName.replaceFirst("is", ""));
Element propertyTag = doc.createElement(propertyName);
boolean likeAttribute = false;
if (result != null) {
if (result instanceof List>) {
List> lstResult = (List>) result;
for (Iterator> it = lstResult.iterator(); it.hasNext();) {
Object hijo = it.next();
if (hijo != null) {
if (!isBasicType(hijo)) {
bean2xml(hijo, propertyTag, doc, dateWithTime, deep + 1, processedObjects);
} else {
Element tagElement = doc.createElement(hijo.getClass().getSimpleName());
Text txtNode = doc.createCDATASection(hijo.toString());
tagElement.appendChild(txtNode);
propertyTag.appendChild(tagElement);
}
}
}
} else if (isBasicType(result)) {
/**
* On primitives, we check if they are marked as @Attribue
*/
likeAttribute = checkMarkedAsAttribute(clazz, propertyName);
String string = (numberFormat != null && result instanceof Number) ? numberFormat
.format(result) : result.toString();
Text txtNode = doc.createCDATASection(string);
if (!likeAttribute) {
propertyTag.appendChild(txtNode);
} else {
root.setAttribute(propertyName, string);
}
} else if (result.getClass().isArray()) {
for (int j = 0; j < Array.getLength(result); j++) {
Object child = Array.get(result, j);
if (child != null) {
if (!isBasicType(child)) {
bean2xml(child, propertyTag, doc, dateWithTime, deep + 1, processedObjects);
} else {
Element tagElement = doc.createElement(child.getClass().getSimpleName());
Text txtNode = doc.createCDATASection(child.toString());
tagElement.appendChild(txtNode);
propertyTag.appendChild(tagElement);
}
}
}
} else if (result instanceof Date) {
SimpleDateFormat sdf = null;
if (dateWithTime) {
sdf = new SimpleDateFormat(dateTimeFormat);
} else {
sdf = new SimpleDateFormat(dateFormat);
}
String fechaStr = sdf.format((Date) result);
Text txtNode = doc.createCDATASection(fechaStr);
propertyTag.appendChild(txtNode);
} else if (result instanceof Enum>) {
Text txtNode = doc.createCDATASection(result.toString());
propertyTag.appendChild(txtNode);
} else {
bean2xml(result, propertyTag, doc, dateWithTime, deep + 1, processedObjects);
}
} else {
/**
* Si un valor es nulo también deberiamos de tener en
* cuanta si lo queremos como atributo o no. En caso de
* ser atributo directamente no aparecerá como atributo
* vacío (los tags si aparecen cuando están vacíos).
*/
likeAttribute = checkMarkedAsAttribute(clazz, propertyName);
}
if (!likeAttribute) {
root.appendChild(propertyTag);
}
}
}
return root;
} catch (DOMException e) {
logger.error(e, "clazzName={0} ; simpleClassName={1}", clazzName, rootName);
throw e;
}
}
private static boolean checkMarkedAsAttribute(Class> clase, String nombrePropiedad) {
try {
Field f = clase.getDeclaredField(nombrePropiedad);
boolean markedAsAttribute = f.isAnnotationPresent(Attribute.class);
return markedAsAttribute;
} catch (SecurityException e) {
/*
* El campo como tal no existe (es sólo un getter) así que no puede
* estar marcado. Se devuelve falso.
*/
return false;
} catch (NoSuchFieldException e) {
/*
* El campo como tal no existe (es sólo un getter) así que no puede
* estar marcado. Se devuelve falso.
*/
return false;
}
}
protected static boolean isBasicType(Object obj) {
return obj instanceof String || obj instanceof Integer || obj instanceof Long || obj instanceof Double
|| obj instanceof Boolean || obj instanceof Float || obj instanceof Byte;
}
protected static byte[] DOM2String(Document doc, boolean salidaEnUTF8, boolean indent) throws TransformerException,
UnsupportedEncodingException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = null;
transformer = transformerFactory.newTransformer();
if (indent) {
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
}
Source source = new DOMSource(doc);
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
transformer.transform(source, result);
return salidaEnUTF8 ? writer.toString().getBytes("UTF-8") : writer.toString().getBytes();
}
protected static String getSimpleClassName(String className) {
int idx = className.lastIndexOf('.');
String simple = className.substring(idx + 1);
idx = simple.indexOf('$');
if (idx >= 0) {
simple = simple.replaceAll("\\$", ".");
}
return simple;
}
public static String getDateTimeFormat() {
return dateTimeFormat;
}
public static void setDateTimeFormat(String dateTimeFormat) {
XMLUtil.dateTimeFormat = dateTimeFormat;
}
public static String getDateFormat() {
return dateFormat;
}
public static void setDateFormat(String dateFormat) {
XMLUtil.dateFormat = dateFormat;
}
public static NumberFormat getNumberFormat() {
return numberFormat;
}
public static void setNumberFormat(NumberFormat numberFormat) {
XMLUtil.numberFormat = numberFormat;
}
}