fix the jaxb import/export
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / jaxb / CdmDocumentBuilder.java
1 /**
2 * Copyright (C) 2008 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.cdm.io.jaxb;
11
12 import java.io.File;
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;
20
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;
35
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;
41
42 import eu.etaxonomy.cdm.jaxb.CdmNamespacePrefixMapper;
43 import eu.etaxonomy.cdm.jaxb.FormattedText;
44 import eu.etaxonomy.cdm.jaxb.MultilanguageTextElement;
45
46 /**
47 * Initializes a JaxbContext with one class (eu.etaxonomy.cdm.model.DataSet).
48 *
49 * @author a.babadshanjan, ben.clark
50 */
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 {
55
56 private static final Logger logger = Logger.getLogger(CdmDocumentBuilder.class);
57
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;
65
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};
79
80 protected String[] getSchemaFiles() {
81 return CDM_SCHEMA_FILES;
82 }
83
84 protected Class[] getContextClasses() {
85 return CONTEXT_CLASSES;
86 }
87
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();
92
93 Source[] sources = new Source[schemaFiles.length];
94
95 for(int i = 0; i < schemaFiles.length; i++) {
96 String schemaName = schemaFiles[i];
97 sources[i] = new StreamSource(this.getClass().getResourceAsStream(schemaName));
98 }
99
100 schema = schemaFactory.newSchema(sources);
101 }
102
103 protected void constructUnmarshaller() throws ParserConfigurationException, SAXException, JAXBException {
104 unmarshaller = jaxbContext.createUnmarshaller();
105 unmarshaller.setSchema(schema);
106
107 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
108
109 saxParserFactory.setNamespaceAware(true);
110 saxParserFactory.setXIncludeAware(true);
111 saxParserFactory.setValidating(true);
112
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());
120 }
121
122 public CdmDocumentBuilder() throws SAXException, JAXBException, IOException, ParserConfigurationException {
123 constructSchema();
124
125 jaxbContext = JAXBContext.newInstance(getContextClasses());
126
127 constructUnmarshaller();
128 constructMarshaller();
129 }
130
131 protected void constructMarshaller() throws JAXBException {
132 marshaller = jaxbContext.createMarshaller();
133 marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new CdmNamespacePrefixMapper() );
134 marshaller.setSchema(schema);
135
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);
141
142 CdmMarshallerListener marshallerListener = new CdmMarshallerListener();
143 marshaller.setListener(marshallerListener);
144 marshaller.setEventHandler(new WarningTolerantValidationEventHandler());
145 System.out.println(marshaller.toString());
146
147 }
148
149 public CdmDocumentBuilder(boolean formattedOutput, String encoding) throws SAXException, JAXBException, IOException, ParserConfigurationException {
150 this.formattedOutput = formattedOutput;
151 this.encoding = encoding;
152 constructSchema();
153
154 jaxbContext = JAXBContext.newInstance(getContextClasses());
155
156 constructUnmarshaller();
157 constructMarshaller();
158 }
159
160 public void marshal(DataSet dataSet, Writer writer) throws JAXBException {
161
162 logger.info("Start marshalling");
163 marshaller.marshal(dataSet, writer);
164
165 }
166
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);
172 return t;
173 }
174
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);
181 return t;
182 }
183
184 public <T> T unmarshal(Class<T> clazz, File file) throws JAXBException, UnsupportedEncodingException, FileNotFoundException {
185
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);
191 return t;
192
193 }
194
195 public void marshal(DataSet dataSet, SAXResult result) throws JAXBException {
196 logger.info("Start marshalling");
197 marshaller.marshal(dataSet, result);
198
199 }
200
201 // public void marshal(DataSet dataSet, File file) throws JAXBException {
202 // marshaller.marshal(dataSet, file);
203 // }
204
205 }
206
207