/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.sa.util; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringWriter; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; /** * Utility for acquiring JAXB Contexts and performing serialization/deserialization. This class leverages special files * in META-INF/jaxb-index. These allow any plugin to contribute to the jaxb context used for serialization in the * engine. */ public class JAXBUtils { private static final Logger LOG = Logger.getLogger(JAXBUtils.class); private static volatile JAXBContext CONTEXT; /** Serialize the given object to XML */ public static String marshal(Object obj) throws JAXBException { StringWriter writer = new StringWriter(); JAXBUtils.getJAXBContext().createMarshaller().marshal(obj, writer); return writer.toString(); } /** Unmarshall the XML string to the Type of T */ @SuppressWarnings("unchecked") public static <T> T unmarshal(String xml) throws JAXBException, IOException { ByteArrayInputStream input = new ByteArrayInputStream(xml.getBytes()); Object obj = JAXBUtils.getJAXBContext().createUnmarshaller().unmarshal(input); input.close(); return (T) obj; } public static JAXBContext getJAXBContext() throws JAXBException { if (CONTEXT == null) { CONTEXT = getJAXBContext(JAXBUtils.class.getClassLoader()); } return CONTEXT; } private static JAXBContext getJAXBContext(ClassLoader classLoader) throws JAXBException { String contextPath = findContextPath(classLoader); return JAXBContext.newInstance(contextPath); } private static String findContextPath(ClassLoader classLoader) throws JAXBException { Set<String> packageNames = new HashSet<String>(); try { Enumeration<URL> resources = classLoader.getResources("META-INF/jaxb-index"); while (resources.hasMoreElements()) { URL url = resources.nextElement(); LOG.debug("Found jaxb-index: " + url); readPackages(url, packageNames); } } catch (IOException e) { LOG.info("Failed to load META-INF/jaxb-index files", e); throw new JAXBException(e); } return StringUtils.join(packageNames, ":"); } private static void readPackages(URL url, Set<String> packageNames) throws IOException { BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream())); try { for (String s = r.readLine(); s != null; s = r.readLine()) { s = StringUtils.trimToNull(s); if (s != null) { LOG.debug("Adding package JAXB context: " + s); packageNames.add(s); } } } finally { r.close(); } } }