570b43c8dd5fefbd5bc46095c59f85a5ee5ea120
[jabaws.git] / engine / compbio / engine / conf / RunnerConfigMarshaller.java
1 /* Copyright (c) 2009 Peter Troshin\r
2  *  \r
3  *  JAva Bioinformatics Analysis Web Services (JABAWS) @version: 1.0     \r
4  * \r
5  *  This library is free software; you can redistribute it and/or modify it under the terms of the\r
6  *  Apache License version 2 as published by the Apache Software Foundation\r
7  * \r
8  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r
9  *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache \r
10  *  License for more details.\r
11  * \r
12  *  A copy of the license is in apache_license.txt. It is also available here:\r
13  * @see: http://www.apache.org/licenses/LICENSE-2.0.txt\r
14  * \r
15  * Any republication or derived work distributed in source code form\r
16  * must include this copyright and license notice.\r
17  */\r
18 \r
19 package compbio.engine.conf;\r
20 \r
21 import java.io.File;\r
22 import java.io.IOException;\r
23 import java.io.InputStream;\r
24 import java.io.OutputStream;\r
25 import java.util.ArrayList;\r
26 import java.util.Arrays;\r
27 import java.util.List;\r
28 \r
29 import javax.xml.bind.JAXBContext;\r
30 import javax.xml.bind.JAXBElement;\r
31 import javax.xml.bind.JAXBException;\r
32 import javax.xml.bind.Marshaller;\r
33 import javax.xml.bind.SchemaOutputResolver;\r
34 import javax.xml.bind.Unmarshaller;\r
35 import javax.xml.transform.Result;\r
36 import javax.xml.transform.stream.StreamResult;\r
37 import javax.xml.transform.stream.StreamSource;\r
38 import javax.xml.validation.Schema;\r
39 import javax.xml.validation.SchemaFactory;\r
40 import javax.xml.validation.Validator;\r
41 \r
42 import org.apache.log4j.Logger;\r
43 import org.xml.sax.SAXException;\r
44 \r
45 import compbio.util.SysPrefs;\r
46 \r
47 public class RunnerConfigMarshaller<T> {\r
48 \r
49         private static final Logger log = Logger\r
50                         .getLogger(RunnerConfigMarshaller.class);\r
51 \r
52         private final JAXBContext ctx;\r
53 \r
54         @SuppressWarnings("all")\r
55         public RunnerConfigMarshaller(Class<?> rootClass) throws JAXBException {\r
56                 this(rootClass, null);\r
57         }\r
58 \r
59         public RunnerConfigMarshaller(Class<?> rootClass, Class<?>... classes)\r
60                         throws JAXBException {\r
61 \r
62                 if (classes != null) {\r
63                         List<Class<?>> classesList = new ArrayList<Class<?>>(Arrays\r
64                                         .asList(classes));\r
65                         classesList.add(rootClass);\r
66                         ctx = JAXBContext.newInstance(classesList.toArray(new Class<?>[0]));\r
67                 } else {\r
68                         ctx = JAXBContext.newInstance(rootClass);\r
69                 }\r
70         }\r
71 \r
72         public void write(Object xmlRootElement, OutputStream out)\r
73                         throws JAXBException, IOException {\r
74                 Marshaller marsh = ctx.createMarshaller();\r
75                 marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r
76                 // disable validation\r
77                 marsh.setSchema(null);\r
78                 marsh.marshal(xmlRootElement, out);\r
79         }\r
80 \r
81         public void writeAndValidate(Object xmlRootElement, String schemafile,\r
82                         OutputStream out) throws JAXBException, IOException, SAXException {\r
83                 Marshaller marsh = ctx.createMarshaller();\r
84                 marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r
85                 marsh.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION,\r
86                                 schemafile);\r
87                 marsh.setSchema(getSchema(schemafile));\r
88                 marsh.marshal(xmlRootElement, out);\r
89         }\r
90 \r
91         void generateSchema(String directoryForSchema, String schemaName)\r
92                         throws JAXBException, IOException {\r
93 \r
94                 Marshaller marsh = ctx.createMarshaller();\r
95                 marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r
96                 ctx.generateSchema(new MySchemaOutputResolver(directoryForSchema,\r
97                                 schemaName));\r
98         }\r
99 \r
100         public static Schema getSchema(String schemafile) throws SAXException {\r
101                 // define the type of schema - we use W3C:\r
102                 String schemaLang = "http://www.w3.org/2001/XMLSchema";\r
103                 // get validation driver:\r
104                 SchemaFactory factory = SchemaFactory.newInstance(schemaLang);\r
105                 // create schema by reading it from an XSD file:\r
106                 Schema schema = factory.newSchema(new StreamSource(schemafile));\r
107                 return schema;\r
108         }\r
109 \r
110         /**\r
111          * \r
112          * @return\r
113          * @throws SAXException\r
114          */\r
115         public static Validator getValidator(String schemafile) throws SAXException {\r
116                 Schema schema = getSchema(schemafile);\r
117                 Validator validator = schema.newValidator();\r
118                 return validator;\r
119         }\r
120 \r
121         public static Validator getValidator(Schema schema) throws SAXException {\r
122                 Validator validator = schema.newValidator();\r
123                 return validator;\r
124         }\r
125 \r
126         public static boolean validate(Validator validator, String document)\r
127                         throws IOException, SAXException {\r
128                 try {\r
129                         // at last perform validation:\r
130                         validator.validate(new StreamSource(document));\r
131                 } catch (SAXException ex) {\r
132                         ex.printStackTrace();\r
133                         log.warn("SAXException validating xml" + ex.getMessage());\r
134                         // we are here if the document is not valid:\r
135                         // ... process validation error...\r
136                         return false;\r
137                 }\r
138                 return true;\r
139         }\r
140 \r
141         public <V> V readAndValidate(InputStream document, Class<V> resultElemType)\r
142                         throws JAXBException, IOException, SAXException {\r
143 \r
144                 String schemaFile = Long.toHexString(System.nanoTime());\r
145                 generateSchema(SysPrefs.getSystemTmpDir(), schemaFile);\r
146 \r
147                 Unmarshaller um = ctx.createUnmarshaller();\r
148                 um.setSchema(getSchema(SysPrefs.getSystemTmpDir() + File.separator\r
149                                 + schemaFile));\r
150 \r
151                 JAXBElement<V> rconfig = um.unmarshal(new StreamSource(document),\r
152                                 resultElemType);\r
153                 return rconfig.getValue();\r
154         }\r
155 \r
156         static class MySchemaOutputResolver extends SchemaOutputResolver {\r
157                 final String dir;\r
158                 final String sname;\r
159 \r
160                 public MySchemaOutputResolver(String directory, String suggestedFileName) {\r
161                         this.dir = directory;\r
162                         this.sname = suggestedFileName;\r
163                 }\r
164 \r
165                 @Override\r
166                 public Result createOutput(String namespaceUri, String suggestedFileName)\r
167                                 throws IOException {\r
168                         return new StreamResult(new File(dir, this.sname));\r
169                 }\r
170         }\r
171 \r
172         @SuppressWarnings("all")\r
173         public <V> V read(InputStream instream, Class<V> resultElemType)\r
174                         throws JAXBException {\r
175                 return read(instream, resultElemType, null);\r
176         }\r
177 \r
178         public <V> V read(InputStream instream, Class<V> resultElemType,\r
179                         Class<?>... classes) throws JAXBException {\r
180                 if (instream == null) {\r
181                         throw new NullPointerException("Input stream must be provided!");\r
182                 }\r
183                 JAXBContext ctx = null;\r
184                 if (classes != null) {\r
185                         List<Class<?>> classesList = new ArrayList<Class<?>>(Arrays\r
186                                         .asList(classes));\r
187                         classesList.add(resultElemType);\r
188                         ctx = JAXBContext.newInstance(classesList.toArray(new Class<?>[0]));\r
189                 } else {\r
190                         ctx = JAXBContext.newInstance(resultElemType);\r
191                 }\r
192 \r
193                 Unmarshaller um = ctx.createUnmarshaller();\r
194                 JAXBElement<V> rconfig = um.unmarshal(new StreamSource(instream),\r
195                                 resultElemType);\r
196 \r
197                 return rconfig.getValue();\r
198         }\r
199 \r
200 }\r