mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Finished first pass
This commit is contained in:
parent
bc74e44d38
commit
fec212ee1f
@ -63,7 +63,6 @@ FileSystemColumnUtils.abstractFileColumns.metaAddrColLbl=Meta Addr.
|
||||
FileSystemColumnUtils.abstractFileColumns.mimeType=MIME Type
|
||||
FileSystemColumnUtils.abstractFileColumns.modeColLbl=Mode
|
||||
FileSystemColumnUtils.abstractFileColumns.modifiedTimeColLbl=Modified Time
|
||||
FileSystemColumnUtils.abstractFileColumns.nameColLbl=Name
|
||||
FileSystemColumnUtils.abstractFileColumns.objectId=Object ID
|
||||
FileSystemColumnUtils.abstractFileColumns.originalName=Original Name
|
||||
FileSystemColumnUtils.abstractFileColumns.scoreName=S
|
||||
@ -72,5 +71,18 @@ FileSystemColumnUtils.abstractFileColumns.sizeColLbl=Size
|
||||
FileSystemColumnUtils.abstractFileColumns.typeDirColLbl=Type(Dir)
|
||||
FileSystemColumnUtils.abstractFileColumns.typeMetaColLbl=Type(Meta)
|
||||
FileSystemColumnUtils.abstractFileColumns.useridColLbl=UserID
|
||||
FileSystemColumnUtils.imageColumns.devID=Device ID
|
||||
FileSystemColumnUtils.imageColumns.sectorSize=Sector Size (Bytes)
|
||||
FileSystemColumnUtils.imageColumns.size=Size (Bytes)
|
||||
FileSystemColumnUtils.imageColumns.timezone=Timezone
|
||||
FileSystemColumnUtils.imageColumns.type=Type
|
||||
FileSystemColumnUtils.imageColumns.typeValue=Image
|
||||
FileSystemColumnUtils.nameColumn.name=Name
|
||||
FileSystemColumnUtils.noDescription=No Description
|
||||
FileSystemColumnUtils.poolColumns.type=Type
|
||||
FileSystemColumnUtils.volumeColumns.desc=Description
|
||||
FileSystemColumnUtils.volumeColumns.flags=Flags
|
||||
FileSystemColumnUtils.volumeColumns.id=ID
|
||||
FileSystemColumnUtils.volumeColumns.length=Length in Sectors
|
||||
FileSystemColumnUtils.volumeColumns.startingSector=Starting Sector
|
||||
FileTypesByMimeType.name.text=By MIME Type
|
||||
|
@ -19,6 +19,8 @@
|
||||
package org.sleuthkit.autopsy.mainui.datamodel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
@ -26,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.Pool;
|
||||
@ -39,7 +42,15 @@ class FileSystemColumnUtils {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FileSystemColumnUtils.class.getName());
|
||||
|
||||
@Messages({"FileSystemColumnUtils.abstractFileColumns.nameColLbl=Name",
|
||||
enum ContentType {
|
||||
IMAGE,
|
||||
POOL,
|
||||
VOLUME,
|
||||
ABSTRACT_FILE,
|
||||
UNSUPPORTED;
|
||||
}
|
||||
|
||||
@Messages({"FileSystemColumnUtils.nameColumn.name=Name",
|
||||
"FileSystemColumnUtils.abstractFileColumns.originalName=Original Name",
|
||||
"FileSystemColumnUtils.abstractFileColumns.scoreName=S",
|
||||
"FileSystemColumnUtils.abstractFileColumns.commentName=C",
|
||||
@ -65,30 +76,24 @@ class FileSystemColumnUtils {
|
||||
"FileSystemColumnUtils.abstractFileColumns.objectId=Object ID",
|
||||
"FileSystemColumnUtils.abstractFileColumns.mimeType=MIME Type",
|
||||
"FileSystemColumnUtils.abstractFileColumns.extensionColLbl=Extension",
|
||||
"FileSystemColumnUtils.volumeColumns.nameColLbl=Name",
|
||||
"FileSystemColumnUtils.volumeColumns.id=ID",
|
||||
"FileSystemColumnUtils.volumeColumns.startingSector=Starting Sector",
|
||||
"FileSystemColumnUtils.volumeColumns.length=Length in Sectors",
|
||||
"FileSystemColumnUtils.volumeColumns.desc=Description",
|
||||
"FileSystemColumnUtils.volumeColumns.flags=Flags",
|
||||
"FileSystemColumnUtils.imageColumns.nameColLbl=Name",
|
||||
"FileSystemColumnUtils.imageColumns.type=Type",
|
||||
"FileSystemColumnUtils.imageColumns.typeValue=Image",
|
||||
"FileSystemColumnUtils.imageColumns.size=Size (Bytes)",
|
||||
"FileSystemColumnUtils.imageColumns.sectorSize=Sector Size (Bytes)",
|
||||
"FileSystemColumnUtils.imageColumns.timezone=Timezone",
|
||||
"FileSystemColumnUtils.imageColumns.devID=Device ID",
|
||||
"FileSystemColumnUtils.hostColumns.nameColLbl=Name",
|
||||
"FileSystemColumnUtils.poolColumns.nameColLbl=Name",
|
||||
"FileSystemColumnUtils.poolColumns.type=Type",
|
||||
|
||||
"FileSystemColumnUtils.noDescription=No Description"})
|
||||
|
||||
|
||||
|
||||
private static final ColumnKey NAME_COLUMN = getColumnKey(Bundle.FileSystemColumnUtils_nameColumn_name());
|
||||
|
||||
static final List<ColumnKey> ABSTRACT_FILE_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_nameColLbl()),
|
||||
private static final List<ColumnKey> ABSTRACT_FILE_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_originalName()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_scoreName()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_commentName()),
|
||||
@ -108,23 +113,21 @@ class FileSystemColumnUtils {
|
||||
// getFileColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_attrAddrColLbl()),
|
||||
// getFileColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_typeDirColLbl()),
|
||||
// getFileColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_typeMetaColLbl()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_knownColLbl()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_knownColLbl()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_md5HashColLbl()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_sha256HashColLbl()),
|
||||
// getFileColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_objectId()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_mimeType()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_mimeType()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_extensionColLbl()));
|
||||
|
||||
static final List<ColumnKey> VOLUME_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_volumeColumns_nameColLbl()),
|
||||
private static final List<ColumnKey> VOLUME_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_volumeColumns_id()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_volumeColumns_startingSector()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_volumeColumns_length()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_volumeColumns_desc()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_volumeColumns_flags()));
|
||||
|
||||
static final List<ColumnKey> IMAGE_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_imageColumns_nameColLbl()),
|
||||
private static final List<ColumnKey> IMAGE_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_imageColumns_type()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_imageColumns_size()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_imageColumns_sectorSize()),
|
||||
@ -132,83 +135,145 @@ getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_mimeType()),
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_imageColumns_devID())
|
||||
);
|
||||
|
||||
static final List<ColumnKey> HOST_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_hostColumns_nameColLbl())
|
||||
// Note that Hosts aren't content and will not be combined with other types, so we include the name here
|
||||
private static final List<ColumnKey> HOST_COLUMNS = Arrays.asList(
|
||||
NAME_COLUMN
|
||||
);
|
||||
|
||||
static final List<ColumnKey> POOL_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_poolColumns_nameColLbl()),
|
||||
private static final List<ColumnKey> POOL_COLUMNS = Arrays.asList(
|
||||
getColumnKey(Bundle.FileSystemColumnUtils_poolColumns_type())
|
||||
);
|
||||
|
||||
static List<Object> getCellValuesForPool(Pool pool) throws TskCoreException {
|
||||
return Arrays.asList(
|
||||
pool.getType().getName(),
|
||||
pool.getType().getName()
|
||||
);
|
||||
}
|
||||
|
||||
static List<Object> getCellValuesForHost(Host host) throws TskCoreException {
|
||||
return Arrays.asList(
|
||||
host.getName()
|
||||
);
|
||||
}
|
||||
|
||||
static List<Object> getCellValuesForImage(Image image) throws TskCoreException {
|
||||
return Arrays.asList(
|
||||
image.getName(),
|
||||
Bundle.FileSystemColumnUtils_imageColumns_typeValue(),
|
||||
image.getSize(),
|
||||
image.getSsize(),
|
||||
image.getTimeZone(),
|
||||
image.getDeviceId()
|
||||
);
|
||||
}
|
||||
|
||||
static List<Object> getCellValuesForVolume(Volume vol) throws TskCoreException {
|
||||
return Arrays.asList(
|
||||
getVolumeDisplayName(vol),
|
||||
vol.getAddr(),
|
||||
vol.getStart(),
|
||||
vol.getLength(),
|
||||
vol.getDescription(),
|
||||
vol.getFlagsAsString()
|
||||
);
|
||||
}
|
||||
|
||||
private static String getVolumeDisplayName(Volume vol) {
|
||||
// set name, display name, and icon
|
||||
String volName = "vol" + Long.toString(vol.getAddr());
|
||||
long end = vol.getStart() + (vol.getLength() - 1);
|
||||
String tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + "-" + end + ")";
|
||||
|
||||
// If this is a pool volume use a custom display name
|
||||
try {
|
||||
if (vol.getParent() != null
|
||||
&& vol.getParent().getParent() instanceof Pool) {
|
||||
// Pool volumes are not contiguous so printing a range of blocks is inaccurate
|
||||
tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + ")";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Error looking up parent(s) of volume with obj ID = " + vol.getId(), ex);
|
||||
private static ContentType getContentType(Content content) {
|
||||
if (content instanceof Image) {
|
||||
return ContentType.IMAGE;
|
||||
} else if (content instanceof Volume) {
|
||||
return ContentType.VOLUME;
|
||||
} else if (content instanceof Pool) {
|
||||
return ContentType.POOL;
|
||||
} else if (content instanceof AbstractFile) {
|
||||
return ContentType.ABSTRACT_FILE;
|
||||
}
|
||||
return tempVolName;
|
||||
return ContentType.UNSUPPORTED;
|
||||
}
|
||||
|
||||
static boolean isDisplayable(Content content) {
|
||||
return (getContentType(content) != ContentType.UNSUPPORTED);
|
||||
}
|
||||
|
||||
static List<ContentType> getDisplayableTypesForContentList(List<Content> contentList) {
|
||||
List<ContentType> displayableTypes = new ArrayList<>();
|
||||
for (Content content : contentList) {
|
||||
ContentType type = getContentType(content);
|
||||
if (type != ContentType.UNSUPPORTED && ! displayableTypes.contains(type)) {
|
||||
displayableTypes.add(type);
|
||||
}
|
||||
}
|
||||
Collections.sort(displayableTypes);
|
||||
return displayableTypes;
|
||||
}
|
||||
|
||||
static List<ColumnKey> getColumnKeysForContent(List<ContentType> contentTypes) {
|
||||
List<ColumnKey> colKeys = new ArrayList<>();
|
||||
colKeys.add(NAME_COLUMN);
|
||||
|
||||
private static ColumnKey getColumnKey(String name) {
|
||||
return new ColumnKey(name, name, Bundle.FileSystemColumnUtils_noDescription());
|
||||
// Make sure content types are processed in the same order as in getCellValuesForContent()
|
||||
if (contentTypes.contains(ContentType.IMAGE)) {
|
||||
colKeys.addAll(IMAGE_COLUMNS);
|
||||
}
|
||||
if (contentTypes.contains(ContentType.POOL)) {
|
||||
colKeys.addAll(POOL_COLUMNS);
|
||||
}
|
||||
if (contentTypes.contains(ContentType.VOLUME)) {
|
||||
colKeys.addAll(VOLUME_COLUMNS);
|
||||
}
|
||||
if (contentTypes.contains(ContentType.ABSTRACT_FILE)) {
|
||||
colKeys.addAll(ABSTRACT_FILE_COLUMNS);
|
||||
}
|
||||
return colKeys;
|
||||
}
|
||||
|
||||
static List<Object> getCellValuesForContent(Content content, List<ContentType> contentTypes) throws TskCoreException {
|
||||
List<Object> cellValues = new ArrayList<>();
|
||||
cellValues.add(getNameValueForContent(content));
|
||||
|
||||
// Make sure content types are processed in the same order as in getColumnKeysForContent()
|
||||
if (contentTypes.contains(ContentType.IMAGE)) {
|
||||
cellValues.addAll(getNonNameCellValuesForImage(content));
|
||||
}
|
||||
if (contentTypes.contains(ContentType.POOL)) {
|
||||
cellValues.addAll(getNonNameCellValuesForPool(content));
|
||||
}
|
||||
if (contentTypes.contains(ContentType.VOLUME)) {
|
||||
cellValues.addAll(getNonNameCellValuesForVolume(content));
|
||||
}
|
||||
if (contentTypes.contains(ContentType.ABSTRACT_FILE)) {
|
||||
cellValues.addAll(getNonNameCellValuesForAbstractFile(content));
|
||||
}
|
||||
return cellValues;
|
||||
}
|
||||
|
||||
private static String getNameValueForContent(Content content) {
|
||||
if (content instanceof Image) {
|
||||
Image image = (Image)content;
|
||||
return image.getName();
|
||||
} else if (content instanceof Volume) {
|
||||
Volume vol = (Volume)content;
|
||||
return getVolumeDisplayName(vol);
|
||||
} else if (content instanceof Pool) {
|
||||
Pool pool = (Pool)content;
|
||||
return pool.getType().getName(); // We currently use the type name for both the name and type fields
|
||||
} else if (content instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile)content;
|
||||
return file.getName(); // GVDTODO handle . and .. from getContentDisplayName()
|
||||
}
|
||||
return content.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use this method if all rows contain AbstractFile objects.
|
||||
* Make sure the order here matches that in getCellValuesForAbstractFile();
|
||||
*
|
||||
* @return The list of column keys.
|
||||
*/
|
||||
static List<ColumnKey> getColumnKeysForAbstractfile() {
|
||||
List<ColumnKey> colKeys = new ArrayList<>();
|
||||
colKeys.add(NAME_COLUMN);
|
||||
colKeys.addAll(ABSTRACT_FILE_COLUMNS);
|
||||
return colKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use this method if all rows contain AbstractFile objects.
|
||||
* Make sure the order here matches that in getColumnKeysForAbstractfile();
|
||||
*
|
||||
* @param file The file to use to populate the cells.
|
||||
*
|
||||
* @return List of cell values.
|
||||
*/
|
||||
static List<Object> getCellValuesForAbstractFile(AbstractFile file) throws TskCoreException {
|
||||
List<Object> cells = new ArrayList<>();
|
||||
cells.add(getNameValueForContent(file));
|
||||
cells.addAll(getNonNameCellValuesForAbstractFile(file));
|
||||
return cells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the order here matches that in ABSTRACT_FILE_COLUMNS
|
||||
*
|
||||
* @param file
|
||||
* @param content The content to use to populate the cells (may not be an abstract file)
|
||||
*
|
||||
* @return
|
||||
* @return List of cell values
|
||||
*/
|
||||
static List<Object> getCellValuesForAbstractFile(AbstractFile file) throws TskCoreException {
|
||||
private static List<Object> getNonNameCellValuesForAbstractFile(Content content) throws TskCoreException {
|
||||
final int nColumns = 17;
|
||||
if (! (content instanceof AbstractFile)) {
|
||||
return Collections.nCopies(nColumns, null);
|
||||
}
|
||||
|
||||
// Make sure to update nColumns if the number of columns here changes
|
||||
AbstractFile file = (AbstractFile) content;
|
||||
return Arrays.asList(
|
||||
file.getName(), // GVDTODO handle . and .. from getContentDisplayName()
|
||||
// GVDTODO translation column
|
||||
null,
|
||||
//GVDTDO replace nulls with SCO
|
||||
@ -240,4 +305,109 @@ getColumnKey(Bundle.FileSystemColumnUtils_abstractFileColumns_mimeType()),
|
||||
file.getNameExtension()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the order here matches that in POOL_COLUMNS
|
||||
*
|
||||
* @param conent The content to use to populate the cells (may not be a pool)
|
||||
*
|
||||
* @return List of cell values
|
||||
*/
|
||||
private static List<Object> getNonNameCellValuesForPool(Content content) throws TskCoreException {
|
||||
final int nColumns = 1;
|
||||
if (! (content instanceof Pool)) {
|
||||
return Collections.nCopies(nColumns, null);
|
||||
}
|
||||
|
||||
// Make sure to update nColumns if the number of columns here changes
|
||||
Pool pool = (Pool) content;
|
||||
return Arrays.asList(
|
||||
pool.getType().getName() // We currently use the type name for both the name and type fields
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the order here matches that in HOST_COLUMNS
|
||||
*
|
||||
* @param host The host to use to populate the cells
|
||||
*
|
||||
* @return List of cell values
|
||||
*/
|
||||
static List<Object> getCellValuesForHost(Host host) throws TskCoreException {
|
||||
return Arrays.asList(
|
||||
host.getName()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the order here matches that in IMAGE_COLUMNS
|
||||
*
|
||||
* @param content The content to use to populate the cells (may not be an image)
|
||||
*
|
||||
* @return List of cell values
|
||||
*/
|
||||
private static List<Object> getNonNameCellValuesForImage(Content content) throws TskCoreException {
|
||||
final int nColumns = 5;
|
||||
if (! (content instanceof Image)) {
|
||||
return Collections.nCopies(nColumns, null);
|
||||
}
|
||||
|
||||
// Make sure to update nColumns if the number of columns here changes
|
||||
Image image = (Image) content;
|
||||
return Arrays.asList(
|
||||
Bundle.FileSystemColumnUtils_imageColumns_typeValue(),
|
||||
image.getSize(),
|
||||
image.getSsize(),
|
||||
image.getTimeZone(),
|
||||
image.getDeviceId()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the order here matches that in VOLUME_COLUMNS
|
||||
*
|
||||
* @param content The content to use to populate the cells (may not be a volume)
|
||||
*
|
||||
* @return List of cell values
|
||||
*/
|
||||
private static List<Object> getNonNameCellValuesForVolume(Content content) throws TskCoreException {
|
||||
final int nColumns = 5;
|
||||
if (! (content instanceof Volume)) {
|
||||
return Collections.nCopies(nColumns, null);
|
||||
}
|
||||
|
||||
// Make sure to update nColumns if the number of columns here changes
|
||||
Volume vol = (Volume) content;
|
||||
return Arrays.asList(
|
||||
vol.getAddr(),
|
||||
vol.getStart(),
|
||||
vol.getLength(),
|
||||
vol.getDescription(),
|
||||
vol.getFlagsAsString()
|
||||
);
|
||||
}
|
||||
|
||||
private static String getVolumeDisplayName(Volume vol) {
|
||||
// set name, display name, and icon
|
||||
String volName = "vol" + Long.toString(vol.getAddr());
|
||||
long end = vol.getStart() + (vol.getLength() - 1);
|
||||
String tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + "-" + end + ")";
|
||||
|
||||
// If this is a pool volume use a custom display name
|
||||
try {
|
||||
if (vol.getParent() != null
|
||||
&& vol.getParent().getParent() instanceof Pool) {
|
||||
// Pool volumes are not contiguous so printing a range of blocks is inaccurate
|
||||
tempVolName = volName + " (" + vol.getDescription() + ": " + vol.getStart() + ")";
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Error looking up parent(s) of volume with obj ID = " + vol.getId(), ex);
|
||||
}
|
||||
return tempVolName;
|
||||
}
|
||||
|
||||
private static ColumnKey getColumnKey(String name) {
|
||||
return new ColumnKey(name, name, Bundle.FileSystemColumnUtils_noDescription());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 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.mainui.datamodel;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Key for content object in order to retrieve data from DAO.
|
||||
*/
|
||||
public class FileSystemContentSearchParam {
|
||||
private final Long contentObjectId;
|
||||
|
||||
public FileSystemContentSearchParam(Long contentObjectId) {
|
||||
this.contentObjectId = contentObjectId;
|
||||
}
|
||||
|
||||
public Long getContentObjectId() {
|
||||
return contentObjectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 67 * hash + Objects.hashCode(this.contentObjectId);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FileSystemContentSearchParam other = (FileSystemContentSearchParam) obj;
|
||||
if (!Objects.equals(this.contentObjectId, other.contentObjectId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -20,7 +20,20 @@ package org.sleuthkit.autopsy.mainui.datamodel;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -29,7 +42,7 @@ public class FileSystemDAO {
|
||||
private static final int CACHE_SIZE = 15; // rule of thumb: 5 entries times number of cached SearchParams sub-types
|
||||
private static final long CACHE_DURATION = 2;
|
||||
private static final TimeUnit CACHE_DURATION_UNITS = TimeUnit.MINUTES;
|
||||
private final Cache<SearchParams<?>, SearchResultsDTO> searchParamsCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).expireAfterAccess(CACHE_DURATION, CACHE_DURATION_UNITS).build();
|
||||
private final Cache<SearchParams<?>, BaseSearchResultsDTO> searchParamsCache = CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).expireAfterAccess(CACHE_DURATION, CACHE_DURATION_UNITS).build();
|
||||
|
||||
private static final String FILE_SYSTEM_TYPE_ID = "FILE_SYSTEM";
|
||||
|
||||
@ -42,5 +55,105 @@ public class FileSystemDAO {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private BaseSearchResultsDTO fetchContentForTableFromContent(SearchParams<FileSystemContentSearchParam> cacheKey) throws NoCurrentCaseException, TskCoreException {
|
||||
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
|
||||
Long objectId = cacheKey.getParamData().getContentObjectId();
|
||||
List<Content> contentForTable = new ArrayList<>();
|
||||
String parentName = "";
|
||||
Content parentContent = skCase.getContentById(objectId);
|
||||
if (parentContent != null) {
|
||||
parentName = parentContent.getName();
|
||||
for (Content content : parentContent.getChildren()) {
|
||||
if (FileSystemColumnUtils.isDisplayable(content)) {
|
||||
contentForTable.add(content);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The parent object may be a Host
|
||||
Optional<Host> host = skCase.getHostManager().getHostById(objectId);
|
||||
if (host.isPresent()) {
|
||||
parentName = host.get().getName();
|
||||
contentForTable.addAll(skCase.getHostManager().getDataSourcesForHost(host.get()));
|
||||
} else {
|
||||
throw new TskCoreException("Error loading children of object with ID " + objectId + " - ID not found in tsk_objects or tsk_hosts");
|
||||
}
|
||||
}
|
||||
return fetchContentForTable(cacheKey, contentForTable, parentName);
|
||||
}
|
||||
|
||||
private BaseSearchResultsDTO fetchContentForTableFromHost(SearchParams<FileSystemHostSearchParam> cacheKey) throws NoCurrentCaseException, TskCoreException {
|
||||
|
||||
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||
|
||||
Long objectId = cacheKey.getParamData().getHostObjectId();
|
||||
List<Content> contentForTable = new ArrayList<>();
|
||||
String parentName = "";
|
||||
Optional<Host> host = skCase.getHostManager().getHostById(objectId);
|
||||
if (host.isPresent()) {
|
||||
parentName = host.get().getName();
|
||||
contentForTable.addAll(skCase.getHostManager().getDataSourcesForHost(host.get()));
|
||||
} else {
|
||||
throw new TskCoreException("Error loading children of object with ID " + objectId + " - ID not found in tsk_objects or tsk_hosts");
|
||||
}
|
||||
return fetchContentForTable(cacheKey, contentForTable, parentName);
|
||||
}
|
||||
|
||||
|
||||
private BaseSearchResultsDTO fetchContentForTable(SearchParams<?> cacheKey, List<Content> contentForTable,
|
||||
String parentName) throws NoCurrentCaseException, TskCoreException {
|
||||
// Ensure consistent columns for each page by doing this before paging
|
||||
List<FileSystemColumnUtils.ContentType> displayableTypes = FileSystemColumnUtils.getDisplayableTypesForContentList(contentForTable);
|
||||
|
||||
List<Content> pagedContent = getPaged(contentForTable, cacheKey);
|
||||
List<ColumnKey> columnKeys = FileSystemColumnUtils.getColumnKeysForContent(displayableTypes);
|
||||
|
||||
List<RowDTO> rows = new ArrayList<>();
|
||||
for (Content content : pagedContent) {
|
||||
List<Object> cellValues = FileSystemColumnUtils.getCellValuesForContent(content, displayableTypes);
|
||||
rows.add(new BaseRowDTO(cellValues, FILE_SYSTEM_TYPE_ID, content.getId()));
|
||||
}
|
||||
return new BaseSearchResultsDTO(FILE_SYSTEM_TYPE_ID, parentName, columnKeys, rows, cacheKey.getStartItem(), contentForTable.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of paged content.
|
||||
*
|
||||
* @param contentObjects The content objects.
|
||||
* @param searchParams The search parameters including the paging.
|
||||
*
|
||||
* @return The list of paged artifacts.
|
||||
*/
|
||||
List<Content> getPaged(List<? extends Content> contentObjects, SearchParams<?> searchParams) {
|
||||
Stream<? extends Content> pagedArtsStream = contentObjects.stream()
|
||||
.sorted(Comparator.comparing((conent) -> conent.getId()))
|
||||
.skip(searchParams.getStartItem());
|
||||
|
||||
if (searchParams.getMaxResultsCount() != null) {
|
||||
pagedArtsStream = pagedArtsStream.limit(searchParams.getMaxResultsCount());
|
||||
}
|
||||
|
||||
return pagedArtsStream.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public BaseSearchResultsDTO getContentForTable(FileSystemContentSearchParam objectKey, long startItem, Long maxCount, boolean hardRefresh) throws ExecutionException, IllegalArgumentException {
|
||||
|
||||
SearchParams<FileSystemContentSearchParam> searchParams = new SearchParams<>(objectKey, startItem, maxCount);
|
||||
if (hardRefresh) {
|
||||
searchParamsCache.invalidate(searchParams);
|
||||
}
|
||||
|
||||
return searchParamsCache.get(searchParams, () -> fetchContentForTableFromContent(searchParams));
|
||||
}
|
||||
|
||||
public BaseSearchResultsDTO getContentForTable(FileSystemHostSearchParam objectKey, long startItem, Long maxCount, boolean hardRefresh) throws ExecutionException, IllegalArgumentException {
|
||||
|
||||
SearchParams<FileSystemHostSearchParam> searchParams = new SearchParams<>(objectKey, startItem, maxCount);
|
||||
if (hardRefresh) {
|
||||
searchParamsCache.invalidate(searchParams);
|
||||
}
|
||||
|
||||
return searchParamsCache.get(searchParams, () -> fetchContentForTableFromHost(searchParams));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2021 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.mainui.datamodel;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Key for content object in order to retrieve data from DAO.
|
||||
*/
|
||||
public class FileSystemHostSearchParam {
|
||||
private final Long hostObjectId;
|
||||
|
||||
public FileSystemHostSearchParam(Long hostObjectId) {
|
||||
this.hostObjectId = hostObjectId;
|
||||
}
|
||||
|
||||
public Long getHostObjectId() {
|
||||
return hostObjectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 67 * hash + Objects.hashCode(this.hostObjectId);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FileSystemHostSearchParam other = (FileSystemHostSearchParam) obj;
|
||||
if (!Objects.equals(this.hostObjectId, other.hostObjectId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public class MainDAO {
|
||||
private final DataArtifactDAO dataArtifactDAO = DataArtifactDAO.getInstance();
|
||||
private final AnalysisResultDAO analysisResultDAO = AnalysisResultDAO.getInstance();
|
||||
private final ViewsDAO viewsDAO = ViewsDAO.getInstance();
|
||||
private final FileSystemDAO fileSystemDAO = FileSystemDAO.getInstance();
|
||||
|
||||
public DataArtifactDAO getDataArtifactsDAO() {
|
||||
return dataArtifactDAO;
|
||||
@ -49,4 +50,8 @@ public class MainDAO {
|
||||
public ViewsDAO getViewsDAO() {
|
||||
return viewsDAO;
|
||||
}
|
||||
|
||||
public FileSystemDAO getFileSystemDAO() {
|
||||
return fileSystemDAO;
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +328,7 @@ public class ViewsDAO {
|
||||
cellValues));
|
||||
}
|
||||
|
||||
return new BaseSearchResultsDTO(FILE_VIEW_EXT_TYPE_ID, displayName, FileSystemColumnUtils.ABSTRACT_FILE_COLUMNS, fileRows, startItem, totalResultsCount);
|
||||
return new BaseSearchResultsDTO(FILE_VIEW_EXT_TYPE_ID, displayName, FileSystemColumnUtils.getColumnKeysForAbstractfile(), fileRows, startItem, totalResultsCount);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,7 @@ import org.sleuthkit.autopsy.testutils.CaseUtils;
|
||||
import org.sleuthkit.autopsy.testutils.TestUtilsException;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.AnalysisResult;
|
||||
import org.sleuthkit.datamodel.Attribute;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@ -43,10 +44,18 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.DataArtifact;
|
||||
import org.sleuthkit.datamodel.DataSource;
|
||||
import org.sleuthkit.datamodel.FileSystem;
|
||||
import org.sleuthkit.datamodel.FsContent;
|
||||
import org.sleuthkit.datamodel.Host;
|
||||
import org.sleuthkit.datamodel.Pool;
|
||||
import org.sleuthkit.datamodel.Image;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.Volume;
|
||||
import org.sleuthkit.datamodel.VolumeSystem;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@ -123,6 +132,19 @@ public class TableSearchTest extends NbTestCase {
|
||||
// Keyword hits test
|
||||
AnalysisResult keywordHitAnalysisResult = null; // A keyword hit
|
||||
Content keywordHitSource = null; // The source of the keyword hit above
|
||||
|
||||
// File system test
|
||||
Host fsTestHostA = null; // A host
|
||||
Image fsTestImageA = null; // An image
|
||||
VolumeSystem fsTestVsA = null; // A volume system
|
||||
Volume fsTestVolumeA1 = null; // A volume
|
||||
Volume fsTestVolumeA2 = null; // Another volume
|
||||
Volume fsTestVolumeA3 = null; // Another volume
|
||||
FileSystem fsTestFsA = null; // A file system
|
||||
AbstractFile fsTestRootDirA = null; // The root directory
|
||||
Image fsTestImageB = null; // Another image
|
||||
Volume fsTestVolumeB1 = null; // Another volume
|
||||
Pool fsTestPoolB = null; // A pool
|
||||
|
||||
public static Test suite() {
|
||||
NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(TableSearchTest.class).
|
||||
@ -148,12 +170,14 @@ public class TableSearchTest extends NbTestCase {
|
||||
mimeSearchTest();
|
||||
extensionSearchTest();
|
||||
sizeSearchTest();
|
||||
fileSystemTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a case and add sample data.
|
||||
*/
|
||||
private void setUpCaseDatabase() {
|
||||
SleuthkitCase.CaseDbTransaction trans = null;
|
||||
try {
|
||||
// Create a test case
|
||||
openCase = CaseUtils.createAsCurrentCase("testTableSearchCase");
|
||||
@ -161,11 +185,12 @@ public class TableSearchTest extends NbTestCase {
|
||||
blackboard = db.getBlackboard();
|
||||
|
||||
// Add two logical files data sources
|
||||
SleuthkitCase.CaseDbTransaction trans = db.beginTransaction();
|
||||
trans = db.beginTransaction();
|
||||
dataSource1 = db.addLocalFilesDataSource("devId1", "C:\\Fake\\Path\\1", "EST", null, trans);
|
||||
dataSource2 = db.addLocalFilesDataSource("devId2", "C:\\Fake\\Path\\2", "EST", null, trans);
|
||||
dataSource3 = db.addLocalFilesDataSource("devId3", "C:\\Fake\\Path\\3", "EST", null, trans);
|
||||
trans.commit();
|
||||
trans = null;
|
||||
|
||||
// Add files
|
||||
AbstractFile folderA1 = db.addLocalDirectory(dataSource1.getId(), "folder1");
|
||||
@ -306,7 +331,81 @@ public class TableSearchTest extends NbTestCase {
|
||||
null, KEYWORD_SET_1, null, attrs).getAnalysisResult();
|
||||
keywordHitSource = hashHitAnalysisResult;
|
||||
|
||||
// Create a normal image
|
||||
// fsTestImageA (Host: fsTestHostA)
|
||||
// - fsTestVsA
|
||||
// -- fsTestVolumeA1
|
||||
// --- fsTestFsA
|
||||
// ---- fsTestRootDirA
|
||||
// ----- (3 files)
|
||||
// -- fsTestVolumeA2
|
||||
// -- fsTestVolumeA3
|
||||
fsTestHostA = db.getHostManager().newHost("File system test host");
|
||||
trans = db.beginTransaction();
|
||||
fsTestImageA = db.addImage(TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_DETECT, 512, 1024, "image1", Arrays.asList("C:\\Fake\\Path\\4"),
|
||||
"EST", null, null, null, "deviceID12345", fsTestHostA, trans);
|
||||
fsTestVsA = db.addVolumeSystem(fsTestImageA.getId(), TskData.TSK_VS_TYPE_ENUM.TSK_VS_TYPE_DOS, 0, 1024, trans);
|
||||
fsTestVolumeA1 = db.addVolume(fsTestVsA.getId(), 0, 0, 512, "Test vol A1", 0, trans);
|
||||
fsTestVolumeA2 = db.addVolume(fsTestVsA.getId(), 1, 512, 512, "Test vol A2", 0, trans);
|
||||
fsTestVolumeA3 = db.addVolume(fsTestVsA.getId(), 2, 1024, 512, "Test vol A3", 0, trans);
|
||||
fsTestFsA = db.addFileSystem(fsTestVolumeA1.getId(), 0, TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_EXT2, 512, 1,
|
||||
1, 1, 10, "Test file system", trans);
|
||||
trans.commit();
|
||||
trans = null;
|
||||
fsTestRootDirA = db.addFileSystemFile(fsTestImageA.getId(), fsTestFsA.getId(),
|
||||
"", 0, 0,
|
||||
TskData.TSK_FS_ATTR_TYPE_ENUM.TSK_FS_ATTR_TYPE_DEFAULT, 0,
|
||||
TskData.TSK_FS_NAME_FLAG_ENUM.ALLOC, (short)0, 128,
|
||||
0, 0, 0, 0, false, fsTestFsA);
|
||||
db.addFileSystemFile(fsTestImageA.getId(), fsTestFsA.getId(),
|
||||
"Test file 1", 0, 0,
|
||||
TskData.TSK_FS_ATTR_TYPE_ENUM.TSK_FS_ATTR_TYPE_DEFAULT, 0,
|
||||
TskData.TSK_FS_NAME_FLAG_ENUM.ALLOC, (short)0, 123,
|
||||
0, 0, 0, 0, false, fsTestRootDirA);
|
||||
db.addFileSystemFile(fsTestImageA.getId(), fsTestFsA.getId(),
|
||||
"Test file 2", 0, 0,
|
||||
TskData.TSK_FS_ATTR_TYPE_ENUM.TSK_FS_ATTR_TYPE_DEFAULT, 0,
|
||||
TskData.TSK_FS_NAME_FLAG_ENUM.ALLOC, (short)0, 456,
|
||||
0, 0, 0, 0, false, fsTestRootDirA);
|
||||
db.addFileSystemFile(fsTestImageA.getId(), fsTestFsA.getId(),
|
||||
"Test file 3", 0, 0,
|
||||
TskData.TSK_FS_ATTR_TYPE_ENUM.TSK_FS_ATTR_TYPE_DEFAULT, 0,
|
||||
TskData.TSK_FS_NAME_FLAG_ENUM.ALLOC, (short)0, 789,
|
||||
0, 0, 0, 0, false, fsTestRootDirA);
|
||||
|
||||
// Create an image with some odd structures for testing
|
||||
trans = db.beginTransaction();
|
||||
fsTestImageB = db.addImage(TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_DETECT, 512, 1024, "image2", Arrays.asList("C:\\Fake\\Path\\5"),
|
||||
"EST", null, null, null, "deviceID678", fsTestHostA, trans);
|
||||
|
||||
// Images can have VS, pool, FS, file, artifact, and report children.
|
||||
// Add a VS, pool, and local file
|
||||
VolumeSystem vsB = db.addVolumeSystem(fsTestImageB.getId(), TskData.TSK_VS_TYPE_ENUM.TSK_VS_TYPE_BSD, 0, 2048, trans);
|
||||
db.addPool(fsTestImageB.getId(), TskData.TSK_POOL_TYPE_ENUM.TSK_POOL_TYPE_APFS, trans);
|
||||
db.addLocalFile("Test local file B1", "C:\\Fake\\Path\\6", 6000, 0, 0, 0, 0,
|
||||
true, TskData.EncodingType.NONE, fsTestImageB, trans);
|
||||
|
||||
// Volumes can have pool, FS, file, and artifact children
|
||||
fsTestVolumeB1 = db.addVolume(vsB.getId(), 0, 0, 512, "Test vol B1", 0, trans);
|
||||
fsTestPoolB = db.addPool(fsTestVolumeB1.getId(), TskData.TSK_POOL_TYPE_ENUM.TSK_POOL_TYPE_APFS, trans);
|
||||
db.addLocalFile("Test local file B2", "C:\\Fake\\Path\\7", 7000, 0, 0, 0, 0,
|
||||
true, TskData.EncodingType.NONE, fsTestVolumeB1, trans);
|
||||
|
||||
// Pools can have VS, file, and artifact children
|
||||
db.addVolumeSystem(fsTestPoolB.getId(), TskData.TSK_VS_TYPE_ENUM.TSK_VS_TYPE_GPT, 0, 2048, trans);
|
||||
db.addLocalFile("Test local file B3", "C:\\Fake\\Path\\8", 8000, 0, 0, 0, 0,
|
||||
true, TskData.EncodingType.NONE, fsTestPoolB, trans);
|
||||
|
||||
trans.commit();
|
||||
trans = null;
|
||||
} catch (TestUtilsException | TskCoreException | BlackboardException ex) {
|
||||
if (trans != null) {
|
||||
try {
|
||||
trans.rollback();
|
||||
} catch (TskCoreException ex2) {
|
||||
ex2.printStackTrace();
|
||||
}
|
||||
}
|
||||
Exceptions.printStackTrace(ex);
|
||||
Assert.fail(ex.getMessage());
|
||||
}
|
||||
@ -611,7 +710,7 @@ public class TableSearchTest extends NbTestCase {
|
||||
Exceptions.printStackTrace(ex);
|
||||
Assert.fail(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void extensionSearchTest() {
|
||||
// Quick test that everything is initialized
|
||||
@ -673,6 +772,79 @@ public class TableSearchTest extends NbTestCase {
|
||||
Assert.fail(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void fileSystemTest() {
|
||||
// Quick test that everything is initialized
|
||||
assertTrue(db != null);
|
||||
|
||||
try {
|
||||
FileSystemDAO fileSystemDAO = MainDAO.getInstance().getFileSystemDAO();
|
||||
|
||||
// HostA is associated with two images
|
||||
FileSystemHostSearchParam hostParam = new FileSystemHostSearchParam(fsTestHostA.getHostId());
|
||||
BaseSearchResultsDTO results = fileSystemDAO.getContentForTable(hostParam, 0, null, false);
|
||||
assertEquals(2, results.getTotalResultsCount());
|
||||
assertEquals(2, results.getItems().size());
|
||||
|
||||
// ImageA has one volumne system child which we don't display
|
||||
FileSystemContentSearchParam param = new FileSystemContentSearchParam(fsTestImageA.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(0, results.getTotalResultsCount());
|
||||
assertEquals(0, results.getItems().size());
|
||||
|
||||
// VsA has three volume children
|
||||
param = new FileSystemContentSearchParam(fsTestVsA.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(3, results.getTotalResultsCount());
|
||||
assertEquals(3, results.getItems().size());
|
||||
|
||||
// VolumeA1 has a file system child which we don't display
|
||||
param = new FileSystemContentSearchParam(fsTestVolumeA1.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(0, results.getTotalResultsCount());
|
||||
assertEquals(0, results.getItems().size());
|
||||
|
||||
// FsA has the root folder as its child. We don't actually display this,
|
||||
// but I'm not sure the DAO is responible for figuring that out.
|
||||
param = new FileSystemContentSearchParam(fsTestFsA.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(1, results.getTotalResultsCount());
|
||||
assertEquals(1, results.getItems().size());
|
||||
|
||||
// The root dir contains three files
|
||||
param = new FileSystemContentSearchParam(fsTestRootDirA.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(3, results.getTotalResultsCount());
|
||||
assertEquals(3, results.getItems().size());
|
||||
|
||||
// ImageB has VS (not displayed), pool, and one local file children
|
||||
param = new FileSystemContentSearchParam(fsTestImageB.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(2, results.getTotalResultsCount());
|
||||
assertEquals(2, results.getItems().size());
|
||||
|
||||
// Check that we have the "Type" column from the Pool and the "Known" column from the file
|
||||
List<String> columnDisplayNames = results.getColumns().stream().map(p -> p.getDisplayName()).collect(Collectors.toList());
|
||||
assertTrue(columnDisplayNames.contains("Type"));
|
||||
assertTrue(columnDisplayNames.contains("Known"));
|
||||
|
||||
// fsTestVolumeB1 has pool and one local file children
|
||||
param = new FileSystemContentSearchParam(fsTestVolumeB1.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(2, results.getTotalResultsCount());
|
||||
assertEquals(2, results.getItems().size());
|
||||
|
||||
// fsTestPoolB has VS (not displayed) and local file children
|
||||
param = new FileSystemContentSearchParam(fsTestPoolB.getId());
|
||||
results = fileSystemDAO.getContentForTable(param, 0, null, false);
|
||||
assertEquals(1, results.getTotalResultsCount());
|
||||
assertEquals(1, results.getItems().size());
|
||||
|
||||
} catch (ExecutionException ex) {
|
||||
Exceptions.printStackTrace(ex);
|
||||
Assert.fail(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private enum CustomRootFilter implements FileExtSearchFilter {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user