2 * Copyright (C) 2008 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.io
.jaxb
;
13 import java
.io
.FileInputStream
;
14 import java
.io
.FileNotFoundException
;
15 import java
.io
.IOException
;
16 import java
.io
.InputStreamReader
;
17 import java
.io
.Reader
;
18 import java
.io
.UnsupportedEncodingException
;
19 import java
.io
.Writer
;
21 import javax
.xml
.XMLConstants
;
22 import javax
.xml
.bind
.JAXBContext
;
23 import javax
.xml
.bind
.JAXBException
;
24 import javax
.xml
.bind
.Marshaller
;
25 import javax
.xml
.bind
.Unmarshaller
;
26 import javax
.xml
.parsers
.ParserConfigurationException
;
27 import javax
.xml
.parsers
.SAXParser
;
28 import javax
.xml
.parsers
.SAXParserFactory
;
29 import javax
.xml
.transform
.Source
;
30 import javax
.xml
.transform
.sax
.SAXResult
;
31 import javax
.xml
.transform
.sax
.SAXSource
;
32 import javax
.xml
.transform
.stream
.StreamSource
;
33 import javax
.xml
.validation
.Schema
;
34 import javax
.xml
.validation
.SchemaFactory
;
36 import org
.apache
.log4j
.Logger
;
37 import org
.apache
.xml
.resolver
.tools
.CatalogResolver
;
38 import org
.xml
.sax
.InputSource
;
39 import org
.xml
.sax
.SAXException
;
40 import org
.xml
.sax
.XMLReader
;
42 import eu
.etaxonomy
.cdm
.jaxb
.CdmNamespacePrefixMapper
;
43 import eu
.etaxonomy
.cdm
.jaxb
.FormattedText
;
44 import eu
.etaxonomy
.cdm
.jaxb
.MultilanguageTextElement
;
47 * Initializes a JaxbContext with one class (eu.etaxonomy.cdm.model.DataSet).
49 * @author a.babadshanjan, ben.clark
51 //Binds it to XML schemas found in /src/main/resources/schema/cdm (cdm.xsd, common.xsd, name.xsd).
52 //There is a bit of magic with a resource resolver in eu.etaxonomy.cdm.io.jaxb
53 //which allows to package the schemas into a jar file.
54 public class CdmDocumentBuilder
{
56 private static final Logger logger
= Logger
.getLogger(CdmDocumentBuilder
.class);
58 private JAXBContext jaxbContext
;
59 private boolean formattedOutput
= Boolean
.TRUE
;
60 private String encoding
= "UTF-8";
61 private Schema schema
;
62 private Marshaller marshaller
;
63 private Unmarshaller unmarshaller
;
64 private XMLReader xmlReader
;
66 public static String CDM_NAMESPACE
= "eu.etaxonomy.cdm.model";
67 public static String
[] CDM_SCHEMA_FILES
= { "/schema/cdm/agent.xsd",
68 "/schema/cdm/cdm.xsd",
69 "/schema/cdm/common.xsd",
70 "/schema/cdm/description.xsd",
71 "/schema/cdm/location.xsd",
72 "/schema/cdm/media.xsd",
73 "/schema/cdm/molecular.xsd",
74 "/schema/cdm/name.xsd",
75 "/schema/cdm/occurrence.xsd",
76 "/schema/cdm/reference.xsd",
77 "/schema/cdm/taxon.xsd"};
78 public static Class
[] CONTEXT_CLASSES
= {DataSet
.class,FormattedText
.class,MultilanguageTextElement
.class};
80 protected String
[] getSchemaFiles() {
81 return CDM_SCHEMA_FILES
;
84 protected Class
[] getContextClasses() {
85 return CONTEXT_CLASSES
;
88 protected void constructSchema() throws IOException
, SAXException
{
89 SchemaFactory schemaFactory
= SchemaFactory
.newInstance(XMLConstants
.W3C_XML_SCHEMA_NS_URI
);
90 schemaFactory
.setResourceResolver(new CdmResourceResolver());
91 String
[] schemaFiles
= getSchemaFiles();
93 Source
[] sources
= new Source
[schemaFiles
.length
];
95 for(int i
= 0; i
< schemaFiles
.length
; i
++) {
96 String schemaName
= schemaFiles
[i
];
97 sources
[i
] = new StreamSource(this.getClass().getResourceAsStream(schemaName
));
100 schema
= schemaFactory
.newSchema(sources
);
103 protected void constructUnmarshaller() throws ParserConfigurationException
, SAXException
, JAXBException
{
104 unmarshaller
= jaxbContext
.createUnmarshaller();
105 unmarshaller
.setSchema(schema
);
107 SAXParserFactory saxParserFactory
= SAXParserFactory
.newInstance();
109 saxParserFactory
.setNamespaceAware(true);
110 saxParserFactory
.setXIncludeAware(true);
111 saxParserFactory
.setValidating(true);
113 SAXParser saxParser
= saxParserFactory
.newSAXParser();
114 saxParser
.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
115 "http://www.w3.org/2001/XMLSchema");
116 xmlReader
= saxParser
.getXMLReader();
117 xmlReader
.setEntityResolver(new CatalogResolver());
118 xmlReader
.setErrorHandler(new DefaultErrorHandler());
119 unmarshaller
.setEventHandler(new WarningTolerantValidationEventHandler());
122 public CdmDocumentBuilder() throws SAXException
, JAXBException
, IOException
, ParserConfigurationException
{
125 jaxbContext
= JAXBContext
.newInstance(getContextClasses());
127 constructUnmarshaller();
128 constructMarshaller();
131 protected void constructMarshaller() throws JAXBException
{
132 marshaller
= jaxbContext
.createMarshaller();
133 marshaller
.setProperty("com.sun.xml.bind.namespacePrefixMapper", new CdmNamespacePrefixMapper() );
134 marshaller
.setSchema(schema
);
136 // For test purposes insert newlines to make the XML output readable
137 marshaller
.setProperty(Marshaller
.JAXB_FORMATTED_OUTPUT
, formattedOutput
);
138 // marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,"http://etaxonomy.eu/cdm/model/1.0 schema/cdm/cdm.xsd");
139 //marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,"http://etaxonomy.eu/cdm/model/1.0 cdm.xsd");
140 marshaller
.setProperty(Marshaller
.JAXB_ENCODING
, encoding
);
142 CdmMarshallerListener marshallerListener
= new CdmMarshallerListener();
143 marshaller
.setListener(marshallerListener
);
144 marshaller
.setEventHandler(new WarningTolerantValidationEventHandler());
145 System
.out
.println(marshaller
.toString());
149 public CdmDocumentBuilder(boolean formattedOutput
, String encoding
) throws SAXException
, JAXBException
, IOException
, ParserConfigurationException
{
150 this.formattedOutput
= formattedOutput
;
151 this.encoding
= encoding
;
154 jaxbContext
= JAXBContext
.newInstance(getContextClasses());
156 constructUnmarshaller();
157 constructMarshaller();
160 public void marshal(DataSet dataSet
, Writer writer
) throws JAXBException
{
162 logger
.info("Start marshalling");
163 marshaller
.marshal(dataSet
, writer
);
167 public <T
> T
unmarshal(Class
<T
> clazz
,Reader reader
) throws JAXBException
{
168 InputSource input
= new InputSource(reader
);
169 SAXSource saxSource
= new SAXSource( xmlReader
, input
);
170 logger
.info("Start unmarshalling");
171 T t
= (T
) unmarshaller
.unmarshal(saxSource
);
175 public <T
> T
unmarshal(Class
<T
> clazz
,Reader reader
, String systemId
) throws JAXBException
{
176 InputSource input
= new InputSource(reader
);
177 input
.setSystemId(systemId
);
178 SAXSource saxSource
= new SAXSource( xmlReader
, input
);
179 logger
.info("Start unmarshalling");
180 T t
= (T
) unmarshaller
.unmarshal(saxSource
);
184 public <T
> T
unmarshal(Class
<T
> clazz
, File file
) throws JAXBException
, UnsupportedEncodingException
, FileNotFoundException
{
186 InputSource input
= new InputSource(new InputStreamReader(new FileInputStream(file
),encoding
));
187 input
.setSystemId(file
.toURI().toString());
188 SAXSource saxSource
= new SAXSource( xmlReader
, input
);
189 logger
.info("Start unmarshalling");
190 T t
= (T
) unmarshaller
.unmarshal(saxSource
);
195 public void marshal(DataSet dataSet
, SAXResult result
) throws JAXBException
{
196 logger
.info("Start marshalling");
197 marshaller
.marshal(dataSet
, result
);
201 // public void marshal(DataSet dataSet, File file) throws JAXBException {
202 // marshaller.marshal(dataSet, file);