/jaxrs/eagledns/src/main/java/se/unlogic/standardutils/xml/XMLGenerator.java
Java | 349 lines | 205 code | 136 blank | 8 comment | 65 complexity | f6f8c9aa3ec579aa3e69c061fbefee17 MD5 | raw file
- /*******************************************************************************
- * Copyright (c) 2010 Robert "Unlogic" Olofsson (unlogic@unlogic.se).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Lesser Public License v3
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/lgpl-3.0-standalone.html
- ******************************************************************************/
- package se.unlogic.standardutils.xml;
-
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import se.unlogic.standardutils.annotations.NoAnnotatedFieldsFoundException;
- import se.unlogic.standardutils.arrays.ArrayUtils;
- import se.unlogic.standardutils.date.DateUtils;
- import se.unlogic.standardutils.reflection.ReflectionUtils;
- import se.unlogic.standardutils.string.DummyStringyfier;
- import se.unlogic.standardutils.string.StringUtils;
- import se.unlogic.standardutils.string.Stringyfier;
-
- import java.lang.reflect.Field;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Date;
- import java.util.List;
- import java.util.concurrent.ConcurrentHashMap;
-
- public class XMLGenerator {
-
- //TODO Use weak references in this map to prevent memory leaks
- private static ConcurrentHashMap<Class<?>, ClassXMLInfo> FIELD_MAP = new ConcurrentHashMap<Class<?>, ClassXMLInfo>();
-
- @SuppressWarnings("unchecked")
- public static Element toXML(Object bean, Document doc){
-
- ClassXMLInfo classInfo = FIELD_MAP.get(bean.getClass());
-
- if(classInfo == null){
-
- Class<?> clazz = bean.getClass();
-
- XMLElement xmlElement = clazz.getAnnotation(XMLElement.class);
-
- if(xmlElement == null){
-
- throw new MissingXMLAnnotationException(clazz);
- }
-
- String elementName = xmlElement.name();
-
- if(StringUtils.isEmpty(elementName)){
-
- elementName = clazz.getSimpleName();
- }
-
- List<FieldXMLInfo> annotatedFields = new ArrayList<FieldXMLInfo>();
-
- Class<?> currentClazz = clazz;
-
- while (currentClazz != Object.class) {
-
- Field[] fields = currentClazz.getDeclaredFields();
-
- for(Field field : fields){
-
- XMLElement elementAnnotation = field.getAnnotation(XMLElement.class);
-
- if(elementAnnotation != null){
-
- String name = elementAnnotation.name();
-
- if(StringUtils.isEmpty(name)){
-
- name = field.getName();
- }
-
- Stringyfier valueFormatter = null;
-
- if(elementAnnotation.valueFormatter() != DummyStringyfier.class){
-
- try {
- valueFormatter = elementAnnotation.valueFormatter().newInstance();
-
- } catch (InstantiationException e) {
-
- throw new RuntimeException(e);
-
- } catch (IllegalAccessException e) {
-
- throw new RuntimeException(e);
- }
- }
-
- if(Collection.class.isAssignableFrom(field.getType())){
-
- boolean elementable = false;
-
- if(ReflectionUtils.isGenericlyTyped(field) && Elementable.class.isAssignableFrom((Class<?>) ReflectionUtils.getGenericType(field))){
-
- elementable = true;
- }
-
- String childName = elementAnnotation.childName();
-
- if(StringUtils.isEmpty(childName)){
-
- childName = "value";
- }
-
- annotatedFields.add(new FieldXMLInfo(name, field, FieldType.Element,elementAnnotation.cdata(),elementable,true,false,childName,elementAnnotation.skipChildParentElement(),valueFormatter));
-
- }else if(field.getType().isArray()){
-
- boolean elementable = false;
-
- if(Elementable.class.isAssignableFrom(field.getType())){
-
- elementable = true;
- }
-
- String childName = elementAnnotation.childName();
-
- if(StringUtils.isEmpty(childName)){
-
- childName = "value";
- }
-
- annotatedFields.add(new FieldXMLInfo(name, field, FieldType.Element,elementAnnotation.cdata(),elementable,false,true,childName,elementAnnotation.skipChildParentElement(),valueFormatter));
-
- }else{
-
- String childName = null;
-
- if(!StringUtils.isEmpty(elementAnnotation.childName())){
-
- childName = elementAnnotation.childName();
- }
-
- annotatedFields.add(new FieldXMLInfo(name, field, FieldType.Element,elementAnnotation.cdata(),Elementable.class.isAssignableFrom(field.getType()),false,false,childName,false,valueFormatter));
- }
-
- ReflectionUtils.fixFieldAccess(field);
- }
-
- XMLAttribute attributeAnnotation = field.getAnnotation(XMLAttribute.class);
-
- if(attributeAnnotation != null){
-
- String name = attributeAnnotation.name();
-
- if(StringUtils.isEmpty(name)){
-
- name = field.getName();
- }
-
- Stringyfier valueFormatter = null;
-
- if(attributeAnnotation.valueFormatter() != DummyStringyfier.class){
-
- try {
- valueFormatter = attributeAnnotation.valueFormatter().newInstance();
-
- } catch (InstantiationException e) {
-
- throw new RuntimeException(e);
-
- } catch (IllegalAccessException e) {
-
- throw new RuntimeException(e);
- }
- }
-
- annotatedFields.add(new FieldXMLInfo(name, field, FieldType.Attribute,false,false,false,false,null,false,valueFormatter));
-
- ReflectionUtils.fixFieldAccess(field);
- }
- }
-
- currentClazz = currentClazz.getSuperclass();
- }
-
- if(annotatedFields.isEmpty()){
-
- throw new NoAnnotatedFieldsFoundException(clazz,XMLElement.class,XMLAttribute.class);
- }
-
- classInfo = new ClassXMLInfo(elementName, annotatedFields);
-
- FIELD_MAP.put(clazz, classInfo);
- }
-
- Element classElement = doc.createElement(classInfo.getElementName());
-
- for(FieldXMLInfo fieldInfo : classInfo.getFields()){
-
- Object fieldValue;
- try {
- fieldValue = fieldInfo.getField().get(bean);
- } catch (IllegalArgumentException e) {
-
- throw new RuntimeException(e);
-
- } catch (IllegalAccessException e) {
-
- throw new RuntimeException(e);
- }
-
- if(fieldValue == null){
-
- continue;
-
- }else if(!fieldInfo.isList() && fieldInfo.getValueFormatter() != null){
-
- fieldValue = fieldInfo.getValueFormatter().format(fieldValue);
-
- }else if(fieldValue instanceof Date){
-
- fieldValue = DateUtils.DATE_TIME_FORMATTER.format(fieldValue);
- }
-
- if(fieldInfo.getFieldType() == FieldType.Attribute){
-
- classElement.setAttribute(fieldInfo.getName(), fieldValue.toString());
-
- }else if(fieldInfo.isList()){
-
- List<?> fieldValues = (List<?>)fieldValue;
-
- if(fieldValues.isEmpty()){
-
- continue;
- }
-
- Element subElement;
-
- if(fieldInfo.skipSubElement()){
-
- subElement = classElement;
-
- }else{
-
- subElement = doc.createElement(fieldInfo.getName());
- }
-
-
- for(Object value : fieldValues){
-
- if(value != null){
-
- parseValue(fieldInfo,value,subElement,doc);
- }
- }
-
- if(!fieldInfo.skipSubElement() && subElement.hasChildNodes()){
- classElement.appendChild(subElement);
- }
-
- }else if(fieldInfo.isArray()){
-
- Object[] fieldValues = (Object[])fieldValue;
-
- if(ArrayUtils.isEmpty(fieldValues)){
-
- continue;
- }
-
- Element subElement;
-
- if(fieldInfo.skipSubElement()){
-
- subElement = classElement;
-
- }else{
-
- subElement = doc.createElement(fieldInfo.getName());
- }
-
-
- for(Object value : fieldValues){
-
- if(value != null){
-
- parseValue(fieldInfo,value,subElement,doc);
- }
- }
-
- if(!fieldInfo.skipSubElement() && subElement.hasChildNodes()){
- classElement.appendChild(subElement);
- }
-
- }else if(fieldInfo.isElementable()){
-
- Element subElement = ((Elementable)fieldValue).toXML(doc);
-
- if(subElement != null){
-
- if(fieldInfo.getChildName() != null){
-
- Element middleElement = doc.createElement(fieldInfo.getChildName());
- classElement.appendChild(middleElement);
- middleElement.appendChild(subElement);
-
- }else{
- classElement.appendChild(subElement);
- }
- }
- }else if(fieldInfo.isCDATA()){
-
- classElement.appendChild(XMLUtils.createCDATAElement(fieldInfo.getName(), fieldValue.toString(), doc));
-
- }else{
- classElement.appendChild(XMLUtils.createElement(fieldInfo.getName(), fieldValue.toString(), doc));
- }
- }
-
- return classElement;
- }
-
- private static void parseValue(FieldXMLInfo fieldInfo, Object value, Element subElement, Document doc) {
-
- if(fieldInfo.getValueFormatter() != null){
-
- value = fieldInfo.getValueFormatter().format(value);
-
- }else if(value instanceof Date){
-
- value = DateUtils.DATE_TIME_FORMATTER.format(value);
- }
-
- if(fieldInfo.isElementable()){
-
- Element subSubElement = ((Elementable)value).toXML(doc);
-
- if(subSubElement != null){
-
- subElement.appendChild(subSubElement);
- }
- }else{
-
- if(fieldInfo.isCDATA()){
-
- subElement.appendChild(XMLUtils.createCDATAElement(fieldInfo.getChildName(), value, doc));
-
- }else{
-
- subElement.appendChild(XMLUtils.createElement(fieldInfo.getChildName(), value, doc));
- }
- }
- }
- }