Merge remote-tracking branch 'upstream/develop' into 3468_ArtifactHits

This commit is contained in:
U-BASIS\dgrove 2018-02-12 14:05:10 -05:00
commit 037142917e
31 changed files with 4696 additions and 112 deletions

View File

@ -489,12 +489,16 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
corAttrInstances.addAll(getCorrelatedInstances(corAttr, dataSourceName, deviceId));
corAttrInstances.forEach((corAttrInstance) -> {
try {
CorrelationAttribute newCeArtifact = new CorrelationAttribute(
corAttr.getCorrelationType(),
corAttr.getCorrelationValue()
);
newCeArtifact.addInstance(corAttrInstance);
tableModel.addEamArtifact(newCeArtifact);
} catch (EamDbException ex){
LOGGER.log(Level.SEVERE, "Error creating correlation attribute", ex);
}
});
}

View File

@ -271,6 +271,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void updateCase(CorrelationCase eamCase) throws EamDbException {
if(eamCase == null) {
throw new EamDbException("CorrelationCase argument is null");
}
Connection conn = connect();
PreparedStatement preparedStatement = null;
@ -444,6 +448,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
if(correlationCase == null) {
throw new EamDbException("CorrelationCase argument is null");
}
Connection conn = connect();
CorrelationDataSource eamDataSourceResult = null;
@ -513,6 +521,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
if(eamArtifact == null) {
throw new EamDbException("CorrelationAttribute is null");
}
if(eamArtifact.getCorrelationType() == null) {
throw new EamDbException("Correlation type is null");
}
if(eamArtifact.getCorrelationValue() == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect();
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
@ -531,6 +549,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql.toString());
for (CorrelationAttributeInstance eamInstance : eamInstances) {
if (!eamArtifact.getCorrelationValue().isEmpty()) {
if(eamInstance.getCorrelationCase() == null) {
throw new EamDbException("CorrelationAttributeInstance has null case");
}
if(eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("CorrelationAttributeInstance has null data source");
}
if(eamInstance.getKnownStatus() == null) {
throw new EamDbException("CorrelationAttributeInstance has null known status");
}
preparedStatement.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
preparedStatement.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
preparedStatement.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
@ -567,6 +595,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
@ -619,6 +650,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
if(filePath == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect();
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
@ -641,7 +678,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
try {
preparedStatement = conn.prepareStatement(sql.toString());
preparedStatement.setString(1, filePath);
preparedStatement.setString(1, filePath.toLowerCase());
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
artifactInstance = getEamArtifactInstanceFromResultSet(resultSet);
@ -670,6 +707,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
if(value == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect();
Long instanceCount = 0L;
@ -684,7 +728,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
try {
preparedStatement = conn.prepareStatement(sql.toString());
preparedStatement.setString(1, value);
preparedStatement.setString(1, value.toLowerCase());
resultSet = preparedStatement.executeQuery();
resultSet.next();
instanceCount = resultSet.getLong(1);
@ -701,6 +745,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override
public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException {
if (corAttr == null) {
throw new EamDbException("Correlation attribute is null");
}
Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
@ -719,6 +766,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
Long instanceCount = 0L;
@ -840,6 +891,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override
public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
if(eamArtifact.getCorrelationType() == null) {
throw new EamDbException("Correlation type is null");
}
synchronized (bulkArtifacts) {
bulkArtifacts.get(eamArtifact.getCorrelationType().getDbTableName()).add(eamArtifact);
bulkArtifactsCount++;
@ -893,6 +948,17 @@ public abstract class AbstractSqlEamDb implements EamDb {
for (CorrelationAttributeInstance eamInstance : eamInstances) {
if (!eamArtifact.getCorrelationValue().isEmpty()) {
if(eamInstance.getCorrelationCase() == null) {
throw new EamDbException("Correlation attribute instance has null case");
}
if(eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("Correlation attribute instance has null data source");
}
if(eamInstance.getKnownStatus()== null) {
throw new EamDbException("Correlation attribute instance has null known known status");
}
bulkPs.setString(1, eamInstance.getCorrelationCase().getCaseUUID());
bulkPs.setString(2, eamInstance.getCorrelationDataSource().getDeviceID());
bulkPs.setInt(3, eamInstance.getCorrelationDataSource().getCaseID());
@ -929,12 +995,16 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
Connection conn = connect();
if(cases == null) {
throw new EamDbException("cases argument is null");
}
if (cases.isEmpty()) {
return;
}
Connection conn = connect();
int counter = 0;
PreparedStatement bulkPs = null;
try {
@ -1012,8 +1082,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
Connection conn = connect();
if(eamArtifact == null) {
throw new EamDbException("Correlation attribute is null");
}
if(knownStatus == null) {
throw new EamDbException("Known status is null");
}
if (1 != eamArtifact.getInstances().size()) {
throw new EamDbException("Error: Artifact must have exactly one (1) Artifact Instance to set as notable."); // NON-NLS
}
@ -1021,6 +1095,15 @@ public abstract class AbstractSqlEamDb implements EamDb {
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
CorrelationAttributeInstance eamInstance = eamInstances.get(0);
if(eamInstance.getCorrelationCase() == null) {
throw new EamDbException("Correlation case is null");
}
if(eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("Correlation data source is null");
}
Connection conn = connect();
PreparedStatement preparedUpdate = null;
PreparedStatement preparedQuery = null;
ResultSet resultSet = null;
@ -1103,6 +1186,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
List<CorrelationAttributeInstance> artifactInstances = new ArrayList<>();
@ -1153,6 +1240,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
Long badInstances = 0L;
@ -1197,6 +1288,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
Collection<String> caseNames = new LinkedHashSet<>();
@ -1382,6 +1477,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
throw new EamDbException("null correlation type");
}
// TEMP: Only support file correlation type
if (aType.getId() != CorrelationAttribute.FILES_TYPE_ID) {
@ -1424,6 +1522,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public long newOrganization(EamOrganization eamOrg) throws EamDbException {
if(eamOrg == null) {
throw new EamDbException("EamOrganization is null");
}
Connection conn = connect();
ResultSet generatedKeys = null;
PreparedStatement preparedStatement = null;
@ -1529,6 +1631,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException {
EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
if(globalSet == null) {
throw new EamDbException("Reference set with ID " + referenceSetID + " not found");
}
return (getOrganizationByID(globalSet.getOrgID()));
}
@ -1542,6 +1647,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
if(updatedOrganization == null) {
throw new EamDbException("null updatedOrganization");
}
Connection conn = connect();
PreparedStatement preparedStatement = null;
String sql = "UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
@ -1566,6 +1675,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
"AbstractSqlEamDb.deleteOrganization.errorDeleting.message=Error executing query when attempting to delete organization by id."})
@Override
public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
if(organizationToDelete == null) {
throw new EamDbException("Organization to delete is null");
}
Connection conn = connect();
PreparedStatement checkIfUsedStatement = null;
ResultSet resultSet = null;
@ -1605,6 +1718,18 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
if(eamGlobalSet == null){
throw new EamDbException("EamGlobalSet argument is null");
}
if(eamGlobalSet.getFileKnownStatus() == null){
throw new EamDbException("File known status on the EamGlobalSet is null");
}
if(eamGlobalSet.getType() == null){
throw new EamDbException("Type on the EamGlobalSet is null");
}
Connection conn = connect();
PreparedStatement preparedStatement1 = null;
@ -1666,8 +1791,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement1 = conn.prepareStatement(sql1);
preparedStatement1.setInt(1, referenceSetID);
resultSet = preparedStatement1.executeQuery();
resultSet.next();
if(resultSet.next()) {
return getEamGlobalSetFromResultSet(resultSet);
} else {
return null;
}
} catch (SQLException ex) {
throw new EamDbException("Error getting reference set by id.", ex); // NON-NLS
@ -1689,6 +1817,11 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
if(correlationType == null){
throw new EamDbException("Correlation type is null");
}
List<EamGlobalSet> results = new ArrayList<>();
Connection conn = connect();
@ -1723,6 +1856,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
if(eamGlobalFileInstance.getKnownStatus() == null){
throw new EamDbException("known status of EamGlobalFileInstance is null");
}
if(correlationType == null){
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
PreparedStatement preparedStatement = null;
@ -1786,6 +1926,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
if(contentType == null) {
throw new EamDbException("Null correlation type");
}
if(globalInstances == null) {
throw new EamDbException("Null set of EamGlobalFileInstance");
}
Connection conn = connect();
PreparedStatement bulkPs = null;
@ -1799,6 +1946,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType)));
for (EamGlobalFileInstance globalInstance : globalInstances) {
if(globalInstance.getKnownStatus() == null){
throw new EamDbException("EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + " has null known status");
}
bulkPs.setInt(1, globalInstance.getGlobalSetID());
bulkPs.setString(2, globalInstance.getMD5Hash());
bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
@ -1808,7 +1959,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkPs.executeBatch();
conn.commit();
} catch (SQLException ex) {
} catch (SQLException | EamDbException ex) {
try {
conn.rollback();
} catch (SQLException ex2) {
@ -1833,6 +1984,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
if(aType == null) {
throw new EamDbException("correlation type is null");
}
Connection conn = connect();
List<EamGlobalFileInstance> globalFileInstances = new ArrayList<>();
@ -1869,6 +2024,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException {
if (newType == null) {
throw new EamDbException("null correlation type");
}
Connection conn = connect();
PreparedStatement preparedStatement = null;
@ -1883,7 +2042,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
} else {
insertSql = "INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
}
querySql = "SELECT id FROM correlation_types WHERE display_name=? AND db_table_name=?";
querySql = "SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
try {
preparedStatement = conn.prepareStatement(insertSql);
@ -2073,9 +2232,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1, typeId);
resultSet = preparedStatement.executeQuery();
resultSet.next();
if(resultSet.next()) {
aType = getCorrelationTypeFromResultSet(resultSet);
return aType;
} else {
throw new EamDbException("Failed to find entry for correlation type ID = " + typeId);
}
} catch (SQLException ex) {
throw new EamDbException("Error getting correlation type by id.", ex); // NON-NLS
@ -2131,8 +2293,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
}
CorrelationDataSource eamDataSource = new CorrelationDataSource(
resultSet.getInt("id"),
resultSet.getInt("case_id"),
resultSet.getInt("id"),
resultSet.getString("device_id"),
resultSet.getString("name")
);
@ -2166,7 +2328,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*
* @throws SQLException when an expected column name is not in the resultSet
*/
private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException {
private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
if (null == resultSet) {
return null;
}
@ -2216,7 +2378,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
return eamGlobalSet;
}
private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException {
private EamGlobalFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
if (null == resultSet) {
return null;
}

View File

@ -28,7 +28,7 @@ import org.openide.util.NbBundle.Messages;
/**
* Represents a type and value pair that can be used for correlation.
* CorrelationAttributeInstances store information about the actual
* occurences of the attribute.
* occurrences of the attribute.
*/
public class CorrelationAttribute implements Serializable {
@ -66,7 +66,10 @@ public class CorrelationAttribute implements Serializable {
return DEFAULT_CORRELATION_TYPES;
}
public CorrelationAttribute(Type correlationType, String correlationValue) {
public CorrelationAttribute(Type correlationType, String correlationValue) throws EamDbException {
if(correlationValue == null) {
throw new EamDbException ("Correlation value is null");
}
this.ID = "";
this.correlationType = correlationType;
// Lower-case all values to normalize and improve correlation hits, going forward make sure this makes sense for all correlation types
@ -181,9 +184,12 @@ public class CorrelationAttribute implements Serializable {
* Must start with a lowercase letter and only contain
* lowercase letters, numbers, and '_' characters.
* @param supported Is this Type currently supported
* @param enabled Is this Type currentl enabled.
* @param enabled Is this Type currently enabled.
*/
public Type(int id, String displayName, String dbTableName, Boolean supported, Boolean enabled) throws EamDbException {
if(dbTableName == null) {
throw new EamDbException("dbTableName is null");
}
this.id = id;
this.displayName = displayName;
this.dbTableName = dbTableName;
@ -195,7 +201,7 @@ public class CorrelationAttribute implements Serializable {
}
/**
* Constructior for custom types where we do not know the Type ID until
* Constructor for custom types where we do not know the Type ID until
* the row has been entered into the correlation_types table
* in the central repository.
*
@ -204,7 +210,7 @@ public class CorrelationAttribute implements Serializable {
* Must start with a lowercase letter and only contain
* lowercase letters, numbers, and '_' characters.
* @param supported Is this Type currently supported
* @param enabled Is this Type currentl enabled.
* @param enabled Is this Type currently enabled.
*/
public Type(String displayName, String dbTableName, Boolean supported, Boolean enabled) throws EamDbException {
this(-1, displayName, dbTableName, supported, enabled);

View File

@ -46,7 +46,7 @@ public class CorrelationAttributeInstance implements Serializable {
public CorrelationAttributeInstance(
CorrelationCase eamCase,
CorrelationDataSource eamDataSource
) {
) throws EamDbException {
this(-1, eamCase, eamDataSource, "", null, TskData.FileKnown.UNKNOWN);
}
@ -54,7 +54,7 @@ public class CorrelationAttributeInstance implements Serializable {
CorrelationCase eamCase,
CorrelationDataSource eamDataSource,
String filePath
) {
) throws EamDbException {
this(-1, eamCase, eamDataSource, filePath, null, TskData.FileKnown.UNKNOWN);
}
@ -63,7 +63,7 @@ public class CorrelationAttributeInstance implements Serializable {
CorrelationDataSource eamDataSource,
String filePath,
String comment
) {
) throws EamDbException {
this(-1, eamCase, eamDataSource, filePath, comment, TskData.FileKnown.UNKNOWN);
}
@ -73,7 +73,7 @@ public class CorrelationAttributeInstance implements Serializable {
String filePath,
String comment,
TskData.FileKnown knownStatus
) {
) throws EamDbException {
this(-1, eamCase, eamDataSource, filePath, comment, knownStatus);
}
@ -84,7 +84,11 @@ public class CorrelationAttributeInstance implements Serializable {
String filePath,
String comment,
TskData.FileKnown knownStatus
) {
) throws EamDbException {
if(filePath == null) {
throw new EamDbException("file path is null");
}
this.ID = ID;
this.correlationCase = eamCase;
this.correlationDataSource = eamDataSource;

View File

@ -50,6 +50,10 @@ public class CorrelationCase implements Serializable {
* @param caseUUID Globally unique identifier
* @param displayName
*/
public CorrelationCase(String caseUUID, String displayName) {
this(-1, caseUUID, displayName);
}
CorrelationCase(int ID, String caseUUID, String displayName) {
this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null);
}
@ -156,7 +160,7 @@ public class CorrelationCase implements Serializable {
/**
* @return the database ID for the case or -1 if it is unknown (or not in the DB)
*/
int getID() {
public int getID() {
// @@@ Should probably have some lazy logic here to lead the ID from the DB if it is -1
return databaseId;
}

View File

@ -38,6 +38,16 @@ public class CorrelationDataSource implements Serializable {
private final String deviceID; //< Unique to its associated case (not necessarily globally unique)
private final String name;
/**
*
* @param caseId
* @param deviceId
* @param name
*/
public CorrelationDataSource(int caseId, String deviceId, String name) {
this(caseId, -1, deviceId, name);
}
CorrelationDataSource(int caseId,
int dataSourceId,
String deviceId,

View File

@ -135,7 +135,8 @@ public class EamArtifactUtil {
* @return the new EamArtifact, or null if one was not created because
* bbArtifact did not contain the needed data
*/
private static CorrelationAttribute getCorrelationAttributeFromBlackboardArtifact(CorrelationAttribute.Type correlationType, BlackboardArtifact bbArtifact) {
private static CorrelationAttribute getCorrelationAttributeFromBlackboardArtifact(CorrelationAttribute.Type correlationType,
BlackboardArtifact bbArtifact) throws EamDbException {
String value = null;
int artifactTypeID = bbArtifact.getArtifactTypeID();

View File

@ -36,7 +36,7 @@ public class EamGlobalFileInstance {
int globalSetID,
String MD5Hash,
TskData.FileKnown knownStatus,
String comment) {
String comment) throws EamDbException {
this(-1, globalSetID, MD5Hash, knownStatus, comment);
}
@ -45,7 +45,13 @@ public class EamGlobalFileInstance {
int globalSetID,
String MD5Hash,
TskData.FileKnown knownStatus,
String comment) {
String comment) throws EamDbException {
if(MD5Hash == null){
throw new EamDbException("null MD5 hash");
}
if(knownStatus == null){
throw new EamDbException("null known status");
}
this.instanceID = instanceID;
this.globalSetID = globalSetID;
// Normalize hashes by lower casing
@ -111,7 +117,10 @@ public class EamGlobalFileInstance {
/**
* @param MD5Hash the MD5Hash to set
*/
public void setMD5Hash(String MD5Hash) {
public void setMD5Hash(String MD5Hash) throws EamDbException {
if(MD5Hash == null){
throw new EamDbException("null MD5 hash");
}
// Normalize hashes by lower casing
this.MD5Hash = MD5Hash.toLowerCase();
}

View File

@ -22,6 +22,7 @@ import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -165,6 +166,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
connectionPool.setMaxIdle(-1);
connectionPool.setMaxWaitMillis(1000);
connectionPool.setValidationQuery(dbSettings.getValidationQuery());
connectionPool.setConnectionInitSqls(Arrays.asList("PRAGMA foreign_keys = ON"));
}
/**

View File

@ -33,3 +33,13 @@ MessageContentViewer.directionText.text=direction
MessageContentViewer.ccLabel.text=CC:
MessageContentViewer.attachmentsPanel.TabConstraints.tabTitle=Attachments
MessageContentViewer.viewInNewWindowButton.text=View in New Window
JPEGViewerDummy.jLabel1.text=You are looking at a JPEG file:
JPEGViewerDummy.jTextField1.text=jTextField1
SQLiteViewer.nextPageButton.text=
SQLiteViewer.prevPageButton.text=
SQLiteViewer.numPagesLabel.text=N
SQLiteViewer.jLabel3.text=of
SQLiteViewer.currPageLabel.text=x
SQLiteViewer.jLabel2.text=Page
SQLiteViewer.numEntriesField.text=num Entries
SQLiteViewer.jLabel1.text=Table

View File

@ -0,0 +1,50 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import java.awt.Component;
import java.util.List;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Defines an interface for application specific content viewer
*
*/
interface FileTypeViewer {
/**
* Returns list of MIME types supported by this viewer
*/
List<String> getSupportedMIMETypes();
/**
* Display the given file's content in the view panel
*/
void setFile(AbstractFile file);
/**
* Returns panel
*/
Component getComponent();
/**
* Clears the data in the panel
*/
void resetComponent();
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<LayoutCode>
<CodeStatement>
<CodeExpression id="1">
<ExpressionOrigin>
<ExpressionProvider type="ComponentRef">
<ComponentRef name="."/>
</ExpressionProvider>
</ExpressionOrigin>
</CodeExpression>
<StatementProvider type="CodeMethod">
<CodeMethod name="setLayout" class="java.awt.Container" parameterTypes="java.awt.LayoutManager"/>
</StatementProvider>
<Parameters>
<CodeExpression id="2">
<ExpressionOrigin>
<ExpressionProvider type="CodeConstructor">
<CodeConstructor class="javax.swing.OverlayLayout" parameterTypes="java.awt.Container"/>
</ExpressionProvider>
<Parameters>
<CodeExpression id="1"/>
</Parameters>
</ExpressionOrigin>
</CodeExpression>
</Parameters>
</CodeStatement>
</LayoutCode>
</Form>

View File

@ -0,0 +1,235 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import com.google.common.base.Strings;
import java.awt.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile;
/**
* Generic Application content viewer
*/
@ServiceProvider(service = DataContentViewer.class, position = 5)
public class FileViewer extends javax.swing.JPanel implements DataContentViewer {
private static final int CONFIDENCE_LEVEL = 7;
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName());
private final Map<String, FileTypeViewer> mimeTypeToViewerMap = new HashMap<>();
// TBD: This hardcoded list of viewers should be replaced with a dynamic lookup
private static final FileTypeViewer[] KNOWN_VIEWERS = new FileTypeViewer[]{
// new JPEGViewerDummy(), // this if for testing only
new SQLiteViewer()
};
private FileTypeViewer lastViewer;
/**
* Creates new form ApplicationContentViewer
*/
public FileViewer() {
// init the mimetype to viewer map
for (FileTypeViewer cv : KNOWN_VIEWERS) {
cv.getSupportedMIMETypes().forEach((mimeType) -> {
if (mimeTypeToViewerMap.containsKey(mimeType) == false) {
mimeTypeToViewerMap.put(mimeType, cv);
} else {
LOGGER.log(Level.WARNING, "Duplicate viewer for mimtype: {0}", mimeType); //NON-NLS
}
});
}
initComponents();
LOGGER.log(Level.INFO, "Created ApplicationContentViewer instance: {0}", this); //NON-NLS
}
/**
* Get the FileTypeViewer for a given mimetype
*
* @param mimeType
*
* @return FileTypeViewer, null if no known content viewer supports the mimetype
*/
private FileTypeViewer getSupportingViewer(String mimeType) {
return mimeTypeToViewerMap.get(mimeType);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new javax.swing.OverlayLayout(this));
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
@Override
public void setNode(Node selectedNode) {
resetComponent();
if (selectedNode == null) {
return;
}
AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
if (file == null) {
return;
}
String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
try {
FileTypeDetector fileTypeDetector = new FileTypeDetector();
mimeType = fileTypeDetector.getMIMEType(file);
}catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize FileTypeDetector.", ex); //NON-NLS
return;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return;
}
else {
FileTypeViewer viewer = getSupportingViewer(mimeType);
if (viewer != null) {
lastViewer = viewer;
viewer.setFile(file);
this.removeAll();
this.add(viewer.getComponent());
this.repaint();
}
}
}
@Override
@NbBundle.Messages("ApplicationContentViewer.title=Application")
public String getTitle() {
return Bundle.ApplicationContentViewer_title();
}
@Override
@NbBundle.Messages("ApplicationContentViewer.toolTip=Displays file contents.")
public String getToolTip() {
return Bundle.ApplicationContentViewer_toolTip();
}
@Override
public DataContentViewer createInstance() {
return new FileViewer();
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
if (lastViewer != null) {
lastViewer.resetComponent();
}
this.removeAll();
lastViewer = null;
}
@Override
public boolean isSupported(Node node) {
if (node == null) {
return false;
}
AbstractFile aFile = node.getLookup().lookup(AbstractFile.class);
if (aFile == null) {
return false;
}
String mimeType = aFile.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", aFile.getName()); //NON-NLS
try {
FileTypeDetector fileTypeDetector = new FileTypeDetector();
mimeType = fileTypeDetector.getMIMEType(aFile);
}catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize FileTypeDetector.", ex); //NON-NLS
return false;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return false;
} else {
return (getSupportingViewer(mimeType) != null);
}
}
@Override
public int isPreferred(Node node) {
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
try {
FileTypeDetector fileTypeDetector = new FileTypeDetector();
mimeType = fileTypeDetector.getMIMEType(file);
}catch (FileTypeDetector.FileTypeDetectorInitException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize FileTypeDetector.", ex); //NON-NLS
return 0;
}
}
if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return 0;
} else {
if (null != getSupportingViewer(mimeType)) {
return CONFIDENCE_LEVEL;
}
}
return 0;
}
}

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="43" max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="35" max="-2" attributes="0"/>
<Component id="jTextField1" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="120" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="269" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="JPEGViewerDummy.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="jTextField1">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="JPEGViewerDummy.jTextField1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,89 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.contentviewers;
import java.awt.Component;
import java.util.Arrays;
import java.util.List;
import org.sleuthkit.datamodel.AbstractFile;
public class JPEGViewerDummy extends javax.swing.JPanel implements FileTypeViewer {
public static final String[] SUPPORTED_MIMETYPES = new String[]{"image/jpeg"};
/**
* Creates new form JPEGViewer
*/
public JPEGViewerDummy() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
jTextField1 = new javax.swing.JTextField();
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(JPEGViewerDummy.class, "JPEGViewerDummy.jLabel1.text")); // NOI18N
jTextField1.setEditable(false);
jTextField1.setText(org.openide.util.NbBundle.getMessage(JPEGViewerDummy.class, "JPEGViewerDummy.jTextField1.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(43, 43, 43)
.addComponent(jLabel1)
.addGap(35, 35, 35)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(120, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(269, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@Override
public List<String> getSupportedMIMETypes() {
return Arrays.asList(SUPPORTED_MIMETYPES);
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
this.jTextField1.setText("");
}
@Override
public void setFile(AbstractFile file) {
this.jTextField1.setText(file.getName());
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel1;
private javax.swing.JTextField jTextField1;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,88 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.sleuthkit.autopsy.datamodel.NodeProperty;
public class SQLiteTableRowFactory extends ChildFactory<Integer> {
private final List<Map<String, Object>> rows;
public SQLiteTableRowFactory(List<Map<String, Object>> rows) {
this.rows = rows;
}
@Override
protected boolean createKeys(List<Integer> keys) {
if (rows != null) {
for (int i = 0; i < rows.size(); i++) {
keys.add(i);
}
}
return true;
}
@Override
protected Node createNodeForKey(Integer key) {
if (Objects.isNull(rows) || rows.isEmpty() || key >= rows.size()) {
return null;
}
return new SQLiteTableRowNode(rows.get(key));
}
}
class SQLiteTableRowNode extends AbstractNode {
private final Map<String, Object> row;
SQLiteTableRowNode(Map<String, Object> row) {
super(Children.LEAF);
this.row = row;
}
@Override
protected Sheet createSheet() {
Sheet s = super.createSheet();
Sheet.Set properties = s.get(Sheet.PROPERTIES);
if (properties == null) {
properties = Sheet.createPropertiesSet();
s.put(properties);
}
for (Map.Entry<String, Object> col : row.entrySet()) {
String colName = col.getKey();
String colVal = col.getValue().toString();
properties.put(new NodeProperty<>(colName, colName, colName, colVal)); // NON-NLS
}
return s;
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
</Form>

View File

@ -0,0 +1,163 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingWorker;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.netbeans.swing.etable.ETableColumn;
import org.netbeans.swing.etable.ETableColumnModel;
import org.netbeans.swing.outline.Outline;
import org.openide.explorer.ExplorerManager;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
class SQLiteTableView extends JPanel implements ExplorerManager.Provider {
private final org.openide.explorer.view.OutlineView outlineView;
private final Outline outline;
private final ExplorerManager explorerManager;
/**
* Creates new form SQLiteTableView
*
*/
SQLiteTableView() {
initComponents();
outlineView = new org.openide.explorer.view.OutlineView();
add(outlineView, BorderLayout.CENTER);
outlineView.setPropertyColumns(); // column headers will be set later
outlineView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
outlineView.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
outline = outlineView.getOutline();
outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
outline.setRowSelectionAllowed(false);
outline.setRootVisible(false);
explorerManager = new ExplorerManager();
}
/**
* Sets up the columns in the display table
*
* @param tableRows
*/
void setupTable(List<Map<String, Object>> tableRows) {
if (Objects.isNull(tableRows) || tableRows.isEmpty()) {
outlineView.setPropertyColumns();
} else {
// Set up the column names
Map<String, Object> row = tableRows.get(0);
String[] propStrings = new String[row.size() * 2];
int i = 0;
for (Map.Entry<String, Object> col : row.entrySet()) {
String colName = col.getKey();
propStrings[2 * i] = colName;
propStrings[2 * i + 1] = colName;
i++;
}
outlineView.setPropertyColumns(propStrings);
}
// Hide the 'Nodes' column
TableColumnModel columnModel = outline.getColumnModel();
ETableColumn column = (ETableColumn) columnModel.getColumn(0);
((ETableColumnModel) columnModel).setColumnHidden(column, true);
// Set the Nodes for the ExplorerManager.
// The Swingworker ensures that setColumnWidths() is called after all nodes have been created.
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
explorerManager.setRootContext(new AbstractNode(Children.create(new SQLiteTableRowFactory(tableRows), true)));
return false;
}
@Override
protected void done() {
super.done();
setColumnWidths();
}
}.execute();
}
private void setColumnWidths() {
int margin = 4;
int padding = 8;
// find the maximum width needed to fit the values for the first N rows, at most
final int rows = Math.min(20, outline.getRowCount());
for (int col = 1; col < outline.getColumnCount(); col++) {
int columnWidthLimit = 500;
int columnWidth = 50;
for (int row = 0; row < rows; row++) {
TableCellRenderer renderer = outline.getCellRenderer(row, col);
Component comp = outline.prepareRenderer(renderer, row, col);
columnWidth = Math.max(comp.getPreferredSize().width, columnWidth);
}
columnWidth += 2 * margin + padding; // add margin and regular padding
columnWidth = Math.min(columnWidth, columnWidthLimit);
outline.getColumnModel().getColumn(col).setPreferredWidth(columnWidth);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new java.awt.BorderLayout());
}// </editor-fold>//GEN-END:initComponents
@Override
public ExplorerManager getExplorerManager() {
return explorerManager;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jHdrPanel" max="32767" attributes="0"/>
<Component id="jTableDataPanel" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jHdrPanel" min="-2" pref="53" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="jTableDataPanel" pref="317" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="jHdrPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[536, 40]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="tablesDropdownList" min="-2" pref="130" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="numEntriesField" min="-2" pref="71" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="15" max="-2" attributes="0"/>
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="currPageLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel3" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="numPagesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="prevPageButton" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="nextPageButton" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace pref="133" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="nextPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="prevPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="tablesDropdownList" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="numEntriesField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="currPageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="numPagesLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JComboBox" name="tablesDropdownList">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tablesDropdownListActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="numEntriesField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.numEntriesField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="currPageLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.currPageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="numPagesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.numPagesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="prevPageButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.prevPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/>
<Property name="disabledSelectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 0, 2, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="prevPageButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="nextPageButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="SQLiteViewer.nextPageButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/>
<Property name="disabledSelectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 0, 2, 0]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[23, 23]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="nextPageButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jTableDataPanel">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,514 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.contentviewers;
import java.awt.BorderLayout;
import java.awt.Component;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JComboBox;
import javax.swing.SwingWorker;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.AbstractFile;
public class SQLiteViewer extends javax.swing.JPanel implements FileTypeViewer {
public static final String[] SUPPORTED_MIMETYPES = new String[]{"application/x-sqlite3"};
private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName());
private Connection connection = null;
private String tmpDBPathName = null;
private File tmpDBFile = null;
private final Map<String, String> dbTablesMap = new TreeMap<>();
private static final int ROWS_PER_PAGE = 100;
private int numRows; // num of rows in the selected table
private int currPage = 0; // curr page of rows being displayed
SQLiteTableView selectedTableView = new SQLiteTableView();
private SwingWorker<? extends Object, ? extends Object> worker;
/**
* Creates new form SQLiteViewer
*/
public SQLiteViewer() {
initComponents();
jTableDataPanel.add(selectedTableView, BorderLayout.CENTER);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jHdrPanel = new javax.swing.JPanel();
tablesDropdownList = new javax.swing.JComboBox<>();
jLabel1 = new javax.swing.JLabel();
numEntriesField = new javax.swing.JTextField();
jLabel2 = new javax.swing.JLabel();
currPageLabel = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
numPagesLabel = new javax.swing.JLabel();
prevPageButton = new javax.swing.JButton();
nextPageButton = new javax.swing.JButton();
jTableDataPanel = new javax.swing.JPanel();
jHdrPanel.setPreferredSize(new java.awt.Dimension(536, 40));
tablesDropdownList.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
tablesDropdownList.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tablesDropdownListActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.jLabel1.text")); // NOI18N
numEntriesField.setEditable(false);
numEntriesField.setText(org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.numEntriesField.text")); // NOI18N
numEntriesField.setBorder(null);
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.jLabel2.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(currPageLabel, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.currPageLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.jLabel3.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(numPagesLabel, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.numPagesLabel.text")); // NOI18N
prevPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(prevPageButton, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.prevPageButton.text")); // NOI18N
prevPageButton.setBorderPainted(false);
prevPageButton.setContentAreaFilled(false);
prevPageButton.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_back_disabled.png"))); // NOI18N
prevPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
prevPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
prevPageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
prevPageButtonActionPerformed(evt);
}
});
nextPageButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(nextPageButton, org.openide.util.NbBundle.getMessage(SQLiteViewer.class, "SQLiteViewer.nextPageButton.text")); // NOI18N
nextPageButton.setBorderPainted(false);
nextPageButton.setContentAreaFilled(false);
nextPageButton.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/btn_step_forward_disabled.png"))); // NOI18N
nextPageButton.setMargin(new java.awt.Insets(2, 0, 2, 0));
nextPageButton.setPreferredSize(new java.awt.Dimension(23, 23));
nextPageButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nextPageButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout jHdrPanelLayout = new javax.swing.GroupLayout(jHdrPanel);
jHdrPanel.setLayout(jHdrPanelLayout);
jHdrPanelLayout.setHorizontalGroup(
jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jHdrPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(15, 15, 15)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(currPageLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel3)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(numPagesLabel)
.addGap(18, 18, 18)
.addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(133, Short.MAX_VALUE))
);
jHdrPanelLayout.setVerticalGroup(
jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jHdrPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(jHdrPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tablesDropdownList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1)
.addComponent(numEntriesField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2)
.addComponent(currPageLabel)
.addComponent(jLabel3)
.addComponent(numPagesLabel)))
.addContainerGap())
);
jTableDataPanel.setLayout(new java.awt.BorderLayout());
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jHdrPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jTableDataPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jHdrPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(jTableDataPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
currPage++;
if (currPage * ROWS_PER_PAGE > numRows) {
nextPageButton.setEnabled(false);
}
currPageLabel.setText(Integer.toString(currPage));
prevPageButton.setEnabled(true);
// read and display a page of rows
String tableName = (String) this.tablesDropdownList.getSelectedItem();
readTable(tableName, (currPage - 1) * ROWS_PER_PAGE + 1, ROWS_PER_PAGE);
}//GEN-LAST:event_nextPageButtonActionPerformed
private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
currPage--;
if (currPage == 1) {
prevPageButton.setEnabled(false);
}
currPageLabel.setText(Integer.toString(currPage));
nextPageButton.setEnabled(true);
// read and display a page of rows
String tableName = (String) this.tablesDropdownList.getSelectedItem();
readTable(tableName, (currPage - 1) * ROWS_PER_PAGE + 1, ROWS_PER_PAGE);
}//GEN-LAST:event_prevPageButtonActionPerformed
private void tablesDropdownListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tablesDropdownListActionPerformed
JComboBox<?> cb = (JComboBox<?>) evt.getSource();
String tableName = (String) cb.getSelectedItem();
if (null == tableName) {
return;
}
selectTable(tableName);
}//GEN-LAST:event_tablesDropdownListActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel currPageLabel;
private javax.swing.JPanel jHdrPanel;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jTableDataPanel;
private javax.swing.JButton nextPageButton;
private javax.swing.JTextField numEntriesField;
private javax.swing.JLabel numPagesLabel;
private javax.swing.JButton prevPageButton;
private javax.swing.JComboBox<String> tablesDropdownList;
// End of variables declaration//GEN-END:variables
@Override
public List<String> getSupportedMIMETypes() {
return Arrays.asList(SUPPORTED_MIMETYPES);
}
@Override
public void setFile(AbstractFile file) {
processSQLiteFile(file);
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
dbTablesMap.clear();
tablesDropdownList.setEnabled(true);
tablesDropdownList.removeAllItems();
numEntriesField.setText("");
// close DB connection to file
if (null != connection) {
try {
connection.close();
connection = null;
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to close DB connection to file.", ex); //NON-NLS
}
}
// delete last temp file
if (null != tmpDBFile) {
tmpDBFile.delete();
tmpDBFile = null;
}
}
/**
* Process the given SQLite DB file
*
* @param sqliteFile -
*
* @return none
*/
private void processSQLiteFile(AbstractFile sqliteFile) {
tablesDropdownList.removeAllItems();
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
try {
// Copy the file to temp folder
tmpDBPathName = Case.getCurrentCase().getTempDirectory() + File.separator + sqliteFile.getName() + "-" + sqliteFile.getId();
tmpDBFile = new File(tmpDBPathName);
ContentUtils.writeToFile(sqliteFile, tmpDBFile);
// Open copy using JDBC
Class.forName("org.sqlite.JDBC"); //NON-NLS //load JDBC driver
connection = DriverManager.getConnection("jdbc:sqlite:" + tmpDBPathName); //NON-NLS
// Read all table names and schema
return getTables();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Failed to copy DB file.", ex); //NON-NLS
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to Open DB.", ex); //NON-NLS
} catch (ClassNotFoundException ex) {
LOGGER.log(Level.SEVERE, "Failed to initialize JDBC Sqlite.", ex); //NON-NLS
}
return false;
}
@Override
protected void done() {
super.done();
try {
boolean status = get();
if ((status == true) && (dbTablesMap.size() > 0)) {
dbTablesMap.keySet().forEach((tableName) -> {
tablesDropdownList.addItem(tableName);
});
} else {
// Populate error message
tablesDropdownList.addItem("No tables found");
tablesDropdownList.setEnabled(false);
}
} catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while opening DB file", ex); //NON-NLS
}
}
}.execute();
}
/**
* Gets the table names and their schema from loaded SQLite db file
*
* @return true if success, false otherwise
*/
private boolean getTables() {
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(
"SELECT name, sql FROM sqlite_master "
+ " WHERE type= 'table' "
+ " ORDER BY name;"); //NON-NLS
while (resultSet.next()) {
String tableName = resultSet.getString("name"); //NON-NLS
String tableSQL = resultSet.getString("sql"); //NON-NLS
dbTablesMap.put(tableName, tableSQL);
}
} catch (SQLException e) {
LOGGER.log(Level.SEVERE, "Error getting table names from the DB", e); //NON-NLS
}
return true;
}
private void selectTable(String tableName) {
if (worker != null && !worker.isDone()) {
worker.cancel(false);
worker = null;
}
worker = new SwingWorker<Integer, Void>() {
@Override
protected Integer doInBackground() throws Exception {
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(
"SELECT count (*) as count FROM " + tableName); //NON-NLS
return resultSet.getInt("count");
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to get data for table.", ex); //NON-NLS
}
//NON-NLS
return 0;
}
@Override
protected void done() {
super.done();
try {
numRows = get();
numEntriesField.setText(numRows + " entries");
currPage = 1;
currPageLabel.setText(Integer.toString(currPage));
numPagesLabel.setText(Integer.toString((numRows / ROWS_PER_PAGE) + 1));
prevPageButton.setEnabled(false);
if (numRows > 0) {
nextPageButton.setEnabled(((numRows > ROWS_PER_PAGE)));
readTable(tableName, (currPage - 1) * ROWS_PER_PAGE + 1, ROWS_PER_PAGE);
} else {
nextPageButton.setEnabled(false);
selectedTableView.setupTable(Collections.emptyList());
}
} catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while reading table.", ex); //NON-NLS
}
}
};
worker.execute();
}
private void readTable(String tableName, int startRow, int numRowsToRead) {
if (worker != null && !worker.isDone()) {
worker.cancel(false);
worker = null;
}
worker = new SwingWorker<ArrayList<Map<String, Object>>, Void>() {
@Override
protected ArrayList<Map<String, Object>> doInBackground() throws Exception {
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(
"SELECT * FROM " + tableName
+ " LIMIT " + Integer.toString(numRowsToRead)
+ " OFFSET " + Integer.toString(startRow - 1)
); //NON-NLS
return resultSetToArrayList(resultSet);
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Failed to get data for table " + tableName, ex); //NON-NLS
}
//NON-NLS
return null;
}
@Override
protected void done() {
if (isCancelled()) {
return;
}
super.done();
try {
ArrayList<Map<String, Object>> rows = get();
if (Objects.nonNull(rows)) {
selectedTableView.setupTable(rows);
}else{
selectedTableView.setupTable(Collections.emptyList());
}
} catch (InterruptedException | ExecutionException ex) {
LOGGER.log(Level.SEVERE, "Unexpected exception while reading table " + tableName, ex); //NON-NLS
}
}
};
worker.execute();
}
@NbBundle.Messages("SQLiteViewer.BlobNotShown.message=BLOB Data not shown")
private ArrayList<Map<String, Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
int columns = metaData.getColumnCount();
ArrayList<Map<String, Object>> rowlist = new ArrayList<>();
while (rs.next()) {
Map<String, Object> row = new LinkedHashMap<>(columns);
for (int i = 1; i <= columns; ++i) {
if (rs.getObject(i) == null) {
row.put(metaData.getColumnName(i), "");
} else {
if (metaData.getColumnTypeName(i).compareToIgnoreCase("blob") == 0) {
row.put(metaData.getColumnName(i), Bundle.SQLiteViewer_BlobNotShown_message());
} else {
row.put(metaData.getColumnName(i), rs.getObject(i));
}
}
}
rowlist.add(row);
}
return rowlist;
}
}

View File

@ -202,7 +202,7 @@ public class ViewContextAction extends AbstractAction {
undecoratedParentNode.setChildNodeSelectionInfo(new ContentNodeSelectionInfo(content));
TreeView treeView = treeViewTopComponent.getTree();
treeView.expandNode(parentTreeViewNode);
if (treeViewTopComponent.getSelectedNode().getDisplayName().equals(parentTreeViewNode.getDisplayName())) {
if (treeViewTopComponent.getSelectedNode().equals(parentTreeViewNode)) {
//In the case where our tree view already has the destination directory selected
//due to an optimization in the ExplorerManager.setExploredContextAndSelection method
//the property change we listen for to call DirectoryTreeTopComponent.respondSelection

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -178,6 +178,8 @@ public class FileTypeDetector {
*
* @return A MIME type name. If file type could not be detected, or results
* were uncertain, octet-stream is returned.
*
*/
public String getMIMEType(AbstractFile file) {
/*

View File

@ -1232,9 +1232,10 @@ public class HashDbManager implements PropertyChangeListener {
} else {
type = TskData.FileKnown.KNOWN;
}
try{
EamGlobalFileInstance fileInstance = new EamGlobalFileInstance(referenceSetID, file.getMd5Hash(),
type, comment);
try{
EamDb.getInstance().addReferenceInstance(fileInstance,EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID));
} catch (EamDbException ex){
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
@ -1260,7 +1261,11 @@ public class HashDbManager implements PropertyChangeListener {
} else {
type = TskData.FileKnown.KNOWN;
}
try {
globalFileInstances.add(new EamGlobalFileInstance(referenceSetID, hashEntry.getMd5Hash(), type, hashEntry.getComment()));
} catch (EamDbException ex){
throw new TskCoreException("Error adding hashes to " + getDisplayName(), ex);
}
}
try{

View File

@ -63,7 +63,7 @@ class ReportGenerator {
*/
private ReportProgressPanel progressPanel;
private String reportPathFormatString;
private static final String REPORT_PATH_FMT_STR = "%s" + File.separator + "%s %s %s" + File.separator;
private final ReportGenerationPanel reportGenerationPanel = new ReportGenerationPanel();
static final String REPORTS_DIR = "Reports"; //NON-NLS
@ -89,12 +89,6 @@ class ReportGenerator {
* Creates a report generator.
*/
ReportGenerator() {
// Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String dateNoTime = dateFormat.format(date);
this.reportPathFormatString = currentCase.getReportDirectory() + File.separator + currentCase.getDisplayName() + " %s " + dateNoTime + File.separator;
this.errorList = new ArrayList<>();
}
@ -136,19 +130,12 @@ class ReportGenerator {
/**
* Run the GeneralReportModules using a SwingWorker.
*/
void generateGeneralReport(GeneralReportModule generalReportModule) {
void generateGeneralReport(GeneralReportModule generalReportModule) throws IOException {
if (generalReportModule != null) {
reportPathFormatString = String.format(reportPathFormatString, generalReportModule.getName());
// Create the root reports directory.
try {
FileUtil.createFolder(new File(reportPathFormatString));
} catch (IOException ex) {
errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedMakeRptFolder"));
logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex); //NON-NLS
}
setupProgressPanel(generalReportModule);
String reportDir = createReportDirectory(generalReportModule);
setupProgressPanel(generalReportModule, reportDir);
ReportWorker worker = new ReportWorker(() -> {
generalReportModule.generateReport(reportPathFormatString, progressPanel);
generalReportModule.generateReport(reportDir, progressPanel);
});
worker.execute();
displayProgressPanel();
@ -163,19 +150,12 @@ class ReportGenerator {
* @param tagSelections the enabled/disabled state of the tag names
* to be included in the report
*/
void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) {
void generateTableReport(TableReportModule tableReport, Map<BlackboardArtifact.Type, Boolean> artifactTypeSelections, Map<String, Boolean> tagNameSelections) throws IOException {
if (tableReport != null && null != artifactTypeSelections) {
reportPathFormatString = String.format(reportPathFormatString, tableReport.getName());
// Create the root reports directory.
try {
FileUtil.createFolder(new File(reportPathFormatString));
} catch (IOException ex) {
errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedMakeRptFolder"));
logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex); //NON-NLS
}
setupProgressPanel(tableReport);
String reportDir = createReportDirectory(tableReport);
setupProgressPanel(tableReport, reportDir);
ReportWorker worker = new ReportWorker(() -> {
tableReport.startReport(reportPathFormatString);
tableReport.startReport(reportDir);
TableReportGenerator generator = new TableReportGenerator(artifactTypeSelections, tagNameSelections, progressPanel, tableReport);
generator.execute();
tableReport.endReport();
@ -194,23 +174,16 @@ class ReportGenerator {
* @param enabledInfo the Information that should be included about each
* file in the report.
*/
void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) {
void generateFileListReport(FileReportModule fileReportModule, Map<FileReportDataTypes, Boolean> enabledInfo) throws IOException {
if (fileReportModule != null && null != enabledInfo) {
reportPathFormatString = String.format(reportPathFormatString, fileReportModule.getName());
// Create the root reports directory.
try {
FileUtil.createFolder(new File(reportPathFormatString));
} catch (IOException ex) {
errorList.add(NbBundle.getMessage(this.getClass(), "ReportGenerator.errList.failedMakeRptFolder"));
logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex); //NON-NLS
}
String reportDir = createReportDirectory(fileReportModule);
List<FileReportDataTypes> enabled = new ArrayList<>();
for (Entry<FileReportDataTypes, Boolean> e : enabledInfo.entrySet()) {
if (e.getValue()) {
enabled.add(e.getKey());
}
}
setupProgressPanel(fileReportModule);
setupProgressPanel(fileReportModule, reportDir);
ReportWorker worker = new ReportWorker(() -> {
if (progressPanel.getStatus() != ReportStatus.CANCELED) {
progressPanel.start();
@ -221,7 +194,7 @@ class ReportGenerator {
List<AbstractFile> files = getFiles();
int numFiles = files.size();
if (progressPanel.getStatus() != ReportStatus.CANCELED) {
fileReportModule.startReport(reportPathFormatString);
fileReportModule.startReport(reportDir);
fileReportModule.startTable(enabled);
}
progressPanel.setIndeterminate(false);
@ -276,15 +249,31 @@ class ReportGenerator {
}
}
private void setupProgressPanel(ReportModule module) {
private void setupProgressPanel(ReportModule module, String reportDir) {
String reportFilePath = module.getRelativeFilePath();
if (!reportFilePath.isEmpty()) {
this.progressPanel = reportGenerationPanel.addReport(module.getName(), String.format(reportPathFormatString, module.getName()) + reportFilePath);
this.progressPanel = reportGenerationPanel.addReport(module.getName(), reportDir + reportFilePath);
} else {
this.progressPanel = reportGenerationPanel.addReport(module.getName(), null);
}
}
private static String createReportDirectory(ReportModule module) throws IOException {
Case currentCase = Case.getCurrentCase();
// Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String dateNoTime = dateFormat.format(date);
String reportPath = String.format(REPORT_PATH_FMT_STR, currentCase.getReportDirectory(), currentCase.getDisplayName(), module.getName(), dateNoTime);
// Create the root reports directory.
try {
FileUtil.createFolder(new File(reportPath));
} catch (IOException ex) {
throw new IOException("Failed to make report folder, unable to generate reports.", ex);
}
return reportPath;
}
private class ReportWorker extends SwingWorker<Void, Void> {
private final Runnable doInBackground;

View File

@ -2,7 +2,7 @@
*
* Autopsy Forensic Browser
*
* Copyright 2013-2015 Basis Technology Corp.
* Copyright 2013-2018 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
@ -26,12 +26,14 @@ import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.EnumSet;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.WizardDescriptor;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
@ -70,6 +72,7 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
TableReportModule tableReport = (TableReportModule) wiz.getProperty("tableModule");
GeneralReportModule generalReport = (GeneralReportModule) wiz.getProperty("generalModule");
FileReportModule fileReport = (FileReportModule) wiz.getProperty("fileModule");
try {
if (tableReport != null) {
generator.generateTableReport(tableReport, (Map<BlackboardArtifact.Type, Boolean>) wiz.getProperty("artifactStates"), (Map<String, Boolean>) wiz.getProperty("tagStates")); //NON-NLS
} else if (generalReport != null) {
@ -77,6 +80,10 @@ public final class ReportWizardAction extends CallableSystemAction implements Pr
} else if (fileReport != null) {
generator.generateFileListReport(fileReport, (Map<FileReportDataTypes, Boolean>) wiz.getProperty("fileReportOptions")); //NON-NLS
}
} catch (IOException e) {
NotifyDescriptor descriptor = new NotifyDescriptor.Message(e.getMessage(), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(descriptor);
}
}
}

View File

@ -1,5 +1,5 @@
#Updated by build script
#Tue, 23 Jan 2018 11:13:26 -0500
#Tue, 23 Jan 2018 11:28:07 -0500
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314
SPLASH_WIDTH=538

View File

@ -1,4 +1,4 @@
#Updated by build script
#Tue, 23 Jan 2018 11:13:26 -0500
#Tue, 23 Jan 2018 11:28:07 -0500
CTL_MainWindow_Title=Autopsy 4.5.0
CTL_MainWindow_Title_No_Project=Autopsy 4.5.0

View File

@ -33,6 +33,9 @@
<condition property="os.family" value="windows">
<os family="windows"/>
</condition>
<condition property="os.family" value="mac">
<os family="mac"/>
</condition>
<import file="build-${os.family}.xml"/>
<!-- Third party tools dependencies -->
@ -82,7 +85,13 @@
<copy file="${basedir}/LICENSE-2.0.txt" tofile="${zip-tmp}/${app.name}/LICENSE-2.0.txt"/>
<copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/>
<copy file="${basedir}/KNOWN_ISSUES.txt" tofile="${zip-tmp}/${app.name}/KNOWN_ISSUES.txt"/>
<if>
<equals arg1="${os.family}" arg2="windows"/>
<then>
<unzip src="${thirdparty.dir}/gstreamer/${os.family}/i386/0.10.7/gstreamer.zip" dest="${zip-tmp}/${app.name}/gstreamer"/>
</then>
</if>
<copy file="${basedir}/icons/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/>
<!-- Copy the Autopsy documentation to the docs folder -->
@ -91,8 +100,17 @@
</copy>
<property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" />
<var name="jvm-value" value="--branding ${app.name} -J-Xms24m -J-Xmx4G -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication"/>
<!-- for Japanese localized version add option: -Duser.language=ja -->
<property name="jvm.options" value="&quot;--branding ${app.name} -J-Xms24m -J-Xmx4G -J-XX:MaxPermSize=128M -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication -J-Xdock:name=${app.title}&quot;" />
<if>
<equals arg1="${os.family}" arg2="mac"/>
<then>
<property name="jvm.options" value="&quot;${jvm-value} -J-Xdock:name=${app.title}&quot;"/>
</then>
<else>
<property name="jvm.options" value="&quot;${jvm-value}&quot;"/>
</else>
</if>
<propertyfile file="${app.property.file}">
<!-- Note: can be higher on 64 bit systems, should be in sync with project.properties -->
<entry key="default_options" value="@JVM_OPTIONS" />

View File

@ -1,13 +1,280 @@
<?xml version="1.0"?>
<ruleset name="Custom ruleset"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
<ruleset name="Autopsy ruleset"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
Ruleset used by Autopsy
</description>
<rule ref="rulesets/java/unusedcode.xml"/>
<rule ref="rulesets/java/basic.xml/SimplifiedTernary"/>
<rule ref="rulesets/java/basic.xml/AvoidUsingOctalValues"/>
<rule ref="rulesets/java/basic.xml/BigIntegerInstantiation"/>
<rule ref="rulesets/java/basic.xml/ClassCastExceptionWithToArray"/>
<rule ref="rulesets/java/basic.xml/ForLoopShouldBeWhileLoop"/>
<rule ref="rulesets/java/basic.xml/CheckResultSet"/>
<rule ref="rulesets/java/basic.xml/UnconditionalIfStatement"/>
<rule ref="rulesets/java/basic.xml/CheckSkipResult"/>
<rule ref="rulesets/java/basic.xml/DontUseFloatTypeForLoopIndices"/>
<rule ref="rulesets/java/basic.xml/MisplacedNullCheck"/>
<rule ref="rulesets/java/basic.xml/AvoidDecimalLiteralsInBigDecimalConstructor"/>
<rule ref="rulesets/java/basic.xml/BooleanInstantiation"/>
<rule ref="rulesets/java/basic.xml/ExtendsObject"/>
<rule ref="rulesets/java/basic.xml/AvoidBranchingStatementAsLastInLoop"/>
<rule ref="rulesets/java/basic.xml/DoubleCheckedLocking"/>
<rule ref="rulesets/java/basic.xml/ReturnFromFinallyBlock"/>
<rule ref="rulesets/java/basic.xml/AvoidThreadGroup"/>
<rule ref="rulesets/java/basic.xml/CollapsibleIfStatements"/>
<rule ref="rulesets/java/basic.xml/AvoidUsingHardCodedIP"/>
<rule ref="rulesets/java/basic.xml/CheckResultSet"/>
<rule ref="rulesets/java/basic.xml/DontCallThreadRun"/>
<rule ref="rulesets/java/basic.xml/BrokenNullCheck"/>
<rule ref="rulesets/java/basic.xml/AvoidMultipleUnaryOperators"/>
<rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode"/>
<rule ref="rulesets/java/basic.xml/JumbledIncrementer"/>
<rule ref="rulesets/java/braces.xml/WhileLoopsMustUseBraces"/>
<rule ref="rulesets/java/braces.xml/IfStmtsMustUseBraces"/>
<rule ref="rulesets/java/braces.xml/IfElseStmtsMustUseBraces"/>
<rule ref="rulesets/java/braces.xml/ForLoopsMustUseBraces"/>
<rule ref="rulesets/java/clone.xml/ProperCloneImplementation"/>
<rule ref="rulesets/java/clone.xml/CloneThrowsCloneNotSupportedException"/>
<rule ref="rulesets/java/clone.xml/CloneMethodMustImplementCloneable"/>
<rule ref="rulesets/java/clone.xml/CloneMethodReturnTypeMustMatchClassName"/>
<rule ref="rulesets/java/clone.xml/CloneMethodMustBePublic"/>
<rule ref="rulesets/java/codesize.xml/NPathComplexity"/>
<rule ref="rulesets/java/codesize.xml/ExcessiveMethodLength"/>
<rule ref="rulesets/java/codesize.xml/ExcessiveParameterList"/>
<rule ref="rulesets/java/codesize.xml/ExcessiveClassLength"/>
<rule ref="rulesets/java/codesize.xml/CyclomaticComplexity"/>
<rule ref="rulesets/java/codesize.xml/StdCyclomaticComplexity"/>
<rule ref="rulesets/java/codesize.xml/ModifiedCyclomaticComplexity"/>
<rule ref="rulesets/java/codesize.xml/ExcessivePublicCount"/>
<rule ref="rulesets/java/codesize.xml/TooManyFields"/>
<rule ref="rulesets/java/codesize.xml/NcssMethodCount"/>
<rule ref="rulesets/java/codesize.xml/NcssTypeCount"/>
<rule ref="rulesets/java/codesize.xml/NcssConstructorCount"/>
<rule ref="rulesets/java/codesize.xml/TooManyMethods"/>
<rule ref="rulesets/java/comments.xml/CommentRequired">
<properties>
<!-- Disabled because we have lots of undocumented fields -->
<property name="fieldCommentRequirement" value="Unwanted"/>
</properties>
</rule>
<!-- Commented out because it was flagged some of our header / copyright comments
<rule ref="rulesets/java/comments.xml/CommentSize"/> -->
<rule ref="rulesets/java/comments.xml/CommentContent"/>
<rule ref="rulesets/java/comments.xml/CommentDefaultAccessModifier"/>
<!--
Commented out because they are controversial and we want basics right now.
<rule ref="rulesets/java/controversial.xml/NullAssignment"/>
<rule ref="rulesets/java/controversial.xml/OnlyOneReturn"/>
<rule ref="rulesets/java/controversial.xml/AssignmentInOperand"/>
<rule ref="rulesets/java/controversial.xml/AtLeastOneConstructor"/>
<rule ref="rulesets/java/controversial.xml/DontImportSun"/>
<rule ref="rulesets/java/controversial.xml/SuspiciousOctalEscape"/>
<rule ref="rulesets/java/controversial.xml/CallSuperInConstructor"/>
<rule ref="rulesets/java/controversial.xml/UnnecessaryParentheses"/>
<rule ref="rulesets/java/controversial.xml/DataflowAnomalyAnalysis"/>
<rule ref="rulesets/java/controversial.xml/AvoidFinalLocalVariable"/>
<rule ref="rulesets/java/controversial.xml/AvoidUsingShortType"/>
<rule ref="rulesets/java/controversial.xml/AvoidUsingVolatile"/>
<rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode"/>
<rule ref="rulesets/java/controversial.xml/AvoidAccessibilityAlteration"/>
<rule ref="rulesets/java/controversial.xml/DoNotCallGarbageCollectionExplicitly"/>
<rule ref="rulesets/java/controversial.xml/AvoidPrefixingMethodParameters"/>
<rule ref="rulesets/java/controversial.xml/AvoidLiteralsInIfCondition"/>
<rule ref="rulesets/java/controversial.xml/UseObjectForClearerAPI"/>
<rule ref="rulesets/java/controversial.xml/UseConcurrentHashMap"/>
<rule ref="rulesets/java/controversial.xml/OneDeclarationPerLine"/>
<rule ref="rulesets/java/controversial.xml/DefaultPackage"/>
<rule ref="rulesets/java/controversial.xml/UnnecessaryConstructor"/>
-->
<rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects"/>
<rule ref="rulesets/java/coupling.xml/ExcessiveImports"/>
<rule ref="rulesets/java/coupling.xml/LooseCoupling"/>
<rule ref="rulesets/java/coupling.xml/LoosePackageCoupling"/>
<!-- Commented out because we have not enforced this in the past
<rule ref="rulesets/java/coupling.xml/LawOfDemeter"/> -->
<rule ref="rulesets/java/design.xml/UseUtilityClass"/>
<rule ref="rulesets/java/design.xml/AvoidDeeplyNestedIfStmts"/>
<rule ref="rulesets/java/design.xml/SwitchDensity"/>
<rule ref="rulesets/java/design.xml/ConstructorCallsOverridableMethod"/>
<rule ref="rulesets/java/design.xml/AccessorClassGeneration"/>
<rule ref="rulesets/java/design.xml/FinalFieldCouldBeStatic"/>
<rule ref="rulesets/java/design.xml/CloseResource"/>
<rule ref="rulesets/java/design.xml/NonStaticInitializer"/>
<rule ref="rulesets/java/design.xml/DefaultLabelNotLastInSwitchStmt"/>
<rule ref="rulesets/java/design.xml/OptimizableToArrayCall"/>
<rule ref="rulesets/java/design.xml/BadComparison"/>
<rule ref="rulesets/java/design.xml/ConfusingTernary"/>
<rule ref="rulesets/java/design.xml/InstantiationToGetClass"/>
<rule ref="rulesets/java/design.xml/IdempotentOperations"/>
<rule ref="rulesets/java/design.xml/SimpleDateFormatNeedsLocale"/>
<rule ref="rulesets/java/design.xml/ImmutableField"/>
<rule ref="rulesets/java/design.xml/UseLocaleWithCaseConversions"/>
<rule ref="rulesets/java/design.xml/AvoidProtectedFieldInFinalClass"/>
<rule ref="rulesets/java/design.xml/AvoidSynchronizedAtMethodLevel"/>
<rule ref="rulesets/java/design.xml/UseNotifyAllInsteadOfNotify"/>
<rule ref="rulesets/java/design.xml/AbstractClassWithoutAbstractMethod"/>
<rule ref="rulesets/java/design.xml/SimplifyConditional"/>
<rule ref="rulesets/java/design.xml/PositionLiteralsFirstInCaseInsensitiveComparisons"/>
<rule ref="rulesets/java/design.xml/UnnecessaryLocalBeforeReturn"/>
<rule ref="rulesets/java/design.xml/NonThreadSafeSingleton"/>
<rule ref="rulesets/java/design.xml/SingleMethodSingleton"/>
<rule ref="rulesets/java/design.xml/SingletonClassReturningNewInstance"/>
<rule ref="rulesets/java/design.xml/UncommentedEmptyConstructor"/>
<rule ref="rulesets/java/design.xml/AvoidConstantsInterface"/>
<rule ref="rulesets/java/design.xml/UnsynchronizedStaticDateFormatter"/>
<rule ref="rulesets/java/design.xml/PreserveStackTrace"/>
<rule ref="rulesets/java/design.xml/UseCollectionIsEmpty"/>
<rule ref="rulesets/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/>
<rule ref="rulesets/java/design.xml/EmptyMethodInAbstractClassShouldBeAbstract"/>
<rule ref="rulesets/java/design.xml/ReturnEmptyArrayRatherThanNull"/>
<rule ref="rulesets/java/design.xml/AbstractClassWithoutAnyMethod"/>
<rule ref="rulesets/java/design.xml/TooFewBranchesForASwitchStatement"/>
<rule ref="rulesets/java/design.xml/UseVarargs"/>
<!-- Commented out because it flagged many of the NetBeans created UI classes that place
fields at various places in the class
<rule ref="rulesets/java/design.xml/FieldDeclarationsShouldBeAtStartOfClass"/> -->
<rule ref="rulesets/java/design.xml/GodClass"/>
<rule ref="rulesets/java/design.xml/AvoidProtectedMethodInFinalClassNotExtending"/>
<rule ref="rulesets/java/design.xml/ConstantsInInterface"/>
<rule ref="rulesets/java/design.xml/CompareObjectsWithEquals"/>
<rule ref="rulesets/java/design.xml/LogicInversion"/>
<rule ref="rulesets/java/design.xml/SingularField"/>
<rule ref="rulesets/java/design.xml/SimplifyBooleanReturns"/>
<rule ref="rulesets/java/design.xml/AvoidInstanceofChecksInCatchClause"/>
<rule ref="rulesets/java/design.xml/NonCaseLabelInSwitchStatement"/>
<rule ref="rulesets/java/design.xml/NonStaticInitializer"/>
<rule ref="rulesets/java/design.xml/AvoidReassigningParameters"/>
<rule ref="rulesets/java/design.xml/SwitchStmtsShouldHaveDefault"/>
<rule ref="rulesets/java/design.xml/MissingBreakInSwitch"/>
<rule ref="rulesets/java/design.xml/EqualsNull"/>
<rule ref="rulesets/java/design.xml/UncommentedEmptyMethodBody"/>
<rule ref="rulesets/java/design.xml/SimplifyBooleanExpressions"/>
<rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic"/>
<rule ref="rulesets/java/design.xml/MissingStaticMethodInNonInstantiatableClass"/>
<rule ref="rulesets/java/design.xml/PositionLiteralsFirstInComparisons"/>
<rule ref="rulesets/java/empty.xml/EmptyCatchBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyWhileStmt"/>
<rule ref="rulesets/java/empty.xml/EmptyFinallyBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyIfStmt"/>
<rule ref="rulesets/java/empty.xml/EmptyStatementNotInLoop"/>
<rule ref="rulesets/java/empty.xml/EmptyTryBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyStatementBlock"/>
<rule ref="rulesets/java/empty.xml/EmptyStaticInitializer"/>
<rule ref="rulesets/java/empty.xml/EmptyInitializer"/>
<rule ref="rulesets/java/empty.xml/EmptySwitchStatements"/>
<rule ref="rulesets/java/empty.xml/EmptySynchronizedBlock"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeOnlyCallsSuperFinalize"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeOverloaded"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeDoesNotCallSuperFinalize"/>
<rule ref="rulesets/java/finalizers.xml/FinalizeShouldBeProtected"/>
<rule ref="rulesets/java/finalizers.xml/AvoidCallingFinalize"/>
<rule ref="rulesets/java/finalizers.xml/EmptyFinalizer"/>
<rule ref="rulesets/java/imports.xml/TooManyStaticImports"/>
<rule ref="rulesets/java/imports.xml/UnusedImports"/>
<rule ref="rulesets/java/imports.xml/ImportFromSamePackage"/>
<rule ref="rulesets/java/imports.xml/DuplicateImports"/>
<rule ref="rulesets/java/imports.xml/DontImportJavaLang"/>
<rule ref="rulesets/java/imports.xml/UnnecessaryFullyQualifiedName"/>
<!-- Disabled because it generated a lot of errors for non-Beans
<rule ref="rulesets/java/javabeans.xml/BeanMembersShouldSerialize"/>-->
<rule ref="rulesets/java/javabeans.xml/MissingSerialVersionUID"/>
<rule ref="rulesets/java/logging-java.xml/MoreThanOneLogger"/>
<rule ref="rulesets/java/logging-java.xml/LoggerIsNotStaticFinal"/>
<rule ref="rulesets/java/logging-java.xml/SystemPrintln"/>
<rule ref="rulesets/java/logging-java.xml/AvoidPrintStackTrace"/>
<rule ref="rulesets/java/logging-java.xml/GuardLogStatementJavaUtil"/>
<rule ref="rulesets/java/logging-java.xml/InvalidSlf4jMessageFormat"/>
<rule ref="rulesets/java/migrating.xml/ReplaceVectorWithList"/>
<rule ref="rulesets/java/migrating.xml/ReplaceHashtableWithMap"/>
<rule ref="rulesets/java/migrating.xml/ReplaceEnumerationWithIterator"/>
<rule ref="rulesets/java/migrating.xml/AvoidEnumAsIdentifier"/>
<rule ref="rulesets/java/migrating.xml/AvoidAssertAsIdentifier"/>
<rule ref="rulesets/java/migrating.xml/IntegerInstantiation"/>
<rule ref="rulesets/java/migrating.xml/ByteInstantiation"/>
<rule ref="rulesets/java/migrating.xml/ShortInstantiation"/>
<rule ref="rulesets/java/migrating.xml/LongInstantiation"/>
<!-- Disabled because it wanted all private static to be caps
<rule ref="rulesets/java/naming.xml/VariableNamingConventions"/> -->
<rule ref="rulesets/java/naming.xml/AvoidDollarSigns"/>
<rule ref="rulesets/java/naming.xml/AbstractNaming"/>
<rule ref="rulesets/java/naming.xml/SuspiciousHashcodeMethodName"/>
<rule ref="rulesets/java/naming.xml/SuspiciousConstantFieldName"/>
<rule ref="rulesets/java/naming.xml/SuspiciousEqualsMethodName"/>
<rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName"/>
<rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName"/>
<rule ref="rulesets/java/naming.xml/MisleadingVariableName"/>
<rule ref="rulesets/java/naming.xml/ShortClassName"/>
<rule ref="rulesets/java/naming.xml/ClassNamingConventions"/>
<rule ref="rulesets/java/naming.xml/MethodNamingConventions"/>
<rule ref="rulesets/java/naming.xml/GenericsNaming"/>
<rule ref="rulesets/java/naming.xml/NoPackage"/>
<rule ref="rulesets/java/naming.xml/MethodWithSameNameAsEnclosingClass"/>
<rule ref="rulesets/java/naming.xml/ShortVariable"/>
<rule ref="rulesets/java/naming.xml/LongVariable"/>
<rule ref="rulesets/java/naming.xml/ShortMethodName"/>
<rule ref="rulesets/java/naming.xml/BooleanGetMethodName"/>
<rule ref="rulesets/java/naming.xml/PackageCase"/>
<rule ref="rulesets/java/optimizations.xml/LocalVariableCouldBeFinal"/>
<rule ref="rulesets/java/optimizations.xml/MethodArgumentCouldBeFinal"/>
<rule ref="rulesets/java/optimizations.xml/AvoidInstantiatingObjectsInLoops"/>
<rule ref="rulesets/java/optimizations.xml/UseArrayListInsteadOfVector"/>
<rule ref="rulesets/java/optimizations.xml/SimplifyStartsWith"/>
<rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends"/>
<rule ref="rulesets/java/optimizations.xml/UseArraysAsList"/>
<rule ref="rulesets/java/optimizations.xml/AvoidArrayLoops"/>
<rule ref="rulesets/java/optimizations.xml/UnnecessaryWrapperObjectCreation"/>
<rule ref="rulesets/java/optimizations.xml/AddEmptyString"/>
<rule ref="rulesets/java/optimizations.xml/RedundantFieldInitializer"/>
<rule ref="rulesets/java/optimizations.xml/PrematureDeclaration"/>
<rule ref="rulesets/java/strictexception.xml/SignatureDeclareThrowsException"/>
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingThrowable"/>
<rule ref="rulesets/java/strictexception.xml/ExceptionAsFlowControl"/>
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingNPE"/>
<rule ref="rulesets/java/strictexception.xml/AvoidRethrowingException"/>
<rule ref="rulesets/java/strictexception.xml/DoNotExtendJavaLangError"/>
<rule ref="rulesets/java/strictexception.xml/DoNotThrowExceptionInFinally"/>
<rule ref="rulesets/java/strictexception.xml/AvoidThrowingNewInstanceOfSameException"/>
<rule ref="rulesets/java/strictexception.xml/AvoidLosingExceptionInformation"/>
<rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException"/>
<rule ref="rulesets/java/strictexception.xml/AvoidThrowingRawExceptionTypes"/>
<rule ref="rulesets/java/strictexception.xml/AvoidThrowingNullPointerException"/>
<rule ref="rulesets/java/strings.xml/AvoidDuplicateLiterals"/>
<rule ref="rulesets/java/strings.xml/InefficientStringBuffering"/>
<rule ref="rulesets/java/strings.xml/AppendCharacterWithChar"/>
<rule ref="rulesets/java/strings.xml/ConsecutiveAppendsShouldReuse"/>
<rule ref="rulesets/java/strings.xml/ConsecutiveLiteralAppends"/>
<rule ref="rulesets/java/strings.xml/UseIndexOfChar"/>
<rule ref="rulesets/java/strings.xml/InefficientEmptyStringCheck"/>
<rule ref="rulesets/java/strings.xml/InsufficientStringBufferDeclaration"/>
<rule ref="rulesets/java/strings.xml/UselessStringValueOf"/>
<rule ref="rulesets/java/strings.xml/StringBufferInstantiationWithChar"/>
<rule ref="rulesets/java/strings.xml/AvoidStringBufferField"/>
<rule ref="rulesets/java/strings.xml/StringInstantiation"/>
<rule ref="rulesets/java/strings.xml/UseEqualsToCompareStrings"/>
<rule ref="rulesets/java/strings.xml/StringToString"/>
<rule ref="rulesets/java/strings.xml/UseStringBufferLength"/>
<rule ref="rulesets/java/strings.xml/UnnecessaryCaseChange"/>
<rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray"/>
<rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly"/>
<rule ref="rulesets/java/typeresolution.xml/LooseCoupling"/>
<rule ref="rulesets/java/typeresolution.xml/CloneMethodMustImplementCloneable"/>
<rule ref="rulesets/java/typeresolution.xml/UnusedImports"/>
<rule ref="rulesets/java/typeresolution.xml/SignatureDeclareThrowsException"/>
<rule ref="rulesets/java/unnecessary.xml/UnnecessaryConversionTemporary"/>
<rule ref="rulesets/java/unnecessary.xml/UnnecessaryFinalModifier"/>
<rule ref="rulesets/java/unnecessary.xml/UselessOverridingMethod"/>
<rule ref="rulesets/java/unnecessary.xml/UnusedNullCheckInEquals"/>
<rule ref="rulesets/java/unnecessary.xml/UselessParentheses"/>
<rule ref="rulesets/java/unnecessary.xml/UselessQualifiedThis"/>
<rule ref="rulesets/java/unnecessary.xml/UselessOperationOnImmutable"/>
<rule ref="rulesets/java/unnecessary.xml/UnnecessaryReturn"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedModifier"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedLocalVariable"/>
<!-- Commented out because it flagged many event listeners and other interfaces.
<rule ref="rulesets/java/unusedcode.xml/UnusedFormalParameter"/> -->
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateField"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateMethod"/>
</ruleset>

View File

@ -810,7 +810,7 @@ class TestConfiguration(object):
if parsed_config.getElementsByTagName("singleUser_golddir"):
self.singleUser_gold = parsed_config.getElementsByTagName("singleUser_golddir")[0].getAttribute("value").encode().decode("utf_8")
if parsed_config.getElementsByTagName("timing"):
self.timing = parsed_config.getElementsByTagName("timing")[0].getAttribute("value").encode().decode("utf_8")
self.timing = ("True" == parsed_config.getElementsByTagName("timing")[0].getAttribute("value").encode().decode("utf_8"))
if parsed_config.getElementsByTagName("autopsyPlatform"):
self.autopsyPlatform = parsed_config.getElementsByTagName("autopsyPlatform")[0].getAttribute("value").encode().decode("utf_8")
# Multi-user settings
@ -1392,7 +1392,7 @@ class Logs(object):
try:
Logs._fill_ingest_data(test_data)
except Exception as e:
Errors.print_error("Error: Unknown fatal error when filling test_config data.")
Errors.print_error("Error when filling test_config data.")
Errors.print_error(str(e) + "\n")
logging.critical(traceback.format_exc())
# If running in verbose mode (-v)
@ -1454,10 +1454,10 @@ class Logs(object):
Errors.print_error("Error: Unable to open autopsy.log.0.")
Errors.print_error(str(e) + "\n")
logging.warning(traceback.format_exc())
# Start date must look like: "Fri Mar 27 13:27:34 EDT 2015"
# Start date must look like: ""
# End date must look like: "Mon Jul 16 13:02:42 2012"
# *** If logging time format ever changes this will break ***
start = datetime.datetime.strptime(test_data.start_date, "%a %b %d %H:%M:%S %Z %Y")
start = datetime.datetime.strptime(test_data.start_date, "%Y-%m-%d %H:%M:%S.%f")
end = datetime.datetime.strptime(test_data.end_date, "%a %b %d %H:%M:%S %Y")
test_data.total_test_time = str(end - start)
@ -1469,7 +1469,6 @@ class Logs(object):
test_data.heap_space = search_logs("Heap memory usage:", test_data)[0].rstrip().split(": ")[1]
ingest_line = search_logs("Ingest (including enqueue)", test_data)[0]
test_data.total_ingest_time = get_word_at(ingest_line, 6).rstrip()
message_line_count = find_msg_in_log_set("Ingest messages count:", test_data)
test_data.indexed_files = message_line_count