19 package org.sleuthkit.autopsy.keywordsearch;
 
   22 import java.text.DateFormat;
 
   23 import java.text.ParseException;
 
   24 import java.text.SimpleDateFormat;
 
   25 import java.util.ArrayList;
 
   26 import java.util.Date;
 
   27 import java.util.List;
 
   28 import java.util.logging.Level;
 
   29 import javax.xml.parsers.DocumentBuilder;
 
   30 import javax.xml.parsers.DocumentBuilderFactory;
 
   31 import javax.xml.parsers.ParserConfigurationException;
 
   36 import org.w3c.dom.Document;
 
   37 import org.w3c.dom.Element;
 
   38 import org.w3c.dom.NodeList;
 
   44 final class XmlKeywordSearchList 
extends KeywordSearchList {
 
   46     private static final Logger xmlListslogger = Logger.getLogger(XmlKeywordSearchList.class.getName());
 
   47     private static final String CUR_LISTS_FILE_NAME = 
"keywords.xml";     
 
   48     private static final String CUR_LISTS_FILE = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_LISTS_FILE_NAME;
 
   49     private static final String ROOT_EL = 
"keyword_lists"; 
 
   50     private static final String LIST_EL = 
"keyword_list"; 
 
   51     private static final String LIST_NAME_ATTR = 
"name"; 
 
   52     private static final String LIST_CREATE_ATTR = 
"created"; 
 
   53     private static final String LIST_MOD_ATTR = 
"modified"; 
 
   54     private static final String LIST_USE_FOR_INGEST = 
"use_for_ingest"; 
 
   55     private static final String LIST_INGEST_MSGS = 
"ingest_messages"; 
 
   56     private static final String KEYWORD_EL = 
"keyword"; 
 
   57     private static final String KEYWORD_LITERAL_ATTR = 
"literal"; 
 
   58     private static final String KEYWORD_WHOLE_ATTR = 
"whole"; 
 
   59     private static final String KEYWORD_SELECTOR_ATTR = 
"selector"; 
 
   60     private static final String DATE_FORMAT = 
"yyyy-MM-dd HH:mm:ss"; 
 
   61     private static final String ENCODING = 
"UTF-8"; 
 
   62     private static XmlKeywordSearchList currentInstance = null;
 
   63     private final DateFormat dateFormatter;
 
   65     static synchronized XmlKeywordSearchList getCurrent() {
 
   66         if (currentInstance == null) {
 
   67             currentInstance = 
new XmlKeywordSearchList(CUR_LISTS_FILE);
 
   68             currentInstance.reload();
 
   70         return currentInstance;
 
   79     XmlKeywordSearchList(String xmlFile) {
 
   81         dateFormatter = 
new SimpleDateFormat(DATE_FORMAT);
 
   85     public boolean save() {
 
   90     public boolean save(
boolean isExport) {
 
   91         boolean success = 
false;
 
   93         DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
 
   96             DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
 
   97             Document doc = docBuilder.newDocument();
 
   99             Element rootEl = doc.createElement(ROOT_EL);
 
  100             doc.appendChild(rootEl);
 
  102             for (String listName : theLists.keySet()) {
 
  103                 if (theLists.get(listName).isEditable() == 
true) {
 
  106                 KeywordList list = theLists.get(listName);
 
  107                 String created = dateFormatter.format(list.getDateCreated());
 
  108                 String modified = dateFormatter.format(list.getDateModified());
 
  109                 String useForIngest = list.getUseForIngest().toString();
 
  110                 String ingestMessages = list.getIngestMessages().toString();
 
  111                 List<Keyword> keywords = list.getKeywords();
 
  113                 Element listEl = doc.createElement(LIST_EL);
 
  114                 listEl.setAttribute(LIST_NAME_ATTR, listName);
 
  115                 listEl.setAttribute(LIST_CREATE_ATTR, created);
 
  116                 listEl.setAttribute(LIST_MOD_ATTR, modified);
 
  121                     listEl.setAttribute(LIST_USE_FOR_INGEST, useForIngest);
 
  122                     listEl.setAttribute(LIST_INGEST_MSGS, ingestMessages);
 
  125                 for (Keyword keyword : keywords) {
 
  126                     Element keywordEl = doc.createElement(KEYWORD_EL);
 
  127                     String literal = keyword.searchTermIsLiteral() ? 
"true" : 
"false"; 
 
  128                     keywordEl.setAttribute(KEYWORD_LITERAL_ATTR, literal);
 
  129                     String whole = keyword.searchTermIsWholeWord() ? 
"true" : 
"false"; 
 
  130                     keywordEl.setAttribute(KEYWORD_WHOLE_ATTR, whole);
 
  131                     BlackboardAttribute.ATTRIBUTE_TYPE selectorType = keyword.getArtifactAttributeType();
 
  132                     if (selectorType != null) {
 
  133                         keywordEl.setAttribute(KEYWORD_SELECTOR_ATTR, selectorType.getLabel());
 
  135                     keywordEl.setTextContent(keyword.getSearchTerm());
 
  136                     listEl.appendChild(keywordEl);
 
  138                 rootEl.appendChild(listEl);
 
  141             success = XMLUtil.saveDoc(XmlKeywordSearchList.class, filePath, ENCODING, doc);
 
  142         } 
catch (ParserConfigurationException e) {
 
  143             xmlListslogger.log(Level.SEVERE, 
"Error saving keyword list: can't initialize parser.", e); 
 
  152     public boolean load() {
 
  153         final Document doc = XMLUtil.loadDoc(XmlKeywordSearchList.class, filePath);
 
  158         Element root = doc.getDocumentElement();
 
  160             xmlListslogger.log(Level.SEVERE, 
"Error loading keyword list: invalid file format."); 
 
  164             NodeList listsNList = root.getElementsByTagName(LIST_EL);
 
  165             int numLists = listsNList.getLength();
 
  166             for (
int i = 0; i < numLists; ++i) {
 
  167                 Element listEl = (Element) listsNList.item(i);
 
  168                 final String name = listEl.getAttribute(LIST_NAME_ATTR);
 
  169                 final String created = listEl.getAttribute(LIST_CREATE_ATTR);
 
  170                 final String modified = listEl.getAttribute(LIST_MOD_ATTR);
 
  173                 Boolean useForIngestBool;
 
  174                 Boolean ingestMessagesBool;
 
  176                 if (listEl.hasAttribute(LIST_USE_FOR_INGEST)) {
 
  177                     useForIngestBool = Boolean.parseBoolean(listEl.getAttribute(LIST_USE_FOR_INGEST));
 
  179                     useForIngestBool = 
true;
 
  182                 if (listEl.hasAttribute(LIST_INGEST_MSGS)) {
 
  183                     ingestMessagesBool = Boolean.parseBoolean(listEl.getAttribute(LIST_INGEST_MSGS));
 
  185                     ingestMessagesBool = 
true;
 
  188                 Date createdDate = dateFormatter.parse(created);
 
  189                 Date modDate = dateFormatter.parse(modified);
 
  191                 List<Keyword> words = 
new ArrayList<>();
 
  192                 KeywordList list = 
new KeywordList(name, createdDate, modDate, useForIngestBool, ingestMessagesBool, words);
 
  195                 NodeList wordsNList = listEl.getElementsByTagName(KEYWORD_EL);
 
  196                 final int numKeywords = wordsNList.getLength();
 
  197                 for (
int j = 0; j < numKeywords; ++j) {
 
  198                     Element wordEl = (Element) wordsNList.item(j);
 
  199                     String literal = wordEl.getAttribute(KEYWORD_LITERAL_ATTR);
 
  200                     boolean isLiteral = literal.equals(
"true"); 
 
  202                     String whole = wordEl.getAttribute(KEYWORD_WHOLE_ATTR);
 
  203                     if (whole.equals(
"")) {
 
  204                         keyword = 
new Keyword(wordEl.getTextContent(), isLiteral);
 
  206                         boolean isWhole = whole.equals(
"true");
 
  207                         keyword = 
new Keyword(wordEl.getTextContent(), isLiteral, isWhole);
 
  209                     String selector = wordEl.getAttribute(KEYWORD_SELECTOR_ATTR);
 
  210                     if (!selector.equals(
"")) {
 
  211                         BlackboardAttribute.ATTRIBUTE_TYPE selectorType = BlackboardAttribute.ATTRIBUTE_TYPE.fromLabel(selector);
 
  212                         keyword.setArtifactAttributeType(selectorType);
 
  216                 theLists.put(name, list);
 
  218         } 
catch (ParseException e) {
 
  220             xmlListslogger.log(Level.SEVERE, 
"Error loading keyword list: can't parse dates.", e);