package org.atricore.idbus.capabilities.josso.main.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.atricore.idbus.capabilities.josso.main.JossoConstants;
import org.atricore.idbus.capabilities.sso.support.core.util.StringSource;
import org.atricore.idbus.kernel.main.databinding.JAXBUtils;
import org.xml.sax.SAXException;
import javax.xml.bind.*;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.ws.Holder;
import java.io.ByteArrayOutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.TreeSet;
/**
* @author <a href="mailto:sgonzalez@atricore.org">Sebastian Gonzalez Oyuela</a>
* @version $Id$
*/
public class XmlUtils {
private static final Log logger = LogFactory.getLog(XmlUtils.class);
private static final TreeSet<String> ssoContextPackages = new TreeSet<String>();
private static final Holder<JAXBUtils.CONSTRUCTION_TYPE> constructionType = new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
private static final XMLInputFactory staxIF = XMLInputFactory.newInstance();
private static final XMLOutputFactory staxOF = XMLOutputFactory.newInstance();
static {
ssoContextPackages.add(JossoConstants.JOSSO_PROTOCOL_PKG);
javax.xml.parsers.DocumentBuilderFactory dbf =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.SAXParserFactory saxf =
SAXParserFactory.newInstance();
try {
logger.debug("DocumentBuilder = " + dbf.newDocumentBuilder());
logger.debug("SAXParser = " + saxf.newSAXParser());
logger.debug("XMLEventReader = " + staxIF.createXMLEventReader(new StringSource("<a>Hello</a>")));
logger.debug("XMLEventWriter = " + staxOF.createXMLEventWriter(new ByteArrayOutputStream()));
} catch (ParserConfigurationException e) {
logger.error(e.getMessage(), e);
} catch (SAXException e) {
logger.error(e.getMessage(), e);
} catch (XMLStreamException e) {
logger.error(e.getMessage(), e);
}
}
public static String marshall(Object content , boolean encode) throws Exception {
String type = content.getClass().getSimpleName();
if (type.endsWith("Type"))
type = type.substring(0, type.length() - 4);
return marshall(content, type, encode);
}
public static String marshall(Object content,
String contentType, boolean encode) throws Exception {
String marshalled;
marshalled = XmlUtils.marshal(content,
JossoConstants.JOSSO_PROTOCOL_NS,
contentType,
new String[]{ JossoConstants.JOSSO_PROTOCOL_PKG }
);
return encode ? new String( new Base64().encode( marshalled.getBytes() ) ) : marshalled;
}
public static JAXBElement createJAXBelement(Object content) {
Class clazz = (Class) content.getClass();
// Remove the 'Type' suffix from the xml type name and use it as XML element!
XmlType t = (XmlType) clazz.getAnnotation(XmlType.class);
String element = t.name().substring(0, t.name().length() - 4);
return new JAXBElement(new QName(JossoConstants.JOSSO_PROTOCOL_NS, element), clazz, content);
}
// JAXB Generic
public static String marshal ( Object msg, String msgQName, String msgLocalName, String[] userPackages ) throws Exception {
TreeSet<String> contextPackages = new TreeSet<String>();
for (int i = 0; i < userPackages.length; i++) {
String userPackage = userPackages[i];
contextPackages.add(userPackage);
}
JAXBContext jaxbContext = JAXBUtils.getJAXBContext(contextPackages, constructionType,
contextPackages.toString(), XmlUtils.class.getClassLoader(), new HashMap<String, Object>());
Marshaller marshaller = JAXBUtils.getJAXBMarshaller(jaxbContext);
JAXBElement jaxbRequest = new JAXBElement( new QName( msgQName, msgLocalName ),
msg.getClass(),
msg
);
Writer writer = new StringWriter();
// Support XMLDsig
XMLEventWriter xmlWriter = staxOF.createXMLEventWriter(writer);
marshaller.marshal( jaxbRequest, xmlWriter);
xmlWriter.flush();
JAXBUtils.releaseJAXBMarshaller(jaxbContext, marshaller);
return writer.toString();
}
public static Object unmarshal(String msg, String userPackages[]) throws Exception {
TreeSet<String> contextPackages = new TreeSet<String>();
for (int i = 0; i < userPackages.length; i++) {
String userPackage = userPackages[i];
contextPackages.add(userPackage);
}
JAXBContext jaxbContext = JAXBUtils.getJAXBContext(contextPackages, constructionType,
contextPackages.toString(), XmlUtils.class.getClassLoader(), new HashMap<String, Object>());
Unmarshaller unmarshaller = JAXBUtils.getJAXBUnmarshaller(jaxbContext);
Object o = unmarshaller.unmarshal(staxIF.createXMLStreamReader(new StringSource(msg)));
JAXBUtils.releaseJAXBUnmarshaller(jaxbContext, unmarshaller);
if (o instanceof JAXBElement)
return ((JAXBElement) o).getValue();
return o;
}
}