Autopsy  4.21.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
XMLUtil.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2012-2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.coreutils;
20 
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.OutputStreamWriter;
27 import java.io.UnsupportedEncodingException;
28 import java.nio.file.Paths;
29 import java.util.logging.Level;
30 import javax.xml.XMLConstants;
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.parsers.ParserConfigurationException;
34 import javax.xml.transform.OutputKeys;
35 import javax.xml.transform.Result;
36 import javax.xml.transform.Transformer;
37 import javax.xml.transform.TransformerConfigurationException;
38 import javax.xml.transform.TransformerException;
39 import javax.xml.transform.TransformerFactory;
40 import javax.xml.transform.dom.DOMResult;
41 import javax.xml.transform.dom.DOMSource;
42 import javax.xml.transform.stream.StreamResult;
43 import javax.xml.validation.Schema;
44 import javax.xml.validation.SchemaFactory;
45 import javax.xml.validation.Validator;
46 import org.w3c.dom.Document;
47 import org.xml.sax.SAXException;
48 
56 public class XMLUtil {
57 
58  static {
59  // this is to ensure using xalan for the transformer factory: https://stackoverflow.com/a/64364531/2375948
60  System.setProperty("javax.xml.transform.TransformerFactory","com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
61  }
62 
63  private static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
64  // See JIRA-6958 for details about class loading and jaxb.
65  ClassLoader original = Thread.currentThread().getContextClassLoader();
66  try {
67  Thread.currentThread().setContextClassLoader(XMLUtil.class.getClassLoader());
68  DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
69  return builderFactory.newDocumentBuilder();
70  } finally {
71  Thread.currentThread().setContextClassLoader(original);
72  }
73  }
74 
75  private static SchemaFactory getSchemaFactory(String schemaLanguage) {
76  return SchemaFactory.newInstance(schemaLanguage);
77  }
78 
79  private static TransformerFactory getTransformerFactory() {
80  // See JIRA-6958 for details about class loading and jaxb.
81  ClassLoader original = Thread.currentThread().getContextClassLoader();
82  try {
83  Thread.currentThread().setContextClassLoader(XMLUtil.class.getClassLoader());
84  return TransformerFactory.newInstance();
85  } finally {
86  Thread.currentThread().setContextClassLoader(original);
87  }
88  }
89 
97  public static Document createDocument() throws ParserConfigurationException {
98  return getDocumentBuilder().newDocument();
99  }
100 
115  public static <T> Document loadDocument(String docPath, Class<T> clazz, String schemaResourceName) throws IOException, ParserConfigurationException, SAXException {
116  Document doc = loadDocument(docPath);
117  validateDocument(doc, clazz, schemaResourceName);
118  return doc;
119  }
120 
132  public static Document loadDocument(String docPath) throws ParserConfigurationException, SAXException, IOException {
133  DocumentBuilder builder = getDocumentBuilder();
134  Document doc = builder.parse(new FileInputStream(docPath));
135  return doc;
136  }
137 
148  public static <T> void validateDocument(final Document doc, Class<T> clazz, String schemaResourceName) throws SAXException, IOException {
149  PlatformUtil.extractResourceToUserConfigDir(clazz, schemaResourceName, false);
150  File schemaFile = new File(Paths.get(PlatformUtil.getUserConfigDirectory(), schemaResourceName).toAbsolutePath().toString());
151  SchemaFactory schemaFactory = getSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI);
152  Schema schema = schemaFactory.newSchema(schemaFile);
153  Validator validator = schema.newValidator();
154  validator.validate(new DOMSource(doc), new DOMResult());
155  }
156 
171  public static void saveDocument(final Document doc, String encoding, String docPath) throws TransformerConfigurationException, FileNotFoundException, UnsupportedEncodingException, TransformerException, IOException {
172  TransformerFactory xf = getTransformerFactory();
173  xf.setAttribute("indent-number", 1); //NON-NLS
174  Transformer xformer = xf.newTransformer();
175  xformer.setOutputProperty(OutputKeys.METHOD, "xml"); //NON-NLS
176  xformer.setOutputProperty(OutputKeys.INDENT, "yes"); //NON-NLS
177  xformer.setOutputProperty(OutputKeys.ENCODING, encoding);
178  xformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); //NON-NLS
179  xformer.setOutputProperty(OutputKeys.VERSION, "1.0");
180  File file = new File(docPath);
181  try (FileOutputStream stream = new FileOutputStream(file)) {
182  Result out = new StreamResult(new OutputStreamWriter(stream, encoding));
183  xformer.transform(new DOMSource(doc), out);
184  stream.flush();
185  }
186  }
187 
205  // TODO: Deprecate.
206  public static <T> boolean xmlIsValid(DOMSource xmlfile, Class<T> clazz, String schemaFile) {
207  try {
208  PlatformUtil.extractResourceToUserConfigDir(clazz, schemaFile, false);
209  File schemaLoc = new File(PlatformUtil.getUserConfigDirectory() + File.separator + schemaFile);
210  SchemaFactory schm = getSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI);
211  try {
212  Schema schema = schm.newSchema(schemaLoc);
213  Validator validator = schema.newValidator();
214  DOMResult result = new DOMResult();
215  validator.validate(xmlfile, result);
216  return true;
217  } catch (SAXException e) {
218  Logger.getLogger(clazz.getName()).log(Level.WARNING, "Unable to validate XML file.", e); //NON-NLS
219  return false;
220  }
221  } catch (IOException e) {
222  Logger.getLogger(clazz.getName()).log(Level.WARNING, "Unable to load XML file [" + xmlfile.toString() + "] of type [" + schemaFile + "]", e); //NON-NLS
223  return false;
224  }
225  }
226 
244  // TODO: Deprecate.
245  public static <T> boolean xmlIsValid(Document doc, Class<T> clazz, String type) {
246  DOMSource dms = new DOMSource(doc);
247  return xmlIsValid(dms, clazz, type);
248  }
249 
256  // TODO: Deprecate.
257  public static <T> Document loadDoc(Class<T> clazz, String xmlPath) {
258  Document ret = null;
259  try {
260  DocumentBuilder builder = getDocumentBuilder();
261  ret = builder.parse(new FileInputStream(xmlPath));
262  } catch (ParserConfigurationException e) {
263  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error loading XML file " + xmlPath + " : can't initialize parser.", e); //NON-NLS
264  } catch (SAXException e) {
265  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error loading XML file " + xmlPath + " : can't parse XML.", e); //NON-NLS
266  } catch (IOException e) {
267  //error reading file
268  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error loading XML file " + xmlPath + " : can't read file.", e); //NON-NLS
269  }
270  return ret;
271  }
272 
280  // TODO: Deprecate
281  public static <T> Document loadDoc(Class<T> clazz, String xmlPath, String xsdPath) {
282  Document ret = loadDoc(clazz, xmlPath);
283  if (!XMLUtil.xmlIsValid(ret, clazz, xsdPath)) {
284  Logger.getLogger(clazz.getName()).log(Level.WARNING, "Error loading XML file: could not validate against [{0}], results may not be accurate", xsdPath); //NON-NLS
285  }
286  return ret;
287  }
288 
297  // TODO: Deprecate.
298  public static <T> boolean saveDoc(Class<T> clazz, String xmlPath, String encoding, final Document doc) {
299  TransformerFactory xf = getTransformerFactory();
300  xf.setAttribute("indent-number", 1); //NON-NLS
301  boolean success = false;
302  try {
303  Transformer xformer = xf.newTransformer();
304  xformer.setOutputProperty(OutputKeys.METHOD, "xml"); //NON-NLS
305  xformer.setOutputProperty(OutputKeys.INDENT, "yes"); //NON-NLS
306  xformer.setOutputProperty(OutputKeys.ENCODING, encoding);
307  xformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); //NON-NLS
308  xformer.setOutputProperty(OutputKeys.VERSION, "1.0");
309  File file = new File(xmlPath);
310  try (FileOutputStream stream = new FileOutputStream(file)) {
311  Result out = new StreamResult(new OutputStreamWriter(stream, encoding));
312  xformer.transform(new DOMSource(doc), out);
313  stream.flush();
314  }
315  success = true;
316 
317  } catch (UnsupportedEncodingException e) {
318  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Should not happen", e); //NON-NLS
319  } catch (TransformerConfigurationException e) {
320  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error writing XML file", e); //NON-NLS
321  } catch (TransformerException e) {
322  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error writing XML file", e); //NON-NLS
323  } catch (FileNotFoundException e) {
324  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error writing XML file: cannot write to file: " + xmlPath, e); //NON-NLS
325  } catch (IOException e) {
326  Logger.getLogger(clazz.getName()).log(Level.SEVERE, "Error writing XML file: cannot write to file: " + xmlPath, e); //NON-NLS
327  }
328  return success;
329  }
330 
331 }
static< T > Document loadDoc(Class< T > clazz, String xmlPath)
Definition: XMLUtil.java:257
static TransformerFactory getTransformerFactory()
Definition: XMLUtil.java:79
static< T > Document loadDoc(Class< T > clazz, String xmlPath, String xsdPath)
Definition: XMLUtil.java:281
static SchemaFactory getSchemaFactory(String schemaLanguage)
Definition: XMLUtil.java:75
static< T > boolean xmlIsValid(Document doc, Class< T > clazz, String type)
Definition: XMLUtil.java:245
static< T > void validateDocument(final Document doc, Class< T > clazz, String schemaResourceName)
Definition: XMLUtil.java:148
static< T > boolean extractResourceToUserConfigDir(final Class< T > resourceClass, final String resourceFileName, boolean overWrite)
static< T > Document loadDocument(String docPath, Class< T > clazz, String schemaResourceName)
Definition: XMLUtil.java:115
static< T > boolean xmlIsValid(DOMSource xmlfile, Class< T > clazz, String schemaFile)
Definition: XMLUtil.java:206
static Document loadDocument(String docPath)
Definition: XMLUtil.java:132
static void saveDocument(final Document doc, String encoding, String docPath)
Definition: XMLUtil.java:171
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static DocumentBuilder getDocumentBuilder()
Definition: XMLUtil.java:63
static< T > boolean saveDoc(Class< T > clazz, String xmlPath, String encoding, final Document doc)
Definition: XMLUtil.java:298

Copyright © 2012-2024 Sleuth Kit Labs. Generated on: Mon Mar 17 2025
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.