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

com.cedarsolutions.util.JaxbUtils Maven / Gradle / Ivy

There is a newer version: 5.8.4
Show newest version
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *              C E D A R
 *          S O L U T I O N S       "Software done right."
 *           S O F T W A R E
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * Copyright (c) 2013 Kenneth J. Pronovici.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Apache License, Version 2.0.
 * See LICENSE for more information about the licensing terms.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * Author   : Kenneth J. Pronovici 
 * Language : Java 6
 * Project  : Common Java Functionality
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package com.cedarsolutions.util;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.util.ValidationEventCollector;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import com.cedarsolutions.exception.CedarRuntimeException;

/**
 * JAXB utilities that operate on a cached JAXB context.
 *
 * 

* The process of establishing a JAXB context can be pretty slow. So, we want * to avoid having to do it more often than necessary. This class keeps an * internal cache of contexts that have already been established. It also * provides some utility methods to simplify marshalling and unmarshalling. *

* * @author Kenneth J. Pronovici */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class JaxbUtils { /** Singleton instance. */ private static JaxbUtils INSTANCE; /** Map from class name to generated JAXB context. */ private Map contextMap = new HashMap(); /** Default constructor is private so class cannot be instantiated. */ private JaxbUtils() { } /** Get an instance of this class to use. */ public static synchronized JaxbUtils getInstance() { if (INSTANCE == null) { INSTANCE = new JaxbUtils(); } return INSTANCE; } /** * Get a JAXB context for the indicated class. * @param className Name of the class to get a context for * @return JAXB context for the class. */ public JAXBContext getJaxbContext(String className) { try { Class clazz = Class.forName(className); return this.getJaxbContext(clazz); } catch (Exception e) { throw new CedarRuntimeException("Error obtaining JAXB context: " + e.getMessage(), e); } } /** * Get a JAXB context for the indicated class. * @param clazz Class to get a context for. * @return JAXB context for the class. */ public synchronized JAXBContext getJaxbContext(Class clazz) { if (!this.contextMap.containsKey(clazz.getName())) { try { JAXBContext context = JAXBContext.newInstance(clazz); this.contextMap.put(clazz.getName(), context); } catch (Exception e) { throw new CedarRuntimeException("Error obtaining JAXB context: " + e.getMessage(), e); } } return this.contextMap.get(clazz.getName()); } /** * Marshal an object of type T, creating XML. * @param Type of the object * @param value Value to marshal. * @return Generated XML. */ public String marshalDocument(T value) { try { JAXBContext context = this.getJaxbContext(value.getClass()); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false); StringWriter writer = new StringWriter(); marshaller.marshal(value, writer); return writer.toString(); } catch (JAXBException e) { throw new CedarRuntimeException("Error marshalling XML: " + e.getMessage(), e); } } /** * Unmarshal XML, creating an object of type T. * @param Type of the object * @param type Type of the object to unmarshal * @param xml XML to use as source * @return Object of type T, unmarshalled from the XML. */ public T unmarshalDocument(Class type, String xml) { return unmarshalDocument(type, xml, true); } /** * Unmarshal XML, creating an object of type T. * @param Type of the object * @param type Type of the object to unmarshal * @param xml XML to use as source * @param validate Whether to validate the unmarshalling step * @return Object of type T, unmarshalled from the XML. */ public T unmarshalDocument(Class type, String xml, boolean validate) { try { JAXBContext context = this.getJaxbContext(type); StringReader reader = new StringReader(xml); Source source = new StreamSource(reader); Unmarshaller unmarshaller = context.createUnmarshaller(); // If an adapter fails, we don't get an unmarshal exception. // Instead, we have to register and interrogate a handler. // See also: http://java.net/jira/browse/JAXB-537 ValidationEventCollector eventHandler = new ValidationEventCollector(); unmarshaller.setEventHandler(eventHandler); JAXBElement element = unmarshaller.unmarshal(source, type); if (validate) { if (eventHandler.hasEvents()) { StringBuffer buffer = new StringBuffer(); buffer.append("Error unmarshalling XML: found validation error(s)"); for (ValidationEvent event : eventHandler.getEvents()) { buffer.append("\n\t -> "); buffer.append(event.getMessage()); } throw new CedarRuntimeException(buffer.toString()); } } return element.getValue(); } catch (JAXBException e) { throw new CedarRuntimeException("Error unmarshalling XML: " + e.getMessage(), e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy