1 package org.openprovenance.model; 2 3 import javax.xml.parsers.DocumentBuilder; 4 import javax.xml.parsers.DocumentBuilderFactory; 5 import javax.xml.parsers.ParserConfigurationException; 6 7 import javax.xml.bind.JAXBContext; 8 import javax.xml.bind.JAXBException; 9 import javax.xml.bind.Marshaller; 10 import javax.xml.bind.PropertyException; 11 import org.w3c.dom.Document; 12 import org.w3c.dom.Node; 13 import java.io.StringWriter; 14 import java.io.File; 15 16 /*** Serialiser of OPM Graphs. */ 17 18 public class OPMSerialiser { 19 private ObjectFactory of=new ObjectFactory(); 20 static DocumentBuilder docBuilder; 21 22 23 /*** Note DocumentBuilderFactory is documented to be non thread safe. 24 TODO: code analysis, of potential concurrency issues. */ 25 static void initBuilder() { 26 try { 27 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 28 docBuilderFactory.setNamespaceAware(true); 29 docBuilder = docBuilderFactory.newDocumentBuilder(); 30 } catch (ParserConfigurationException ex) { 31 throw new RuntimeException(ex); 32 } 33 } 34 35 private static ThreadLocal<OPMSerialiser> threadSerialiser = 36 new ThreadLocal<OPMSerialiser> () { 37 protected synchronized OPMSerialiser initialValue () { 38 try { 39 return new OPMSerialiser(); 40 } catch (JAXBException jxb) { 41 throw new RuntimeException("OPMDeserialiser: serialiser init failure()"); 42 } 43 } 44 }; 45 46 public static OPMSerialiser getThreadOPMSerialiser() { 47 return threadSerialiser.get(); 48 } 49 50 51 52 static { 53 initBuilder(); 54 } 55 protected JAXBContext jc; 56 57 public static String defaultNamespace="http://example.com/"; 58 59 protected final boolean usePrefixMapper; 60 public OPMSerialiser () throws JAXBException { 61 jc = JAXBContext.newInstance( OPMFactory.packageList ); 62 usePrefixMapper=true; 63 } 64 public OPMSerialiser (boolean usePrefixMapper) throws JAXBException { 65 jc = JAXBContext.newInstance( OPMFactory.packageList ); 66 this.usePrefixMapper=usePrefixMapper; 67 } 68 69 public OPMSerialiser (String packageList) throws JAXBException { 70 jc = JAXBContext.newInstance( packageList ); 71 usePrefixMapper=true; 72 } 73 public OPMSerialiser (boolean usePrefixMapper, String packageList) throws JAXBException { 74 jc = JAXBContext.newInstance( packageList ); 75 this.usePrefixMapper=usePrefixMapper; 76 } 77 78 public void configurePrefixes(Marshaller m) throws PropertyException { 79 if (usePrefixMapper) { 80 m.setProperty("com.sun.xml.bind.namespacePrefixMapper", 81 new NamespacePrefixMapper(defaultNamespace)); 82 } 83 } 84 85 public Document serialiseOPMGraph (OPMGraph request) throws JAXBException { 86 return (Document) serialiseOPMGraph (defaultEmptyDocument(), request); 87 } 88 89 public Node serialiseOPMGraph (Node addTo, OPMGraph graph) 90 throws JAXBException { 91 Marshaller m=jc.createMarshaller(); 92 m.marshal(of.createOpmGraph(graph),addTo); 93 return addTo; 94 } 95 public String serialiseOPMGraph (StringWriter sw, OPMGraph graph) 96 throws JAXBException { 97 Marshaller m=jc.createMarshaller(); 98 m.marshal(of.createOpmGraph(graph),sw); 99 return sw.toString(); 100 } 101 102 public String serialiseOPMGraph (StringWriter sw, OPMGraph graph, boolean format) 103 throws JAXBException { 104 Marshaller m=jc.createMarshaller(); 105 m.setProperty("jaxb.formatted.output",format); 106 configurePrefixes(m); 107 m.marshal(of.createOpmGraph(graph),sw); 108 return sw.toString(); 109 } 110 111 public void serialiseOPMGraph (File file, OPMGraph graph, boolean format) 112 throws JAXBException { 113 Marshaller m=jc.createMarshaller(); 114 m.setProperty("jaxb.formatted.output",format); 115 configurePrefixes(m); 116 m.marshal(of.createOpmGraph(graph),file); 117 } 118 119 /*** By default we use a document provided by the DocumentBuilder 120 factory. If this functionality is required, 121 PStructureSerialiser needs to be subclassed and the 122 defaultEmptyDocument method overriden. */ 123 124 public Document defaultEmptyDocument () { 125 return docBuilder.newDocument(); 126 } 127 128 129 130 131 } 132