/******************************************************************************* * Copyright (c) 2012 OpenLegacy Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * OpenLegacy Inc. - initial API and implementation *******************************************************************************/ package org.openlegacy.utils; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.ObjectUtils; import org.springframework.beans.DirectFieldAccessor; import java.beans.PropertyDescriptor; import java.io.InputStream; import java.io.OutputStream; import java.util.Collection; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller.Listener; import javax.xml.bind.Unmarshaller; public class XmlSerializationUtil { public static <T> void serialize(Class<T> rootClass, T persistedObject, OutputStream out) throws JAXBException { JAXBContext context = JAXBContext.newInstance(rootClass); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setListener(new Listener() { @Override public void beforeMarshal(Object source) { resetDefaultValues(source); super.beforeMarshal(source); } }); marshaller.marshal(persistedObject, out); } @SuppressWarnings("unchecked") public static <T> T deserialize(Class<T> rootClass, InputStream in) throws JAXBException { JAXBContext context = JAXBContext.newInstance(rootClass); Unmarshaller unmarshaller = context.createUnmarshaller(); return (T)unmarshaller.unmarshal(in); } /** * This method purpose is to reduce the amount of XML written when serializing an object It reset member to null when the * default value matches the object value * * @param source */ private static void resetDefaultValues(Object source) { DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(source); PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(source); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { String propertyName = propertyDescriptor.getName(); Class<?> propertyType = fieldAccessor.getPropertyType(propertyName); if (propertyType == null || Collection.class.isAssignableFrom(propertyType) || Map.class.isAssignableFrom(propertyType)) { continue; } Object defaultValue = PropertyUtil.getPropertyDefaultValue(source.getClass(), propertyName); Object value = fieldAccessor.getPropertyValue(propertyName); if (fieldAccessor.isWritableProperty(propertyName) && ObjectUtils.equals(value, defaultValue) && !propertyType.isPrimitive()) { fieldAccessor.setPropertyValue(propertyName, null); } } } }