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.
com.nervousync.utils.XmlUtils Maven / Gradle / Ivy
Go to download
Java Utils collections, development by Nervousync Studio (NSYC)
/*
* Licensed to the Nervousync Studio (NSYC) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nervousync.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nervousync.commons.beans.xml.BaseElement;
import com.nervousync.commons.core.Globals;
import com.nervousync.enumerations.xml.DataType;
import com.nervousync.exceptions.xml.XmlException;
/**
* @author Steven Wee [email protected]
* @version $Revision: 1.0 $ $Date: 2009/09/28 14:32:00 $
*/
public final class XmlUtils {
public static final String DEFAULT_NAME = "##default";
// Log Object
private final static Logger LOGGER = LoggerFactory.getLogger(XmlUtils.class);
private XmlUtils() {
}
public static Document loadXml(String xml, XmlNs xmlNs) throws XmlException {
return XmlUtils.loadXml(xml, Globals.DEFAULT_ENCODING, xmlNs);
}
public static Document loadXml(String xml, String encoding, XmlNs xmlNs) throws XmlException {
InputStream inputStream = null;
try {
byte[] xmlBytes = null;
if (encoding == null) {
xmlBytes = xml.getBytes();
} else {
xmlBytes = xml.getBytes(encoding);
}
inputStream = new ByteArrayInputStream(xmlBytes);
SAXReader reader = new SAXReader();
if (xmlNs != null) {
Map namespaceURIs = new HashMap();
namespaceURIs.put(xmlNs.prefix(), xmlNs.namespaceURI());
reader.getDocumentFactory().setXPathNamespaceURIs(namespaceURIs);
}
return reader.read(inputStream);
} catch (Exception e) {
throw new XmlException("Load xml file error! ", e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
throw new XmlException("Close input stream error! ", e);
}
}
}
}
public static String convertToXml(Object object, String indent, String encoding,
boolean expandEmptyElements) throws XmlException {
Document document = XmlUtils.convertToXmlDocument(object, !expandEmptyElements);
return XmlUtils.convertToXmlString(document, indent, encoding, expandEmptyElements);
}
public static T convertToObject(String xml, Class classType) throws XmlException {
return convertToObject(xml, Globals.DEFAULT_ENCODING, classType);
}
public static T convertToObject(String xml, String encoding, Class classType) throws XmlException {
XmlNs xmlNs = null;
if (classType.isAnnotationPresent(XmlNs.class)) {
xmlNs = classType.getAnnotation(XmlNs.class);
}
Document document = XmlUtils.loadXml(xml, encoding, xmlNs);
return XmlUtils.convertToObject(document, classType);
}
public static T convertToObject(Object xmlObj, Class classType) throws XmlException {
T object = null;
if (xmlObj == null) {
return null;
}
XmlNs xmlNs = null;
if (classType.isAnnotationPresent(XmlNs.class)) {
xmlNs = classType.getAnnotation(XmlNs.class);
}
boolean annoCheck = Globals.DEFAULT_VALUE_BOOLEAN;
Element element = null;
if (xmlObj instanceof Document) {
annoCheck = classType.isAnnotationPresent(XmlRootElement.class);
element = ((Document)xmlObj).getRootElement();
} else if (xmlObj instanceof Element) {
annoCheck = classType.isAnnotationPresent(XmlType.class);
element = (Element)xmlObj;
} else if (xmlObj instanceof InputStream) {
return XmlUtils.convertToObject(FileUtils.readFile((InputStream)xmlObj), classType);
} else if (xmlObj instanceof String) {
if (((String)xmlObj).startsWith("<")) {
return XmlUtils.convertToObject(XmlUtils.loadXml((String)xmlObj, xmlNs), classType);
} else if (FileUtils.isExists((String)xmlObj)) {
return XmlUtils.convertToObject(XmlUtils.loadXml(FileUtils.readFile((String)xmlObj), xmlNs), classType);
}
}
if (annoCheck) {
try {
Constructor constructor = null;
if (classType.getName().indexOf('$') == -1) {
constructor = classType.getDeclaredConstructor(new Class[] {});
constructor.setAccessible(true);
object = constructor.newInstance();
} else {
if (!Modifier.isStatic(classType.getModifiers())) {
String parameterTypeName = classType.getName();
parameterTypeName = parameterTypeName.substring(0, parameterTypeName.indexOf('$'));
Class> parameterType = ClassUtils.forName(parameterTypeName);
constructor = classType.getDeclaredConstructor(new Class[] {parameterType});
constructor.setAccessible(true);
Constructor> paramConstructor = parameterType.getDeclaredConstructor(new Class[] {});
paramConstructor.setAccessible(true);
Object paramObj = paramConstructor.newInstance();
object = constructor.newInstance(new Object[]{paramObj});
} else {
constructor = classType.getDeclaredConstructor(new Class[] {});
constructor.setAccessible(true);
object = constructor.newInstance();
}
}
Field[] fields = classType.getDeclaredFields();
for (Field field : fields) {
// 遍历所有属性
String fieldName = field.getName();
Object paramObj = null;
if (field.isAnnotationPresent(XmlAttribute.class)) {
// 标注为Attribute
String attributeName = "";
String attributeValue = "";
XmlAttribute xmlAttribute = field.getAnnotation(XmlAttribute.class);
attributeName = xmlAttribute.name();
if (attributeName == null || DEFAULT_NAME.equals(attributeName)
|| attributeName.trim().length() == 0) {
attributeName = fieldName;
}
attributeValue = element.attributeValue(attributeName);
paramObj = StringUtils.parseSimpleData(attributeValue, field.getType());
} else if (field.isAnnotationPresent(XmlElement.class)) {
String elementName = "";
XmlElement xmlElement = field.getAnnotation(XmlElement.class);
elementName = xmlElement.name();
if (elementName == null || DEFAULT_NAME.equals(elementName)
|| elementName.trim().length() == 0) {
elementName = fieldName;
}
boolean isObject = field.getType().isAnnotationPresent(XmlType.class);
if (isObject) {
paramObj = convertToObject(element.element(elementName), field.getType());
} else {
String elementText = element.elementText(elementName);
if (elementText != null) {
paramObj = StringUtils.parseSimpleData(elementText.trim(), field.getType());
}
}
} else if (field.isAnnotationPresent(XmlElementWrapper.class)) {
XmlElementWrapper xmlElementWrapper = field.getAnnotation(XmlElementWrapper.class);
String elemName = xmlElementWrapper.name();
if (elemName == null || elemName.trim().length() == 0
|| DEFAULT_NAME.equals(elemName)) {
elemName = fieldName;
}
String childElemName = null;
Class> paramClass = null;
boolean isArray = field.getType().isArray();
if (isArray) {
paramClass = field.getType().getComponentType();
} else {
paramClass = (Class>)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0];
}
DataType elemType = ObjectUtils.retrieveSimpleDataType(paramClass);
if (DataType.OBJECT.equals(elemType)) {
XmlType childElement = paramClass.getAnnotation(XmlType.class);
childElemName = childElement.name();
if (childElemName == null || childElemName.trim().length() == 0
|| DEFAULT_NAME.equals(childElemName)) {
childElemName = paramClass.getSimpleName();
}
} else {
childElemName = elemName;
elemName = fieldName;
}
List> elemChildren = null;
if (isArray) {
elemChildren = element.elements(childElemName);
} else {
Element childElem = element.element(elemName);
if (childElem != null) {
elemChildren = childElem.elements(childElemName);
}
}
List objList = null;
if (elemChildren != null) {
objList = new ArrayList(elemChildren.size());
for (Object childObj : elemChildren) {
if (DataType.OBJECT.equals(elemType)) {
objList.add(convertToObject((Element)childObj, paramClass));
} else {
String dataValue = ((Element)childObj).getText();
objList.add(StringUtils.parseSimpleData(dataValue, paramClass));
}
}
} else {
objList = new ArrayList(0);
}
if (isArray) {
paramObj = objList.toArray((Object[])Array.newInstance(paramClass, objList.size()));
} else {
paramObj = objList;
}
} else if (field.isAnnotationPresent(XmlValue.class)) {
paramObj = StringUtils.parseSimpleData(element.elementText(field.getName()), field.getType());
}
if (paramObj != null) {
ReflectionUtils.setField(fieldName, object, paramObj);
}
}
} catch (Exception e) {
throw new XmlException(e);
}
}
return object;
}
public static boolean simpleDataType(Class> targetClass) {
if (String.class.equals(targetClass) || int.class.equals(targetClass) || Integer.class.equals(targetClass)
|| double.class.equals(targetClass) || Double.class.equals(targetClass) || float.class.equals(targetClass) || Float.class.equals(targetClass)
|| boolean.class.equals(targetClass) || Boolean.class.equals(targetClass) || short.class.equals(targetClass) || Short.class.equals(targetClass)
|| long.class.equals(targetClass) || Long.class.equals(targetClass) || BigInteger.class.equals(targetClass)) {
return true;
}
return Globals.DEFAULT_VALUE_BOOLEAN;
}
private static List getFields(Class> clazz) {
List fieldList = new ArrayList();
List existsFieldName = new ArrayList();
if (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (!existsFieldName.contains(field.getName())) {
fieldList.add(field);
existsFieldName.add(field.getName());
}
}
if (!clazz.equals(BaseElement.class)) {
XmlUtils.getFields(fieldList, existsFieldName,
clazz.getSuperclass());
}
}
return fieldList;
}
private static void getFields(List fieldList,
List existsFieldName, Class> clazz) {
if (fieldList == null) {
fieldList = new ArrayList();
}
if (existsFieldName == null) {
existsFieldName = new ArrayList();
}
if (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (!existsFieldName.contains(field.getName())) {
fieldList.add(field);
existsFieldName.add(field.getName());
}
}
if (!clazz.equals(BaseElement.class)) {
XmlUtils.getFields(fieldList, existsFieldName,
clazz.getSuperclass());
}
}
}
private static Document convertToXmlDocument(Object object, boolean ignoreNullElement) {
if (object == null) {
return null;
}
Document document = DocumentHelper.createDocument();
// 获取对象的Class
Class> classType = object.getClass();
Class> paramClass = null;
String rootElemName = null;
Object[] arrayObjects = null;
if (classType.isArray()) {
paramClass = classType.getComponentType();
arrayObjects = (Object[])object;
} else if (Collection.class.isAssignableFrom(classType)) {
arrayObjects = ((Collection>)object).toArray();
if (arrayObjects.length > 0) {
paramClass = arrayObjects[0].getClass();
}
}
if (paramClass != null) {
if (XmlUtils.simpleDataType(paramClass)) {
rootElemName = paramClass.getSimpleName();
if (classType.isArray()) {
for (Object itemObject : arrayObjects) {
Element element = document.addElement(rootElemName);
element.addText(itemObject.toString());
}
} else {
Element rootElement = document.addElement(rootElemName + "s");
for (Object itemObject : arrayObjects) {
Element element = rootElement.addElement(rootElemName);
element.addText(itemObject.toString());
}
}
} else {
XmlRootElement documentAnno = paramClass.getAnnotation(XmlRootElement.class);
rootElemName = documentAnno.name();
if (rootElemName == null || DEFAULT_NAME.equals(rootElemName)
|| rootElemName.trim().length() == 0) {
rootElemName = paramClass.getSimpleName();
}
if (classType.isArray()) {
for (Object itemObject : arrayObjects) {
Element element = document.addElement(rootElemName);
XmlUtils.convertToXmlElement(paramClass, itemObject, element, ignoreNullElement);
}
} else {
Element rootElement = document.addElement(rootElemName + "s");
for (Object itemObject : arrayObjects) {
Element element = rootElement.addElement(rootElemName);
XmlUtils.convertToXmlElement(paramClass, itemObject, element, ignoreNullElement);
}
}
}
} else {
XmlRootElement documentAnno = classType.getAnnotation(XmlRootElement.class);
rootElemName = documentAnno.name();
if (rootElemName == null || DEFAULT_NAME.equals(rootElemName)
|| rootElemName.trim().length() == 0) {
rootElemName = classType.getSimpleName();
}
Element rootElement = document.addElement(rootElemName);
XmlUtils.convertToXmlElement(classType, object, rootElement, ignoreNullElement);
}
return document;
}
private static void convertToXmlElement(Class> objectClass, Object object, Element element, boolean ignoreNullElement) {
if (element == null && ignoreNullElement) {
return;
}
DataType dataType = ObjectUtils.retrieveSimpleDataType(objectClass);
if (DataType.OBJECT.equals(dataType)) {
List fields = XmlUtils.getFields(objectClass);
for (Field field : fields) {
if (field.getAnnotations().length == 0) {
continue;
}
String fieldName = field.getName();
Class> fieldClass = field.getType();
if (field.isAnnotationPresent(XmlElementWrapper.class)) {
if (fieldClass.isArray()) {
fieldClass = fieldClass.getComponentType();
// fieldClass = (Class>) field.getGenericType();
} else {
fieldClass = (Class>)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0];
}
}
DataType fieldType = ObjectUtils.retrieveSimpleDataType(fieldClass);
if (DataType.UNKNOWN.equals(fieldType)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Field type unknown!");
}
continue;
}
try {
if (field.isAnnotationPresent(XmlNs.class)) {
XmlNs xmlNs = field.getAnnotation(XmlNs.class);
element.addNamespace(xmlNs.prefix(), xmlNs.namespaceURI());
}
Object fieldValue = ReflectionUtils.getFieldValue(fieldName, object);
if (field.isAnnotationPresent(XmlValue.class)) {
if (fieldValue != null) {
element.setText(fieldValue.toString());
} else {
if (!ignoreNullElement) {
element.setText("");
}
}
continue;
} else if (field.isAnnotationPresent(XmlAttribute.class)) {
// 标注为Attribute
String attributeName = "";
String attributeValue = "";
XmlAttribute xmlAttrAnno = field.getAnnotation(XmlAttribute.class);
attributeName = xmlAttrAnno.name();
if (DEFAULT_NAME.equals(attributeName)
|| attributeName.trim().length() == 0) {
attributeName = fieldName;
}
if (fieldValue != null) {
if (DataType.NUMBER.equals(fieldType) || DataType.STRING.equals(fieldType)
|| DataType.BOOLEAN.equals(fieldType) || DataType.DATE.equals(fieldType)
|| DataType.ENUM.equals(fieldType)) {
if (DataType.DATE.equals(fieldType)) {
attributeValue = DateTimeUtils.formatDateForSitemap((Date) fieldValue);
} else {
attributeValue = fieldValue.toString();
}
element.addAttribute(attributeName, attributeValue);
} else {
throw new XmlException("Attribute type does not support!");
}
} else {
if (!ignoreNullElement) {
element.addAttribute(attributeName, "");
}
}
} else if (field.isAnnotationPresent(XmlElement.class)) {
String elemName = null;
XmlElement xmlElemAnno = field.getAnnotation(XmlElement.class);
elemName = xmlElemAnno.name();
if (elemName == null || DEFAULT_NAME.equals(elemName)
|| elemName.trim().length() == 0) {
elemName = field.getName();
}
if (DataType.OBJECT.equals(fieldType)) {
Element childElement = element.addElement(elemName);
Object childObject = ReflectionUtils.getFieldValue(field, object);
if (childObject == null) {
if (ignoreNullElement) {
continue;
}
}
convertToXmlElement(fieldClass, childObject, childElement, ignoreNullElement);
} else {
String nodeValue = null;
if (fieldValue != null) {
if (DataType.DATE.equals(fieldType)) {
nodeValue = DateTimeUtils.formatDateForSitemap((Date) fieldValue);
} else if (DataType.BINARY.equals(fieldType)) {
byte[] binary = null;
if (fieldValue instanceof byte[]) {
binary = (byte[])fieldValue;
} else {
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(fieldValue);
binary = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Encode binary data error! ", e);
}
} finally {
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.close();
}
}
}
nodeValue = StringUtils.base64Encode(binary);
} else {
if (fieldValue != null) {
nodeValue = StringUtils.formatTextForXML(fieldValue.toString());
}
}
}
if (nodeValue != null) {
element.addElement(elemName).setText(nodeValue);
} else {
if (!ignoreNullElement) {
element.addElement(elemName).setText("");
}
}
}
} else if (field.isAnnotationPresent(XmlElementWrapper.class)) {
String elemName = null;
XmlElementWrapper xmlElementWrapper = field.getAnnotation(XmlElementWrapper.class);
elemName = xmlElementWrapper.name();
if (elemName == null || elemName.trim().length() == 0
|| DEFAULT_NAME.equals(elemName)) {
elemName = fieldName;
}
String childElemName = null;
Class> paramClass = null;
if (field.getType().isArray()) {
paramClass = field.getType().getComponentType();
} else {
paramClass = (Class>)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0];
}
DataType elemType = ObjectUtils.retrieveSimpleDataType(paramClass);
if (DataType.OBJECT.equals(elemType)) {
XmlType childElement = paramClass.getAnnotation(XmlType.class);
childElemName = childElement.name();
if (childElemName == null || childElemName.trim().length() == 0
|| DEFAULT_NAME.equals(childElemName)) {
childElemName = paramClass.getSimpleName();
}
} else {
childElemName = elemName;
elemName = fieldName;
}
if (fieldValue == null) {
if (!ignoreNullElement) {
if (field.getType().isArray()) {
element.addElement(childElemName).setText(Globals.DEFAULT_VALUE_STRING);
} else {
element.addElement(elemName).addElement(childElemName).setText(Globals.DEFAULT_VALUE_STRING);
}
}
continue;
}
Element parentElement = element;
List> arrayList = null;
if (field.getType().isArray()) {
arrayList = Arrays.asList((Object[]) fieldValue);
} else {
parentElement = element.addElement(elemName);
arrayList = (List>) fieldValue;
}
int arrayCount = arrayList.size();
if (arrayCount == 0 && !ignoreNullElement && field.getType().isArray()) {
parentElement.addElement(childElemName).setText("");
continue;
}
for (int j = 0; j < arrayCount; j++) {
Object childObj = arrayList.get(j);
if (DataType.OBJECT.equals(elemType)) {
Element childElem = parentElement.addElement(childElemName);
convertToXmlElement(paramClass, childObj, childElem, ignoreNullElement);
} else {
String nodeValue = null;
if (DataType.DATE.equals(fieldType)) {
nodeValue = DateTimeUtils.formatDateForSitemap((Date) childObj);
} else if (DataType.BINARY.equals(fieldType)) {
byte[] binary = null;
if (fieldValue instanceof byte[]) {
binary = (byte[])childObj;
} else {
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(childObj);
binary = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Encode binary data error! ", e);
}
} finally {
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.close();
}
}
}
nodeValue = StringUtils.base64Encode(binary);
} else {
nodeValue = StringUtils.formatTextForXML(childObj.toString());
}
if (nodeValue != null) {
parentElement.addElement(childElemName).setText(nodeValue);
} else {
if (!ignoreNullElement) {
parentElement.addElement(childElemName).setText("");
}
}
}
}
}
} catch (Exception e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Convert Object To XML Error! ", e);
}
continue;
}
}
} else {
String text = null;
if (object != null) {
if (DataType.DATE.equals(dataType)) {
text = DateTimeUtils.formatDateForSitemap((Date) object);
} else {
text = object.toString();
}
} else {
text = "";
}
element.setText(text);
}
}
private static String convertToXmlString(Document document, String indent, String encoding, boolean expandEmptyElements) throws XmlException {
if (document == null) {
return null;
}
OutputFormat outputFormat = OutputFormat.createPrettyPrint();
if (encoding == null) {
outputFormat.setEncoding(Globals.DEFAULT_ENCODING);
} else {
outputFormat.setEncoding(encoding);
}
outputFormat.setNewLineAfterDeclaration(Globals.DEFAULT_VALUE_BOOLEAN);
outputFormat.setTrimText(true);
if (indent == null) {
outputFormat.setIndent(true);
outputFormat.setNewlines(Globals.DEFAULT_VALUE_BOOLEAN);
} else {
outputFormat.setIndent(indent);
outputFormat.setNewlines(true);
}
outputFormat.setExpandEmptyElements(expandEmptyElements);
StringWriter stringWriter = null;
XMLWriter xmlWriter = null;
try {
stringWriter = new StringWriter();
xmlWriter = new XMLWriter(stringWriter, outputFormat);
xmlWriter.write(document);
return stringWriter.toString();
} catch (IOException e) {
} finally {
try {
if (xmlWriter != null) {
xmlWriter.close();
}
if (stringWriter != null) {
stringWriter.close();
}
} catch (IOException e) {
}
}
return null;
}
}