mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
custom content provider and args
This commit is contained in:
parent
2fefce513f
commit
402af60d01
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
|
import com.sun.xml.bind.v2.TODO;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -29,8 +30,15 @@ import java.nio.file.Path;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
@ -42,11 +50,15 @@ import javax.xml.transform.TransformerException;
|
|||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
import org.sleuthkit.autopsy.coreutils.Version;
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||||
import org.sleuthkit.datamodel.ContentStream.ContentProvider;
|
import org.sleuthkit.datamodel.ContentStream.ContentProvider;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@ -104,13 +116,20 @@ public final class CaseMetadata {
|
|||||||
private static final String SCHEMA_VERSION_FIVE = "5.0";
|
private static final String SCHEMA_VERSION_FIVE = "5.0";
|
||||||
private final static String ORIGINAL_CASE_ELEMENT_NAME = "OriginalCase"; //NON-NLS
|
private final static String ORIGINAL_CASE_ELEMENT_NAME = "OriginalCase"; //NON-NLS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fields from schema version 5
|
||||||
|
*/
|
||||||
|
private static final String SCHEMA_VERSION_SIX = "6.0";
|
||||||
|
private final static String CONTENT_PROVIDER_ELEMENT_NAME = "ContentProviderArgs";
|
||||||
|
private final static String CONTENT_PROVIDER_ARG_DEFAULT_KEY = "DEFAULT";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unread fields, regenerated on save.
|
* Unread fields, regenerated on save.
|
||||||
*/
|
*/
|
||||||
private final static String MODIFIED_DATE_ELEMENT_NAME = "ModifiedDate"; //NON-NLS
|
private final static String MODIFIED_DATE_ELEMENT_NAME = "ModifiedDate"; //NON-NLS
|
||||||
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
|
private final static String AUTOPSY_SAVED_BY_ELEMENT_NAME = "SavedByAutopsyVersion"; //NON-NLS
|
||||||
|
|
||||||
private final static String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_FIVE;
|
private final static String CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_SIX;
|
||||||
|
|
||||||
private final Path metadataFilePath;
|
private final Path metadataFilePath;
|
||||||
private Case.CaseType caseType;
|
private Case.CaseType caseType;
|
||||||
@ -122,6 +141,7 @@ public final class CaseMetadata {
|
|||||||
private String createdDate;
|
private String createdDate;
|
||||||
private String createdByVersion;
|
private String createdByVersion;
|
||||||
private CaseMetadata originalMetadata = null; // For portable cases
|
private CaseMetadata originalMetadata = null; // For portable cases
|
||||||
|
private ContentProvider contentProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the file extension used for case metadata files.
|
* Gets the file extension used for case metadata files.
|
||||||
@ -214,8 +234,12 @@ public final class CaseMetadata {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The custom provider for content byte data or null if no custom
|
||||||
|
* provider.
|
||||||
|
*/
|
||||||
public ContentProvider getContentProvider() {
|
public ContentProvider getContentProvider() {
|
||||||
return TODO;
|
return contentProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -474,6 +498,10 @@ public final class CaseMetadata {
|
|||||||
Element originalCaseElement = doc.createElement(ORIGINAL_CASE_ELEMENT_NAME);
|
Element originalCaseElement = doc.createElement(ORIGINAL_CASE_ELEMENT_NAME);
|
||||||
rootElement.appendChild(originalCaseElement);
|
rootElement.appendChild(originalCaseElement);
|
||||||
if (originalMetadata != null) {
|
if (originalMetadata != null) {
|
||||||
|
Element contentProviderEl = doc.createElement(CONTENT_PROVIDER_ELEMENT_NAME);
|
||||||
|
originalCaseElement.appendChild(contentProviderEl);
|
||||||
|
serializeContentProviderArgs(doc, argsTODO, contentProviderEl);
|
||||||
|
|
||||||
createChildElement(doc, originalCaseElement, CREATED_DATE_ELEMENT_NAME, originalMetadata.createdDate);
|
createChildElement(doc, originalCaseElement, CREATED_DATE_ELEMENT_NAME, originalMetadata.createdDate);
|
||||||
Element originalCaseDetailsElement = doc.createElement(CASE_ELEMENT_NAME);
|
Element originalCaseDetailsElement = doc.createElement(CASE_ELEMENT_NAME);
|
||||||
originalCaseElement.appendChild(originalCaseDetailsElement);
|
originalCaseElement.appendChild(originalCaseDetailsElement);
|
||||||
@ -549,6 +577,8 @@ public final class CaseMetadata {
|
|||||||
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_CREATED_BY_ELEMENT_NAME, true);
|
this.createdByVersion = getElementTextContent(rootElement, AUTOPSY_CREATED_BY_ELEMENT_NAME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serialize TODO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the content of the children of the case element.
|
* Get the content of the children of the case element.
|
||||||
*/
|
*/
|
||||||
@ -620,6 +650,105 @@ public final class CaseMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads custom content provider arguments from an xml element.
|
||||||
|
* @param element The xml element.
|
||||||
|
* @return The custom content provider arguments.
|
||||||
|
*/
|
||||||
|
private Object loadContentProviderArgs(Element element) {
|
||||||
|
if (element == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList nodeList = element.getChildNodes();
|
||||||
|
if (nodeList != null && nodeList.getLength() > 0) {
|
||||||
|
String nodeTag = element.getTagName();
|
||||||
|
boolean childrenHaveSameTag = true;
|
||||||
|
List<Pair<String, Object>> children = new ArrayList<>();
|
||||||
|
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||||
|
Node child = nodeList.item(i);
|
||||||
|
if (child instanceof Element) {
|
||||||
|
Element childElement = (Element) child;
|
||||||
|
String childTagName = childElement.getTagName();
|
||||||
|
Object childArg = loadContentProviderArgs(childElement);
|
||||||
|
children.add(Pair.of(childTagName, childArg));
|
||||||
|
|
||||||
|
if (childrenHaveSameTag && !childTagName.equalsIgnoreCase(nodeTag)) {
|
||||||
|
childrenHaveSameTag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childrenHaveSameTag) {
|
||||||
|
return children.stream().map(Pair::getValue).collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
Map<String, Object> toRet = new HashMap<>();
|
||||||
|
for (Pair<String, Object> child: children) {
|
||||||
|
toRet.put(child.getKey(), child.getValue());
|
||||||
|
}
|
||||||
|
return toRet;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return element.getTextContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes custom content provider arguments to an xml element.
|
||||||
|
* @param doc The root xml document.
|
||||||
|
* @param arg The argument to serialize.
|
||||||
|
* @param el The xml element for the argument.
|
||||||
|
*/
|
||||||
|
private void serializeContentProviderArgs(Document doc, Object arg, Element el) {
|
||||||
|
if (arg == null) {
|
||||||
|
return;
|
||||||
|
} else if (arg instanceof List) {
|
||||||
|
String parentTagName = el.getTagName();
|
||||||
|
List<? extends Object> argList = (List<? extends Object>) arg;
|
||||||
|
for (Object childArg: argList) {
|
||||||
|
Element childEl = doc.createElement(parentTagName);
|
||||||
|
el.appendChild(childEl);
|
||||||
|
serializeContentProviderArgs(doc, childArg, childEl);
|
||||||
|
}
|
||||||
|
} else if (arg instanceof Map) {
|
||||||
|
Map<? extends Object, ? extends Object> argMap = (Map<? extends Object, ? extends Object>) arg;
|
||||||
|
for (Entry<? extends Object, ? extends Object> childEntry: argMap.entrySet()) {
|
||||||
|
String childTag = childEntry.getKey() == null ? null : childEntry.getKey().toString();
|
||||||
|
if (StringUtils.isBlank(childTag)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Element childEl = doc.createElement(childTag);
|
||||||
|
el.appendChild(childEl);
|
||||||
|
serializeContentProviderArgs(doc, childEntry.getValue(), childEl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
el.setTextContent(arg.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to load a content provider for the provided arguments. Returns
|
||||||
|
* null if no content provider for the arguments can be identified.
|
||||||
|
*
|
||||||
|
* @param args The arguments.
|
||||||
|
* @return The content provider or null if no content provider can be
|
||||||
|
* provisioned for the arguments
|
||||||
|
*/
|
||||||
|
private ContentProvider loadContentProvider(Map<String, Object> args) {
|
||||||
|
Collection<? extends CustomContentProvider> customContentProviders = Lookup.getDefault().lookupAll(CustomContentProvider.class);
|
||||||
|
if (customContentProviders != null) {
|
||||||
|
for (CustomContentProvider customProvider : customContentProviders) {
|
||||||
|
ContentProvider contentProvider = customProvider.load(args);
|
||||||
|
if (contentProvider != null) {
|
||||||
|
return contentProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the text content of an XML element.
|
* Gets the text content of an XML element.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2023 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.casemodule;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.sleuthkit.datamodel.ContentStream.ContentProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads content byte stream from custom source.
|
||||||
|
*/
|
||||||
|
public interface CustomContentProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to create a ContentProvider given the specified args. Returns
|
||||||
|
* null if arguments are invalid for this custom content provider.
|
||||||
|
*
|
||||||
|
* @param args The key value pair of arguments loaded from the .aut xml file.
|
||||||
|
* @return The created content provider or null if arguments are invalid.
|
||||||
|
*/
|
||||||
|
ContentProvider load(Map<String, Object> args);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user