19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.io.BufferedWriter;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.OutputStreamWriter;
26 import java.io.StringWriter;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.ArrayList;
30 import java.util.List;
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.Source;
37 import javax.xml.transform.Transformer;
38 import javax.xml.transform.TransformerException;
39 import javax.xml.transform.TransformerFactory;
40 import javax.xml.transform.dom.DOMSource;
41 import javax.xml.transform.stream.StreamResult;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46 import org.w3c.dom.NodeList;
47 import org.xml.sax.SAXException;
54 private final Path metadataFilePath;
55 private final Path caseDirectoryPath;
56 private final static String METADATA_FILE_NAME =
"SolrCore.properties";
57 private final static String ROOT_ELEMENT_NAME =
"SolrCores";
58 private final static String CORE_ELEMENT_NAME =
"Core";
59 private final static String CORE_NAME_ELEMENT_NAME =
"CoreName";
60 private final static String SCHEMA_VERSION_ELEMENT_NAME =
"SchemaVersion";
61 private final static String SOLR_VERSION_ELEMENT_NAME =
"SolrVersion";
62 private final static String TEXT_INDEX_PATH_ELEMENT_NAME =
"TextIndexPath";
63 private List<Index> indexes =
new ArrayList<>();
64 private final UNCPathUtilities uncPathUtilities =
new UNCPathUtilities();
66 IndexMetadata(String caseDirectory, Index index)
throws TextIndexMetadataException {
67 this.metadataFilePath = Paths.get(caseDirectory, METADATA_FILE_NAME);
68 this.caseDirectoryPath = Paths.get(uncPathUtilities.convertPathToUNC(caseDirectory));
69 this.indexes.add(index);
73 IndexMetadata(String caseDirectory, List<Index> indexes)
throws TextIndexMetadataException {
75 this.metadataFilePath = Paths.get(caseDirectory, METADATA_FILE_NAME);
76 this.caseDirectoryPath = Paths.get(uncPathUtilities.convertPathToUNC(caseDirectory));
77 this.indexes = indexes;
90 IndexMetadata(String caseDirectory)
throws TextIndexMetadataException {
91 this.caseDirectoryPath = Paths.get(caseDirectory);
92 this.metadataFilePath = Paths.get(caseDirectory, METADATA_FILE_NAME);
93 if (!this.metadataFilePath.toFile().exists()) {
94 throw new TextIndexMetadataException(String.format(
"Text index metadata file doesn't exist: %s", metadataFilePath));
99 List<Index> getIndexes() {
110 static boolean isMetadataFilePresent(String caseDirectory) {
111 File file = Paths.get(caseDirectory, METADATA_FILE_NAME).toFile();
124 private void writeToFile() throws TextIndexMetadataException {
129 Document doc = XMLUtil.createDocument();
136 Source source =
new DOMSource(doc);
137 StringWriter stringWriter =
new StringWriter();
138 Result streamResult =
new StreamResult(stringWriter);
139 Transformer transformer = TransformerFactory.newInstance().newTransformer();
140 transformer.setOutputProperty(OutputKeys.INDENT,
"yes");
141 transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount",
"2");
142 transformer.transform(source, streamResult);
147 try (BufferedWriter fileWriter =
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(metadataFilePath.toFile())))) {
148 fileWriter.write(stringWriter.toString());
152 }
catch (ParserConfigurationException | TransformerException | IOException ex) {
153 throw new TextIndexMetadataException(String.format(
"Error writing to text index metadata file %s", metadataFilePath), ex);
160 private void createXMLDOM(Document doc) {
164 Element rootElement = doc.createElement(ROOT_ELEMENT_NAME);
165 doc.appendChild(rootElement);
170 for (Index index : indexes) {
171 Element coreElement = doc.createElement(CORE_ELEMENT_NAME);
172 rootElement.appendChild(coreElement);
173 createChildElement(doc, coreElement, CORE_NAME_ELEMENT_NAME, index.getIndexName());
174 createChildElement(doc, coreElement, SOLR_VERSION_ELEMENT_NAME, index.getSolrVersion());
175 createChildElement(doc, coreElement, SCHEMA_VERSION_ELEMENT_NAME, index.getSchemaVersion());
176 Path relativePath = caseDirectoryPath.relativize(Paths.get(index.getIndexPath()));
177 createChildElement(doc, coreElement, TEXT_INDEX_PATH_ELEMENT_NAME, relativePath.toString());
190 private void createChildElement(Document doc, Element parentElement, String elementName, String elementContent) {
191 Element element = doc.createElement(elementName);
192 element.appendChild(doc.createTextNode(elementContent));
193 parentElement.appendChild(element);
203 private void readFromFile() throws TextIndexMetadataException {
208 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
209 Document doc = builder.parse(metadataFilePath.toFile());
210 doc.getDocumentElement().normalize();
211 Element rootElement = doc.getDocumentElement();
212 if (!rootElement.getNodeName().equals(ROOT_ELEMENT_NAME)) {
213 throw new TextIndexMetadataException(
"Text index metadata file corrupted");
219 NodeList coreElements = doc.getElementsByTagName(CORE_ELEMENT_NAME);
220 if (coreElements.getLength() == 0) {
221 throw new TextIndexMetadataException(
"Text index metadata file corrupted");
224 while (coreIndx < coreElements.getLength()) {
225 Element coreElement = (Element) coreElements.item(coreIndx);
226 String coreName = getElementTextContent(coreElement, CORE_NAME_ELEMENT_NAME,
true);
227 String solrVersion = getElementTextContent(coreElement, SOLR_VERSION_ELEMENT_NAME,
true);
228 String schemaVersion = getElementTextContent(coreElement, SCHEMA_VERSION_ELEMENT_NAME,
true);
229 String relativeTextIndexPath = getElementTextContent(coreElement, TEXT_INDEX_PATH_ELEMENT_NAME,
true);
230 Path absoluteDatabasePath = caseDirectoryPath.resolve(relativeTextIndexPath);
231 Index index =
new Index(absoluteDatabasePath.toString(), solrVersion, schemaVersion, coreName,
"");
236 }
catch (ParserConfigurationException | SAXException | IOException ex) {
237 throw new TextIndexMetadataException(String.format(
"Error reading from text index metadata file %s", metadataFilePath), ex);
253 private String getElementTextContent(Element parentElement, String elementName,
boolean contentIsRequired)
throws TextIndexMetadataException {
254 NodeList elementsList = parentElement.getElementsByTagName(elementName);
255 if (elementsList.getLength() == 0) {
256 throw new TextIndexMetadataException(String.format(
"Missing %s element from text index metadata file %s", elementName, metadataFilePath));
258 String textContent = elementsList.item(0).getTextContent();
259 if (textContent.isEmpty() && contentIsRequired) {
260 throw new TextIndexMetadataException(String.format(
"Empty %s element in text index metadata file %s", elementName, metadataFilePath));
269 public final static class TextIndexMetadataException
extends Exception {
278 super(message, cause);
TextIndexMetadataException(String message)
TextIndexMetadataException(String message, Throwable cause)
static final long serialVersionUID