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_SELECTOR_ATTR = 
"selector"; 
 
   59     private static final String DATE_FORMAT = 
"yyyy-MM-dd HH:mm:ss"; 
 
   60     private static final String ENCODING = 
"UTF-8"; 
 
   61     private static XmlKeywordSearchList currentInstance = null;
 
   62     private final DateFormat dateFormatter;
 
   64     static synchronized XmlKeywordSearchList getCurrent() {
 
   65         if (currentInstance == null) {
 
   66             currentInstance = 
new XmlKeywordSearchList(CUR_LISTS_FILE);
 
   67             currentInstance.reload();
 
   69         return currentInstance;
 
   78     XmlKeywordSearchList(String xmlFile) {
 
   80         dateFormatter = 
new SimpleDateFormat(DATE_FORMAT);
 
   84     public boolean save() {
 
   89     public boolean save(
boolean isExport) {
 
   90         boolean success = 
false;
 
   92         DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
 
   95             DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
 
   96             Document doc = docBuilder.newDocument();
 
   98             Element rootEl = doc.createElement(ROOT_EL);
 
   99             doc.appendChild(rootEl);
 
  101             for (String listName : theLists.keySet()) {
 
  102                 if (theLists.get(listName).isEditable() == 
true) {
 
  105                 KeywordList list = theLists.get(listName);
 
  106                 String created = dateFormatter.format(list.getDateCreated());
 
  107                 String modified = dateFormatter.format(list.getDateModified());
 
  108                 String useForIngest = list.getUseForIngest().toString();
 
  109                 String ingestMessages = list.getIngestMessages().toString();
 
  110                 List<Keyword> keywords = list.getKeywords();
 
  112                 Element listEl = doc.createElement(LIST_EL);
 
  113                 listEl.setAttribute(LIST_NAME_ATTR, listName);
 
  114                 listEl.setAttribute(LIST_CREATE_ATTR, created);
 
  115                 listEl.setAttribute(LIST_MOD_ATTR, modified);
 
  120                     listEl.setAttribute(LIST_USE_FOR_INGEST, useForIngest);
 
  121                     listEl.setAttribute(LIST_INGEST_MSGS, ingestMessages);
 
  124                 for (Keyword keyword : keywords) {
 
  125                     Element keywordEl = doc.createElement(KEYWORD_EL);
 
  126                     String literal = keyword.searchTermIsLiteral() ? 
"true" : 
"false"; 
 
  127                     keywordEl.setAttribute(KEYWORD_LITERAL_ATTR, literal);
 
  128                     BlackboardAttribute.ATTRIBUTE_TYPE selectorType = keyword.getArtifactAttributeType();
 
  129                     if (selectorType != null) {
 
  130                         keywordEl.setAttribute(KEYWORD_SELECTOR_ATTR, selectorType.getLabel());
 
  132                     keywordEl.setTextContent(keyword.getSearchTerm());
 
  133                     listEl.appendChild(keywordEl);
 
  135                 rootEl.appendChild(listEl);
 
  138             success = XMLUtil.saveDoc(XmlKeywordSearchList.class, filePath, ENCODING, doc);
 
  139         } 
catch (ParserConfigurationException e) {
 
  140             xmlListslogger.log(Level.SEVERE, 
"Error saving keyword list: can't initialize parser.", e); 
 
  149     public boolean load() {
 
  150         final Document doc = XMLUtil.loadDoc(XmlKeywordSearchList.class, filePath);
 
  155         Element root = doc.getDocumentElement();
 
  157             xmlListslogger.log(Level.SEVERE, 
"Error loading keyword list: invalid file format."); 
 
  161             NodeList listsNList = root.getElementsByTagName(LIST_EL);
 
  162             int numLists = listsNList.getLength();
 
  163             for (
int i = 0; i < numLists; ++i) {
 
  164                 Element listEl = (Element) listsNList.item(i);
 
  165                 final String name = listEl.getAttribute(LIST_NAME_ATTR);
 
  166                 final String created = listEl.getAttribute(LIST_CREATE_ATTR);
 
  167                 final String modified = listEl.getAttribute(LIST_MOD_ATTR);
 
  170                 Boolean useForIngestBool;
 
  171                 Boolean ingestMessagesBool;
 
  173                 if (listEl.hasAttribute(LIST_USE_FOR_INGEST)) {
 
  174                     useForIngestBool = Boolean.parseBoolean(listEl.getAttribute(LIST_USE_FOR_INGEST));
 
  176                     useForIngestBool = 
true;
 
  179                 if (listEl.hasAttribute(LIST_INGEST_MSGS)) {
 
  180                     ingestMessagesBool = Boolean.parseBoolean(listEl.getAttribute(LIST_INGEST_MSGS));
 
  182                     ingestMessagesBool = 
true;
 
  185                 Date createdDate = dateFormatter.parse(created);
 
  186                 Date modDate = dateFormatter.parse(modified);
 
  188                 List<Keyword> words = 
new ArrayList<>();
 
  189                 KeywordList list = 
new KeywordList(name, createdDate, modDate, useForIngestBool, ingestMessagesBool, words);
 
  192                 NodeList wordsNList = listEl.getElementsByTagName(KEYWORD_EL);
 
  193                 final int numKeywords = wordsNList.getLength();
 
  194                 for (
int j = 0; j < numKeywords; ++j) {
 
  195                     Element wordEl = (Element) wordsNList.item(j);
 
  196                     String literal = wordEl.getAttribute(KEYWORD_LITERAL_ATTR);
 
  197                     boolean isLiteral = literal.equals(
"true"); 
 
  198                     Keyword keyword = 
new Keyword(wordEl.getTextContent(), isLiteral);
 
  199                     String selector = wordEl.getAttribute(KEYWORD_SELECTOR_ATTR);
 
  200                     if (!selector.equals(
"")) {
 
  201                         BlackboardAttribute.ATTRIBUTE_TYPE selectorType = BlackboardAttribute.ATTRIBUTE_TYPE.fromLabel(selector);
 
  202                         keyword.setArtifactAttributeType(selectorType);
 
  207                 theLists.put(name, list);
 
  209         } 
catch (ParseException e) {
 
  211             xmlListslogger.log(Level.SEVERE, 
"Error loading keyword list: can't parse dates.", e);