source: ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/MDMarshaller.java @ 1860

Last change on this file since 1860 was 1860, checked in by twagoo, 12 years ago

ComponentRegistry REST service:

  • Using CMDValidate 1.1 (see r1859)
  • Moved anonymous LSResourceResolver implementation into its own class
  • Passing this class to CMDValidate validator
File size: 6.2 KB
Line 
1package clarin.cmdi.componentregistry;
2
3import clarin.cmdi.componentregistry.components.CMDComponentSpec;
4import java.io.ByteArrayInputStream;
5import java.io.ByteArrayOutputStream;
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.IOException;
9import java.io.InputStream;
10import java.io.OutputStream;
11import java.io.OutputStreamWriter;
12import java.io.UnsupportedEncodingException;
13import java.io.Writer;
14import java.net.MalformedURLException;
15import java.net.URL;
16import javax.xml.bind.JAXBContext;
17import javax.xml.bind.JAXBException;
18import javax.xml.bind.Marshaller;
19import javax.xml.bind.Unmarshaller;
20import javax.xml.transform.Templates;
21import javax.xml.transform.Transformer;
22import javax.xml.transform.TransformerConfigurationException;
23import javax.xml.transform.TransformerException;
24import javax.xml.transform.TransformerFactory;
25import javax.xml.transform.stream.StreamResult;
26import javax.xml.transform.stream.StreamSource;
27import javax.xml.validation.Schema;
28import javax.xml.validation.SchemaFactory;
29import org.apache.xml.resolver.tools.CatalogResolver;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32import org.w3c.dom.bootstrap.DOMImplementationRegistry;
33import org.w3c.dom.ls.DOMImplementationLS;
34import org.w3c.dom.ls.LSInput;
35import org.w3c.dom.ls.LSResourceResolver;
36import org.xml.sax.InputSource;
37import org.xml.sax.SAXException;
38
39public class MDMarshaller {
40
41    private final static Logger LOG = LoggerFactory.getLogger(MDMarshaller.class);
42    /**
43     * I define W3C_XML_SCHEMA_NS_URI here cannot get it from
44     *
45     * @see XMLConstants there is a conflict between stax-api and java5.
46     */
47    private static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
48    private static Schema generalComponentSchema;
49
50    private MDMarshaller() {
51    }
52
53    /**
54     * Helper method that logs errors and returns null if unmarshal failed
55     */
56    public static <T> T unmarshal(Class<T> docClass, File file, Schema schema) {
57        T result = null;
58        try {
59            result = unmarshal(docClass, new FileInputStream(file), schema);
60        } catch (JAXBException e) {
61            LOG.error("Cannot unmarshal xml file: " + file, e);
62        } catch (IOException e) {
63            LOG.error("Cannot retrieve content from file: " + file, e);
64        }
65        return result;
66    }
67
68    /**
69     *
70     * @param docClass
71     * @param inputStream
72     * @param schema to validate against, can be null for no validation.
73     * @return
74     * @throws JAXBException
75     */
76    public static <T> T unmarshal(Class<T> docClass, InputStream inputStream, Schema schema) throws JAXBException {
77        String packageName = docClass.getPackage().getName();
78        JAXBContext jc = JAXBContext.newInstance(packageName);
79        Unmarshaller u = jc.createUnmarshaller();
80
81        if (schema != null) {
82            u.setSchema(schema);
83        }
84        Object unmarshal = u.unmarshal(inputStream);
85        T doc = (T) unmarshal;
86        return doc;
87    }
88
89    /**
90     * Will wrap the Outputstream in a OutputStreamWriter with encoding set to UTF-8. This to make sure profiles are stored correctly.
91     */
92    public static <T> void marshal(T marshallableObject, OutputStream out) throws JAXBException, UnsupportedEncodingException {
93        String packageName = marshallableObject.getClass().getPackage().getName();
94        JAXBContext jc = JAXBContext.newInstance(packageName);
95
96        Marshaller m = jc.createMarshaller();
97        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
98        String schemaLocation = Configuration.getInstance().getSchemaLocation(marshallableObject.getClass().getName());
99        if (schemaLocation != null) {
100            m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
101        }
102        Writer writer = new OutputStreamWriter(out, "UTF-8");
103        m.marshal(marshallableObject, writer);
104    }
105
106    public static synchronized Schema getCMDComponentSchema() {
107        if (generalComponentSchema == null) {
108            try {
109                SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
110                schemaFactory.setResourceResolver(new ComponentRegistryResourceResolver());
111                generalComponentSchema = schemaFactory.newSchema(new URL(Configuration.getInstance().getGeneralComponentSchema()));
112            } catch (MalformedURLException e) {
113                LOG.error("Cannot instantiate schema", e);
114            } catch (SAXException e) {
115                LOG.error("Cannot instantiate schema", e);
116            }
117        }
118        return generalComponentSchema;
119    }
120
121    public static void generateXsd(CMDComponentSpec spec, OutputStream outputStream) {
122        Templates componentToSchemaTemplates;
123        try {
124            System.setProperty("javax.xml.transform.TransformerFactory", net.sf.saxon.TransformerFactoryImpl.class.getName());
125            componentToSchemaTemplates = TransformerFactory.newInstance().newTemplates(
126                    new StreamSource(Configuration.getInstance().getComponent2SchemaXsl()));
127        } catch (TransformerConfigurationException e) {
128            LOG.error("Cannot create Template", e);
129            return;
130        }
131        try {
132            Transformer transformer = componentToSchemaTemplates.newTransformer();
133            ByteArrayOutputStream out = new ByteArrayOutputStream();
134            MDMarshaller.marshal(spec, out);
135            ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());
136            transformer.transform(new StreamSource(input), new StreamResult(outputStream));
137        } catch (TransformerConfigurationException e) {
138            LOG.error("Cannot create Transformer", e);
139        } catch (TransformerException e) {
140            LOG.error("Cannot transform xml file: " + getSpecId(spec), e);
141        } catch (UnsupportedEncodingException e) {
142            LOG.error("Error in encoding: ", e);
143        } catch (JAXBException e) {
144            LOG.error("Cannot marshall spec: " + getSpecId(spec), e);
145        }
146    }
147
148    private static String getSpecId(CMDComponentSpec spec) {
149        String result = "";
150        if (spec != null && spec.getHeader() != null) {
151            result = spec.getHeader().getID();
152        }
153        return result;
154    }
155
156    /**
157     * @param marshallableObject
158     * @return the xml representation of the marshallableObject
159     * @throws jaxb exceptions are wrapped in RuntimeExceptions
160     */
161    public static <T> String marshalToString(T marshallableObject) {
162        ByteArrayOutputStream out = new ByteArrayOutputStream();
163        try {
164            marshal(marshallableObject, out);
165            return out.toString("UTF-8");
166        } catch (UnsupportedEncodingException e) {
167            throw new RuntimeException(e);
168        } catch (JAXBException e) {
169            throw new RuntimeException(e);
170        }
171    }
172}
Note: See TracBrowser for help on using the repository browser.