//
// typica - A client library for Amazon Web Services
// Copyright (C) 2007 Xerox Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.xerox.amazonws.common;
import java.io.InputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Hashtable;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
/**
* This class implements some helpful methods to marshal and unmarshal xml.
*
* @author D. Kavanagh
* @author developer@dotech.com
*/
public class JAXBuddy {
public final static Hashtable<String, JAXBContext> contextCache = new Hashtable<String, JAXBContext>();
private static final DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
private static ThreadLocal<DocumentBuilder> builder = null;
public static DocumentBuilder createDocumentBuilder() throws Exception
{
return domFactory.newDocumentBuilder() ;
}
/** Initialize DocumentBuilder **/
static {
builder = new ThreadLocal<DocumentBuilder>() {
@Override
protected synchronized DocumentBuilder initialValue() {
DocumentBuilder b = null;
try {
domFactory.setNamespaceAware(true);
b= createDocumentBuilder();
} catch(JAXBException e) {
throw new ExceptionInInitializerError(e);
} catch (Exception e) {
e.printStackTrace();
}
return b;
}
};
}
/**
* A convenience method to turn an object into a stream of XML.
*
* @param c the class you're serializing
* @param object the object you're serializing
* @return an input stream to read the XML from
*/
public static <T> InputStream serializeXMLFile(Class<T> c, Object object)
throws JAXBException, IOException {
Marshaller m = getMarshaller(c);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
m.marshal(object, baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return bais;
}
/**
* A convenience method to turn an object into a string of XML.
*
* @param c the class you're serializing
* @param object the object you're serializing
* @return a string containing the XML
*/
public static <T> String serializeXMLString(Class<T> c, Object object)
throws JAXBException, IOException {
Marshaller m = getMarshaller(c);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
m.marshal(object, baos);
return new String(baos.toByteArray());
}
/**
* A convenience method to turn XML in a stream into an object.
*
* @param c the class you're deserializing
* @param is the stream to read the XMl from
* @return an object representing the data from the stream
*/
public static <T> T deserializeXMLStream(Class<T> c, InputStream is)
throws JAXBException, IOException, SAXException {
Unmarshaller u = getUnmarshaller(c);
//T result = c.cast(u.unmarshal(is));
Document doc = builder.get().parse(is);
if (doc == null) {
throw new IOException("XML parser returned no document");
}
Node root = doc.getDocumentElement();
T result = c.cast(u.unmarshal(doc));
return result;
}
/**
* This method will clear the internal cache we use to speed up these util functions.
*
* Do we think anybody will need this method? no...
* Are we providing it to be nice to the anal retentive amongst us? yes.
*/
public static void clearCache() {
contextCache.clear();
}
private static Marshaller getMarshaller(Class<?> c) throws JAXBException {
String typePackage = c.getPackage().getName();
JAXBContext jc = contextCache.get(typePackage);
if (jc == null) {
jc = JAXBContext.newInstance(typePackage);
contextCache.put(typePackage, jc);
}
Marshaller m = jc.createMarshaller();
return m;
}
private static Unmarshaller getUnmarshaller(Class<?> c) throws JAXBException {
String typePackage = c.getPackage().getName();
JAXBContext jc = contextCache.get(typePackage);
if (jc == null) {
jc = JAXBContext.newInstance(typePackage, c.getClassLoader());
contextCache.put(typePackage, jc);
}
Unmarshaller u = jc.createUnmarshaller();
return u;
}
}