All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jsftoolkit.utils.serial.AnnotatedObjectDomSerializer Maven / Gradle / Ivy

package com.jsftoolkit.utils.serial;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.jsftoolkit.utils.Utils;

/**
 * {@link #toDom(Object, Document, DomSerializerManager)}
 * 
 * @author noah
 * 
 */
public class AnnotatedObjectDomSerializer implements DomSerializer {

	/**
	 * Checks obj for {@link XmlElement}, {@link XmlAttribute},
	 * {@link XmlCollection}, and {@link XmlFollow} annotations and serializes
	 * appropriately.
	 * 

* Only annotated properties are serialized. If obj does not have the * {@link XmlElement} annotation, an {@link IllegalArgumentException} will * be thrown. */ @SuppressWarnings("unchecked") public Node toDom(Object obj, Document doc, DomSerializerManager manager) { if (obj == null) { return null; } Class clazz = obj.getClass(); // check the annotation XmlElement annotation = clazz.getAnnotation(XmlElement.class); if (annotation == null) { throw new IllegalArgumentException(clazz + " is not annotated and does not have a DomSerializer."); } // create an element for the object Element element = doc.createElement(annotation.tagName()); // get the property descriptors BeanInfo beanInfo; try { beanInfo = Introspector.getBeanInfo(clazz); } catch (IntrospectionException e) { throw new RuntimeException("Introspection failed on " + clazz, e); } // check each property for annotations for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) { try { Method read = pd.getReadMethod(); Object pValue = read.invoke(obj); if (pValue == null) { continue; } // see if it is an attribute XmlAttribute attrib = read.getAnnotation(XmlAttribute.class); if (attrib != null) { element.setAttribute(Utils.getValue(attrib.name(), pd .getName()), manager.serialize(pValue)); } else { // if not, see if it is a nested element XmlFollow follow = read.getAnnotation(XmlFollow.class); if (follow != null) { element.appendChild(manager.nextToDom(pValue, doc)); } else { for (Node child : tryCollection(doc, manager, pd, pValue)) { element.appendChild(child); } } } } catch (Exception e) { throw new RuntimeException("Error getting value of " + pd.getName(), e); } } return element; } /** * Creates nodes from the value, if it has the {@link XmlCollection} * annotation. * * @param doc * @param manager * @param pd * @param pValue * @return * @throws Exception */ protected List tryCollection(Document doc, DomSerializerManager manager, PropertyDescriptor pd, Object pValue) throws Exception { XmlCollection collection = pd.getReadMethod().getAnnotation( XmlCollection.class); List nodes = new ArrayList(); if (collection == null || pValue == null) { return nodes; } // get the items to be serialized Class cType = pValue.getClass(); Collection items = null; if (Collection.class.isAssignableFrom(cType)) { items = (Collection) pValue; } else if (Map.class.isAssignableFrom(cType)) { items = ((Map) pValue).values(); } else { throw new IllegalArgumentException( "Argument is not a Collection or a Map"); } // create an element for each item String tag = collection.itemTag(); for (Object item : items) { if (Utils.isEmpty(tag)) { nodes.add(manager.nextToDom(item, doc)); } else { Node itemNode = doc.createElement(tag); itemNode.appendChild(manager.nextToDom(item, doc)); nodes.add(itemNode); } } return nodes; } }