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;
43 import org.w3c.dom.Document;
44 import org.w3c.dom.Element;
45 import org.w3c.dom.NodeList;
46 import org.xml.sax.SAXException;
53 private final Path metadataFilePath;
54 private final Path caseDirectoryPath;
55 private final static String METADATA_FILE_NAME =
"SolrCore.properties";
56 private final static String ROOT_ELEMENT_NAME =
"SolrCores";
57 private final static String CORE_ELEMENT_NAME =
"Core";
58 private final static String CORE_NAME_ELEMENT_NAME =
"CoreName";
59 private final static String SCHEMA_VERSION_ELEMENT_NAME =
"SchemaVersion";
60 private final static String SOLR_VERSION_ELEMENT_NAME =
"SolrVersion";
61 private final static String TEXT_INDEX_PATH_ELEMENT_NAME =
"TextIndexPath";
62 private List<Index> indexes =
new ArrayList<>();
64 IndexMetadata(String caseDirectory, Index index)
throws TextIndexMetadataException {
65 this.metadataFilePath = Paths.get(caseDirectory, METADATA_FILE_NAME);
66 this.caseDirectoryPath = Paths.get(caseDirectory);
67 this.indexes.add(index);
71 IndexMetadata(String caseDirectory, List<Index> indexes)
throws TextIndexMetadataException {
73 this.metadataFilePath = Paths.get(caseDirectory, METADATA_FILE_NAME);
74 this.caseDirectoryPath = Paths.get(caseDirectory);
75 this.indexes = indexes;
88 IndexMetadata(String caseDirectory)
throws TextIndexMetadataException {
89 this.caseDirectoryPath = Paths.get(caseDirectory);
90 this.metadataFilePath = Paths.get(caseDirectory, METADATA_FILE_NAME);
91 if (!this.metadataFilePath.toFile().exists()) {
92 throw new TextIndexMetadataException(String.format(
"Text index metadata file doesn't exist: %s", metadataFilePath));
97 List<Index> getIndexes() {
108 static boolean isMetadataFilePresent(String caseDirectory) {
109 File file = Paths.get(caseDirectory, METADATA_FILE_NAME).toFile();
122 private void writeToFile() throws TextIndexMetadataException {
127 Document doc = XMLUtil.createDocument();
134 Source source =
new DOMSource(doc);
135 StringWriter stringWriter =
new StringWriter();
136 Result streamResult =
new StreamResult(stringWriter);
137 Transformer transformer = TransformerFactory.newInstance().newTransformer();
138 transformer.setOutputProperty(OutputKeys.INDENT,
"yes");
139 transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount",
"2");
140 transformer.transform(source, streamResult);
145 try (BufferedWriter fileWriter =
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(metadataFilePath.toFile())))) {
146 fileWriter.write(stringWriter.toString());
150 }
catch (ParserConfigurationException | TransformerException | IOException ex) {
151 throw new TextIndexMetadataException(String.format(
"Error writing to text index metadata file %s", metadataFilePath), ex);
158 private void createXMLDOM(Document doc) {
162 Element rootElement = doc.createElement(ROOT_ELEMENT_NAME);
163 doc.appendChild(rootElement);
168 for (Index index : indexes) {
169 Element coreElement = doc.createElement(CORE_ELEMENT_NAME);
170 rootElement.appendChild(coreElement);
171 createChildElement(doc, coreElement, CORE_NAME_ELEMENT_NAME, index.getIndexName());
172 createChildElement(doc, coreElement, SOLR_VERSION_ELEMENT_NAME, index.getSolrVersion());
173 createChildElement(doc, coreElement, SCHEMA_VERSION_ELEMENT_NAME, index.getSchemaVersion());
174 Path relativePath = caseDirectoryPath.relativize(Paths.get(index.getIndexPath()));
175 createChildElement(doc, coreElement, TEXT_INDEX_PATH_ELEMENT_NAME, relativePath.toString());
188 private void createChildElement(Document doc, Element parentElement, String elementName, String elementContent) {
189 Element element = doc.createElement(elementName);
190 element.appendChild(doc.createTextNode(elementContent));
191 parentElement.appendChild(element);
201 private void readFromFile() throws TextIndexMetadataException {
206 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
207 Document doc = builder.parse(metadataFilePath.toFile());
208 doc.getDocumentElement().normalize();
209 Element rootElement = doc.getDocumentElement();
210 if (!rootElement.getNodeName().equals(ROOT_ELEMENT_NAME)) {
211 throw new TextIndexMetadataException(
"Text index metadata file corrupted");
217 NodeList coreElements = doc.getElementsByTagName(CORE_ELEMENT_NAME);
218 if (coreElements.getLength() == 0) {
219 throw new TextIndexMetadataException(
"Text index metadata file corrupted");
222 while (coreIndx < coreElements.getLength()) {
223 Element coreElement = (Element) coreElements.item(coreIndx);
224 String coreName = getElementTextContent(coreElement, CORE_NAME_ELEMENT_NAME,
true);
225 String solrVersion = getElementTextContent(coreElement, SOLR_VERSION_ELEMENT_NAME,
true);
226 String schemaVersion = getElementTextContent(coreElement, SCHEMA_VERSION_ELEMENT_NAME,
true);
227 String relativeTextIndexPath = getElementTextContent(coreElement, TEXT_INDEX_PATH_ELEMENT_NAME,
true);
228 Path absoluteDatabasePath = caseDirectoryPath.resolve(relativeTextIndexPath);
229 Index index =
new Index(absoluteDatabasePath.toString(), solrVersion, schemaVersion, coreName,
"");
234 }
catch (ParserConfigurationException | SAXException | IOException ex) {
235 throw new TextIndexMetadataException(String.format(
"Error reading from text index metadata file %s", metadataFilePath), ex);
251 private String getElementTextContent(Element parentElement, String elementName,
boolean contentIsRequired)
throws TextIndexMetadataException {
252 NodeList elementsList = parentElement.getElementsByTagName(elementName);
253 if (elementsList.getLength() == 0) {
254 throw new TextIndexMetadataException(String.format(
"Missing %s element from text index metadata file %s", elementName, metadataFilePath));
256 String textContent = elementsList.item(0).getTextContent();
257 if (textContent.isEmpty() && contentIsRequired) {
258 throw new TextIndexMetadataException(String.format(
"Empty %s element in text index metadata file %s", elementName, metadataFilePath));
267 public final static class TextIndexMetadataException
extends Exception {
276 super(message, cause);
TextIndexMetadataException(String message)
TextIndexMetadataException(String message, Throwable cause)
static final long serialVersionUID