/*
* Autopsy Forensic Browser
*
* Copyright 2011-2014 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.datamodel;
import java.awt.event.ActionEvent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import org.openide.nodes.Sheet;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.FileSearchAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.ingest.RunIngestModulesDialog;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.VirtualDirectory;
/**
* Node for layout dir
*/
public class VirtualDirectoryNode extends AbstractAbstractFileNode<VirtualDirectory> {
private static Logger logger = Logger.getLogger(VirtualDirectoryNode.class.getName());
//prefix for special VirtualDirectory root nodes grouping local files
public final static String LOGICAL_FILE_SET_PREFIX = "LogicalFileSet"; //NON-NLS
public static String nameForLayoutFile(VirtualDirectory ld) {
return ld.getName();
}
public VirtualDirectoryNode(VirtualDirectory ld) {
super(ld);
this.setDisplayName(nameForLayoutFile(ld));
String name = ld.getName();
//set icon for name, special case for some built-ins
if (name.equals(VirtualDirectory.NAME_UNALLOC)) {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/folder-icon-deleted.png"); //NON-NLS
} else if (ld.isDataSource()) {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/fileset-icon-16.png"); //NON-NLS
} else if (name.equals(VirtualDirectory.NAME_CARVED)) {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png"); //TODO NON-NLS
} else {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/Folder-icon.png"); //NON-NLS
}
}
/**
* Right click action for this node
*
* @param popup
*
* @return
*/
@Override
@NbBundle.Messages({"VirtualDirectoryNode.action.runIngestMods.text=Run Ingest Modules"})
public Action[] getActions(boolean popup) {
List<Action> actions = new ArrayList<>();
for (Action a : super.getActions(true)) {
actions.add(a);
}
actions.add(new NewWindowViewAction(
NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.getActions.viewInNewWin.text"), this));
actions.add(null); // creates a menu separator
actions.add(ExtractAction.getInstance());
actions.add(null); // creates a menu separator
actions.add(new FileSearchAction(
Bundle.ImageNode_getActions_openFileSearchByAttr_text()));
actions.add(new AbstractAction(
Bundle.VirtualDirectoryNode_action_runIngestMods_text()) {
@Override
public void actionPerformed(ActionEvent e) {
final RunIngestModulesDialog ingestDialog = new RunIngestModulesDialog(Collections.<Content>singletonList(content));
ingestDialog.display();
}
});
actions.addAll(ContextMenuExtensionPoint.getActions());
return actions.toArray(new Action[0]);
}
@Override
@Messages({"VirtualDirectoryNode.createSheet.size.name=Size (Bytes)",
"VirtualDirectoryNode.createSheet.size.displayName=Size (Bytes)",
"VirtualDirectoryNode.createSheet.size.desc=Size of the data source in bytes.",
"VirtualDirectoryNode.createSheet.type.name=Type",
"VirtualDirectoryNode.createSheet.type.displayName=Type",
"VirtualDirectoryNode.createSheet.type.desc=Type of the image.",
"VirtualDirectoryNode.createSheet.type.text=Logical File Set",
"VirtualDirectoryNode.createSheet.timezone.name=Timezone",
"VirtualDirectoryNode.createSheet.timezone.displayName=Timezone",
"VirtualDirectoryNode.createSheet.timezone.desc=Timezone of the image",
"VirtualDirectoryNode.createSheet.deviceId.name=Device ID",
"VirtualDirectoryNode.createSheet.deviceId.displayName=Device ID",
"VirtualDirectoryNode.createSheet.deviceId.desc=Device ID of the image"})
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set ss = s.get(Sheet.PROPERTIES);
if (ss == null) {
ss = Sheet.createPropertiesSet();
s.put(ss);
}
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.name"),
NbBundle.getMessage(this.getClass(),
"VirtualDirectoryNode.createSheet.name.displayName"),
NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.desc"),
getName()));
if (!this.content.isDataSource()) {
Map<String, Object> map = new LinkedHashMap<>();
fillPropertyMap(map, content);
final String NO_DESCR = NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.noDesc");
for (Map.Entry<String, Object> entry : map.entrySet()) {
ss.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue()));
}
addTagProperty(ss);
} else {
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_type_name(),
Bundle.VirtualDirectoryNode_createSheet_type_displayName(),
Bundle.VirtualDirectoryNode_createSheet_type_desc(),
Bundle.VirtualDirectoryNode_createSheet_type_text()));
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_size_name(),
Bundle.VirtualDirectoryNode_createSheet_size_displayName(),
Bundle.VirtualDirectoryNode_createSheet_size_desc(),
this.content.getSize()));
try (SleuthkitCase.CaseDbQuery query = Case.getCurrentCase().getSleuthkitCase().executeQuery("SELECT time_zone FROM data_source_info WHERE obj_id = " + this.content.getId())) {
ResultSet timeZoneSet = query.getResultSet();
if (timeZoneSet.next()) {
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_timezone_name(),
Bundle.VirtualDirectoryNode_createSheet_timezone_displayName(),
Bundle.VirtualDirectoryNode_createSheet_timezone_desc(),
timeZoneSet.getString("time_zone")));
}
} catch (SQLException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get time zone for the following image: " + this.content.getId(), ex);
}
try (SleuthkitCase.CaseDbQuery query = Case.getCurrentCase().getSleuthkitCase().executeQuery("SELECT device_id FROM data_source_info WHERE obj_id = " + this.content.getId());) {
ResultSet deviceIdSet = query.getResultSet();
if (deviceIdSet.next()) {
ss.put(new NodeProperty<>(Bundle.VirtualDirectoryNode_createSheet_deviceId_name(),
Bundle.VirtualDirectoryNode_createSheet_deviceId_displayName(),
Bundle.VirtualDirectoryNode_createSheet_deviceId_desc(),
deviceIdSet.getString("device_id")));
}
} catch (SQLException | TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get device id for the following image: " + this.content.getId(), ex);
}
}
return s;
}
@Override
public <T> T accept(ContentNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public <T> T accept(DisplayableItemNodeVisitor<T> v) {
return v.visit(this);
}
@Override
public boolean isLeafTypeNode() {
return true;
}
/**
* Convert meta flag long to user-readable string / label
*
* @param metaFlag to convert
*
* @return string formatted meta flag representation
*/
public static String metaFlagToString(short metaFlag) {
String result = "";
short allocFlag = TskData.TSK_FS_META_FLAG_ENUM.ALLOC.getValue();
short unallocFlag = TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.getValue();
if ((metaFlag & allocFlag) == allocFlag) {
result = TskData.TSK_FS_META_FLAG_ENUM.ALLOC.toString();
}
if ((metaFlag & unallocFlag) == unallocFlag) {
result = TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.toString();
}
return result;
}
@Override
public String getItemType() {
// use content.isDataSource if different column settings are desired
return DisplayableItemNode.FILE_PARENT_NODE_KEY;
}
}