Clean up logging system
[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.getLogger(RunnerConfigMarshaller.class);\r
50 \r
51         private final JAXBContext ctx;\r
52 \r
53         @SuppressWarnings("all")\r
54         public RunnerConfigMarshaller(Class<?> rootClass) throws JAXBException {\r
55                 this(rootClass, null);\r
56         }\r
57 \r
58         public RunnerConfigMarshaller(Class<?> rootClass, Class<?>... classes)\r
59                         throws JAXBException {\r
60 \r
61                 if (classes != null) {\r
62                         List<Class<?>> classesList = new ArrayList<Class<?>>(\r
63                                         Arrays.asList(classes));\r
64                         classesList.add(rootClass);\r
65                         ctx = JAXBContext.newInstance(classesList.toArray(new Class<?>[0]));\r
66                 } else {\r
67                         ctx = JAXBContext.newInstance(rootClass);\r
68                 }\r
69         }\r
70 \r
71         public void write(Object xmlRootElement, OutputStream out)\r
72                         throws JAXBException, IOException {\r
73                 Marshaller marsh = ctx.createMarshaller();\r
74                 marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r
75                 // disable validation\r
76                 marsh.setSchema(null);\r
77                 marsh.marshal(xmlRootElement, out);\r
78         }\r
79 \r
80         public void writeAndValidate(Object xmlRootElement, String schemafile,\r
81                         OutputStream out) throws JAXBException, IOException, SAXException {\r
82                 Marshaller marsh = ctx.createMarshaller();\r
83                 marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r
84                 marsh.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION,\r
85                                 schemafile);\r
86                 marsh.setSchema(getSchema(schemafile));\r
87                 marsh.marshal(xmlRootElement, out);\r
88         }\r
89 \r
90         void generateSchema(String directoryForSchema, String schemaName)\r
91                         throws JAXBException, IOException {\r
92 \r
93                 Marshaller marsh = ctx.createMarshaller();\r
94                 marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\r
95                 ctx.generateSchema(new MySchemaOutputResolver(directoryForSchema,\r
96                                 schemaName));\r
97         }\r
98 \r
99         public static Schema getSchema(String schemafile) throws SAXException {\r
100                 // define the type of schema - we use W3C:\r
101                 String schemaLang = "http://www.w3.org/2001/XMLSchema";\r
102                 // get validation driver:\r
103                 SchemaFactory factory = SchemaFactory.newInstance(schemaLang);\r
104                 // create schema by reading it from an XSD file:\r
105                 Schema schema = factory.newSchema(new StreamSource(schemafile));\r
106                 return schema;\r
107         }\r
108 \r
109         /**\r
110          * \r
111          * @return validator instance\r
112          * @throws SAXException\r
113          */\r
114         public static Validator getValidator(String schemafile) throws SAXException {\r
115                 Schema schema = getSchema(schemafile);\r
116                 Validator validator = schema.newValidator();\r
117                 return validator;\r
118         }\r
119 \r
120         public static Validator getValidator(Schema schema) throws SAXException {\r
121                 Validator validator = schema.newValidator();\r
122                 return validator;\r
123         }\r
124 \r
125         public static boolean validate(Validator validator, String document)\r
126                         throws IOException, SAXException {\r
127                 try {\r
128                         // at last perform validation:\r
129                         validator.validate(new StreamSource(document));\r
130                 } catch (SAXException ex) {\r
131                         ex.printStackTrace();\r
132                         log.warn("SAXException validating xml" + ex.getMessage());\r
133                         // we are here if the document is not valid:\r
134                         // ... process validation error...\r
135                         return false;\r
136                 }\r
137                 return true;\r
138         }\r
139 \r
140         public <V> V readAndValidate(InputStream document, Class<V> resultElemType)\r
141                         throws JAXBException, IOException, SAXException {\r
142 \r
143                 String schemaFile = Long.toHexString(System.nanoTime());\r
144                 generateSchema(SysPrefs.getSystemTmpDir(), schemaFile);\r
145 \r
146                 Unmarshaller um = ctx.createUnmarshaller();\r
147                 um.setSchema(getSchema(SysPrefs.getSystemTmpDir() + File.separator\r
148                                 + schemaFile));\r
149 \r
150                 JAXBElement<V> rconfig = um.unmarshal(new StreamSource(document),\r
151                                 resultElemType);\r
152                 return rconfig.getValue();\r
153         }\r
154 \r
155         static class MySchemaOutputResolver extends SchemaOutputResolver {\r
156                 final String dir;\r
157                 final String sname;\r
158 \r
159                 public MySchemaOutputResolver(String directory, String suggestedFileName) {\r
160                         this.dir = directory;\r
161                         this.sname = suggestedFileName;\r
162                 }\r
163 \r
164                 @Override\r
165                 public Result createOutput(String namespaceUri, String suggestedFileName)\r
166                                 throws IOException {\r
167                         return new StreamResult(new File(dir, this.sname));\r
168                 }\r
169         }\r
170 \r
171         @SuppressWarnings("all")\r
172         public <V> V read(InputStream instream, Class<V> resultElemType)\r
173                         throws JAXBException {\r
174                 return read(instream, resultElemType, null);\r
175         }\r
176 \r
177         public <V> V read(InputStream instream, Class<V> resultElemType,\r
178                         Class<?>... classes) throws JAXBException {\r
179                 if (instream == null) {\r
180                         throw new NullPointerException("Input stream must be provided!");\r
181                 }\r
182                 JAXBContext ctx = null;\r
183                 if (classes != null) {\r
184                         List<Class<?>> classesList = new ArrayList<Class<?>>(\r
185                                         Arrays.asList(classes));\r
186                         classesList.add(resultElemType);\r
187                         ctx = JAXBContext.newInstance(classesList.toArray(new Class<?>[0]));\r
188                 } else {\r
189                         ctx = JAXBContext.newInstance(resultElemType);\r
190                 }\r
191 \r
192                 Unmarshaller um = ctx.createUnmarshaller();\r
193                 JAXBElement<V> rconfig = um.unmarshal(new StreamSource(instream),\r
194                                 resultElemType);\r
195 \r
196                 return rconfig.getValue();\r
197         }\r
198 \r
199 }\r