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