Merge branch '3788-intercase-correlation' of https://github.com/briangsweeney/autopsy into 3788-intercase-correlation

This commit is contained in:
Brian Sweeney 2018-05-11 13:13:50 -06:00
commit aa10c0b071
10 changed files with 921 additions and 415 deletions

View File

@ -279,7 +279,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void updateCase(CorrelationCase eamCase) throws EamDbException {
if(eamCase == null) {
if (eamCase == null) {
throw new EamDbException("CorrelationCase argument is null");
}
@ -457,7 +457,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
if(correlationCase == null) {
if (correlationCase == null) {
throw new EamDbException("CorrelationCase argument is null");
}
@ -530,13 +530,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
if(eamArtifact == null) {
if (eamArtifact == null) {
throw new EamDbException("CorrelationAttribute is null");
}
if(eamArtifact.getCorrelationType() == null) {
if (eamArtifact.getCorrelationType() == null) {
throw new EamDbException("Correlation type is null");
}
if(eamArtifact.getCorrelationValue() == null) {
if (eamArtifact.getCorrelationValue() == null) {
throw new EamDbException("Correlation value is null");
}
@ -559,13 +559,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql.toString());
for (CorrelationAttributeInstance eamInstance : eamInstances) {
if (!eamArtifact.getCorrelationValue().isEmpty()) {
if(eamInstance.getCorrelationCase() == null) {
if (eamInstance.getCorrelationCase() == null) {
throw new EamDbException("CorrelationAttributeInstance has null case");
}
if(eamInstance.getCorrelationDataSource() == null) {
if (eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("CorrelationAttributeInstance has null data source");
}
if(eamInstance.getKnownStatus() == null) {
if (eamInstance.getKnownStatus() == null) {
throw new EamDbException("CorrelationAttributeInstance has null known status");
}
@ -605,7 +605,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
Connection conn = connect();
@ -647,6 +647,82 @@ public abstract class AbstractSqlEamDb implements EamDb {
return artifactInstances;
}
/**
* Retrieves eamArtiifact instances from the database that match
* the given list of MD5 values and optionally filters by given case.
*
* @param correlationCase Case id to search on, if null, searches all cases
* @param values List of ArtifactInstance MD5 values to find matches of.
*
* @return List of artifact instances for a given list of MD5 values
*/
@Override
public List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List<String> values) throws EamDbException {
CorrelationAttribute.Type aType = CorrelationAttribute.getDefaultCorrelationTypes().get(0); // Files type
if (aType == null) {
throw new EamDbException("Correlation Type is null");
}
boolean singleCase = false;
if (correlationCase != null) {
singleCase = false;
}
Connection conn = connect();
List<CorrelationAttributeCommonInstance> artifactInstances = new ArrayList<>();
CorrelationAttributeCommonInstance artifactInstance;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
String valuesString = "";
StringBuilder valuesFilter = new StringBuilder(values.size());
if (!values.isEmpty()) {
for (String value : values) {
valuesFilter.append("'").append(value).append("',");
}
valuesString = valuesFilter.toString().substring(0, valuesFilter.length() - 1);
}
String tableName = EamDbUtil.correlationTypeToInstanceTableName(aType);
StringBuilder sql = new StringBuilder(9);
sql.append("SELECT cases.case_name, cases.case_uid, data_sources.name, device_id, file_path, known_status, comment, data_sources.case_id, value FROM ");
sql.append(tableName);
sql.append(" LEFT JOIN cases ON ");
sql.append(tableName);
sql.append(".case_id=cases.id");
sql.append(" LEFT JOIN data_sources ON ");
sql.append(tableName);
sql.append(".data_source_id=data_sources.id");
sql.append(" WHERE value IN (?)");
if (singleCase) {
sql.append(" AND ");
sql.append(tableName);
sql.append(".case_id = ?");
}
try {
preparedStatement = conn.prepareStatement(sql.toString());
preparedStatement.setString(1, valuesString);
if (singleCase && correlationCase != null) {
preparedStatement.setString(2, String.valueOf(correlationCase.getID()));
}
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
artifactInstance = getCommonEamArtifactInstanceFromResultSet(resultSet);
artifactInstances.add(artifactInstance);
}
} catch (SQLException ex) {
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally {
EamDbUtil.closePreparedStatement(preparedStatement);
EamDbUtil.closeResultSet(resultSet);
EamDbUtil.closeConnection(conn);
}
return artifactInstances;
}
/**
* Retrieves eamArtifact instances from the database that are associated
* with the aType and filePath
@ -660,10 +736,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
if(filePath == null) {
if (filePath == null) {
throw new EamDbException("Correlation value is null");
}
Connection conn = connect();
@ -717,10 +793,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
if(value == null) {
if (value == null) {
throw new EamDbException("Correlation value is null");
}
@ -776,7 +852,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
@ -901,7 +977,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override
public void prepareBulkArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
if(eamArtifact.getCorrelationType() == null) {
if (eamArtifact.getCorrelationType() == null) {
throw new EamDbException("Correlation type is null");
}
@ -959,13 +1035,13 @@ public abstract class AbstractSqlEamDb implements EamDb {
for (CorrelationAttributeInstance eamInstance : eamInstances) {
if (!eamArtifact.getCorrelationValue().isEmpty()) {
if(eamInstance.getCorrelationCase() == null) {
if (eamInstance.getCorrelationCase() == null) {
throw new EamDbException("Correlation attribute instance has null case");
}
if(eamInstance.getCorrelationDataSource() == null) {
if (eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("Correlation attribute instance has null data source");
}
if(eamInstance.getKnownStatus()== null) {
if (eamInstance.getKnownStatus() == null) {
throw new EamDbException("Correlation attribute instance has null known known status");
}
@ -1005,7 +1081,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
if(cases == null) {
if (cases == null) {
throw new EamDbException("cases argument is null");
}
@ -1081,21 +1157,21 @@ public abstract class AbstractSqlEamDb implements EamDb {
}
/**
* Sets an eamArtifact instance to the given knownStatus.
* knownStatus should be BAD if the file has been tagged with a notable tag and
* UNKNOWN otherwise. If eamArtifact
* exists, it is updated. If eamArtifact does not exist it is added with the
* given status.
* Sets an eamArtifact instance to the given knownStatus. knownStatus should
* be BAD if the file has been tagged with a notable tag and UNKNOWN
* otherwise. If eamArtifact exists, it is updated. If eamArtifact does not
* exist it is added with the given status.
*
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
* @param knownStatus The status to change the artifact to. Should never be KNOWN
* @param knownStatus The status to change the artifact to. Should never be
* KNOWN
*/
@Override
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
if(eamArtifact == null) {
if (eamArtifact == null) {
throw new EamDbException("Correlation attribute is null");
}
if(knownStatus == null) {
if (knownStatus == null) {
throw new EamDbException("Known status is null");
}
if (1 != eamArtifact.getInstances().size()) {
@ -1105,10 +1181,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
List<CorrelationAttributeInstance> eamInstances = eamArtifact.getInstances();
CorrelationAttributeInstance eamInstance = eamInstances.get(0);
if(eamInstance.getCorrelationCase() == null) {
if (eamInstance.getCorrelationCase() == null) {
throw new EamDbException("Correlation case is null");
}
if(eamInstance.getCorrelationDataSource() == null) {
if (eamInstance.getCorrelationDataSource() == null) {
throw new EamDbException("Correlation data source is null");
}
@ -1196,7 +1272,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
@ -1250,7 +1326,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
@ -1298,7 +1374,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("Correlation type is null");
}
@ -1418,7 +1494,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override
public boolean referenceSetIsValid(int referenceSetID, String setName, String version) throws EamDbException {
EamGlobalSet refSet = this.getReferenceSetByID(referenceSetID);
if(refSet == null) {
if (refSet == null) {
return false;
}
@ -1487,7 +1563,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("null correlation type");
}
@ -1532,7 +1608,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public long newOrganization(EamOrganization eamOrg) throws EamDbException {
if(eamOrg == null) {
if (eamOrg == null) {
throw new EamDbException("EamOrganization is null");
}
@ -1642,7 +1718,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
public EamOrganization getReferenceSetOrganization(int referenceSetID) throws EamDbException {
EamGlobalSet globalSet = getReferenceSetByID(referenceSetID);
if(globalSet == null) {
if (globalSet == null) {
throw new EamDbException("Reference set with ID " + referenceSetID + " not found");
}
return (getOrganizationByID(globalSet.getOrgID()));
@ -1658,7 +1734,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
if(updatedOrganization == null) {
if (updatedOrganization == null) {
throw new EamDbException("null updatedOrganization");
}
@ -1686,7 +1762,7 @@ 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) {
if (organizationToDelete == null) {
throw new EamDbException("Organization to delete is null");
}
@ -1729,15 +1805,15 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
if(eamGlobalSet == null){
if (eamGlobalSet == null) {
throw new EamDbException("EamGlobalSet argument is null");
}
if(eamGlobalSet.getFileKnownStatus() == null){
if (eamGlobalSet.getFileKnownStatus() == null) {
throw new EamDbException("File known status on the EamGlobalSet is null");
}
if(eamGlobalSet.getType() == null){
if (eamGlobalSet.getType() == null) {
throw new EamDbException("Type on the EamGlobalSet is null");
}
@ -1803,7 +1879,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement1 = conn.prepareStatement(sql1);
preparedStatement1.setInt(1, referenceSetID);
resultSet = preparedStatement1.executeQuery();
if(resultSet.next()) {
if (resultSet.next()) {
return getEamGlobalSetFromResultSet(resultSet);
} else {
return null;
@ -1830,7 +1906,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
@Override
public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
if(correlationType == null){
if (correlationType == null) {
throw new EamDbException("Correlation type is null");
}
@ -1868,10 +1944,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
if(eamGlobalFileInstance.getKnownStatus() == null){
if (eamGlobalFileInstance.getKnownStatus() == null) {
throw new EamDbException("known status of EamGlobalFileInstance is null");
}
if(correlationType == null){
if (correlationType == null) {
throw new EamDbException("Correlation type is null");
}
@ -1939,10 +2015,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
if(contentType == null) {
if (contentType == null) {
throw new EamDbException("Null correlation type");
}
if(globalInstances == null) {
if (globalInstances == null) {
throw new EamDbException("Null set of EamGlobalFileInstance");
}
@ -1959,7 +2035,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkPs = conn.prepareStatement(String.format(sql, EamDbUtil.correlationTypeToReferenceTableName(contentType)));
for (EamGlobalFileInstance globalInstance : globalInstances) {
if(globalInstance.getKnownStatus() == null){
if (globalInstance.getKnownStatus() == null) {
throw new EamDbException("EamGlobalFileInstance with value " + globalInstance.getMD5Hash() + " has null known status");
}
@ -1997,7 +2073,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
*/
@Override
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
if(aType == null) {
if (aType == null) {
throw new EamDbException("correlation type is null");
}
@ -2245,7 +2321,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1, typeId);
resultSet = preparedStatement.executeQuery();
if(resultSet.next()) {
if (resultSet.next()) {
aType = getCorrelationTypeFromResultSet(resultSet);
return aType;
} else {
@ -2356,6 +2432,32 @@ public abstract class AbstractSqlEamDb implements EamDb {
return eamArtifactInstance;
}
/**
* Convert a ResultSet to a Common EamArtifactInstance object
*
* @param resultSet A resultSet with a set of values to create a
* EamArtifactInstance object.
*
* @return fully populated EamArtifactInstance, or null
*
* @throws SQLException when an expected column name is not in the resultSet
*/
private CorrelationAttributeCommonInstance getCommonEamArtifactInstanceFromResultSet(ResultSet resultSet) throws SQLException, EamDbException {
if (null == resultSet) {
return null;
}
CorrelationAttributeCommonInstance eamArtifactInstance = new CorrelationAttributeCommonInstance(
new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")),
new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")),
resultSet.getString("file_path"),
resultSet.getString("comment"),
TskData.FileKnown.valueOf(resultSet.getByte("known_status")),
resultSet.getString("value")
);
return eamArtifactInstance;
}
private EamOrganization getEamOrganizationFromResultSet(ResultSet resultSet) throws SQLException {
if (null == resultSet) {
return null;

View File

@ -0,0 +1,46 @@
/*
* Central Repository
*
* Copyright 2015-2017 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.centralrepository.datamodel;
import org.sleuthkit.datamodel.TskData;
/**
* Common Files Search usage which extends CorrelationAttributeInstance
* by adding the MD5 value to match on for the results table.
*/
public class CorrelationAttributeCommonInstance extends CorrelationAttributeInstance {
private static final long serialVersionUID = 1L;
/**
* The common MD5 value
*/
private final String value;
public CorrelationAttributeCommonInstance(CorrelationCase eamCase, CorrelationDataSource eamDataSource, String filePath, String comment, TskData.FileKnown knownStatus, String value) throws EamDbException {
super(eamCase, eamDataSource, filePath, comment, knownStatus);
this.value = value;
}
public String getValue() {
return value;
}
}

View File

@ -223,6 +223,17 @@ public interface EamDb {
*/
List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException;
/**
* Retrieves eamArtiifact instances from the database that match the given
* list of MD5 values;
*
* @param correlationCase Case id to search on
* @param values List of ArtifactInstance MD5 values to find matches of.
*
* @return List of artifact instances for a given list of MD5 values
*/
List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List<String> values) throws EamDbException;
/**
* Retrieves eamArtifact instances from the database that are associated
* with the aType and filePath

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.apache.commons.dbcp2.BasicDataSource;

View File

@ -34,9 +34,9 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
/**
* Sqlite implementation of the Central Repository database.
* All methods in AbstractSqlEamDb that read or write to the database should
* be overriden here and use appropriate locking.
* Sqlite implementation of the Central Repository database. All methods in
* AbstractSqlEamDb that read or write to the database should be overriden here
* and use appropriate locking.
*/
public class SqliteEamDb extends AbstractSqlEamDb {
@ -57,7 +57,8 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*
* @return the singleton instance of SqliteEamDb
*
* @throws EamDbException if one or more default correlation type(s) have an invalid db table name.
* @throws EamDbException if one or more default correlation type(s) have an
* invalid db table name.
*/
public synchronized static SqliteEamDb getInstance() throws EamDbException {
if (instance == null) {
@ -69,8 +70,8 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
*
* @throws EamDbException if the AbstractSqlEamDb class has one or more default
* correlation type(s) having an invalid db table name.
* @throws EamDbException if the AbstractSqlEamDb class has one or more
* default correlation type(s) having an invalid db table name.
*/
private SqliteEamDb() throws EamDbException {
dbSettings = new SqliteEamDbSettings();
@ -80,7 +81,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override
public void shutdownConnections() throws EamDbException {
try {
synchronized(this) {
synchronized (this) {
if (null != connectionPool) {
connectionPool.close();
connectionPool = null; // force it to be re-created on next connect()
@ -108,7 +109,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override
public void reset() throws EamDbException {
try{
try {
acquireExclusiveLock();
Connection conn = connect();
@ -201,7 +202,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
return "";
}
/**
* Add a new name/value pair in the db_info table.
*
@ -212,7 +212,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void newDbInfo(String name, String value) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.newDbInfo(name, value);
} finally {
@ -231,7 +231,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public String getDbInfo(String name) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getDbInfo(name);
} finally {
@ -249,7 +249,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void updateDbInfo(String name, String value) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.updateDbInfo(name, value);
} finally {
@ -264,7 +264,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public CorrelationCase newCase(Case autopsyCase) throws EamDbException {
try{
try {
acquireExclusiveLock();
return super.newCase(autopsyCase);
} finally {
@ -281,7 +281,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
try{
try {
acquireExclusiveLock();
return super.newCase(eamCase);
} finally {
@ -296,7 +296,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void updateCase(CorrelationCase eamCase) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.updateCase(eamCase);
} finally {
@ -313,7 +313,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public CorrelationCase getCaseByUUID(String caseUUID) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCaseByUUID(caseUUID);
} finally {
@ -328,7 +328,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationCase> getCases() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCases();
} finally {
@ -343,7 +343,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void newDataSource(CorrelationDataSource eamDataSource) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.newDataSource(eamDataSource);
} finally {
@ -354,14 +354,15 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
* Retrieves Data Source details based on data source device ID
*
* @param correlationCase the current CorrelationCase used for ensuring uniqueness of DataSource
* @param correlationCase the current CorrelationCase used for ensuring
* uniqueness of DataSource
* @param dataSourceDeviceId the data source device ID number
*
* @return The data source
*/
@Override
public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getDataSource(correlationCase, dataSourceDeviceId);
} finally {
@ -376,7 +377,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationDataSource> getDataSources() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getDataSources();
} finally {
@ -392,7 +393,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void addArtifact(CorrelationAttribute eamArtifact) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.addArtifact(eamArtifact);
} finally {
@ -411,7 +412,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getArtifactInstancesByTypeValue(aType, value);
} finally {
@ -419,6 +420,25 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
}
/**
* Retrieves eamArtiifact instances from the database that match the given
* list of MD5 values;
*
* @param correlationCase Case id to search on
* @param values List of ArtifactInstance MD5 values to find matches of.
*
* @return List of artifact instances for a given list of MD5 values
*/
@Override
public List<CorrelationAttributeCommonInstance> getArtifactInstancesByCaseValues(CorrelationCase correlationCase, List<String> values) throws EamDbException {
try {
acquireSharedLock();
return super.getArtifactInstancesByCaseValues(correlationCase, values);
} finally {
releaseSharedLock();
}
}
/**
* Retrieves eamArtifact instances from the database that are associated
* with the aType and filePath
@ -432,7 +452,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesByPath(CorrelationAttribute.Type aType, String filePath) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getArtifactInstancesByPath(aType, filePath);
} finally {
@ -453,7 +473,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public Long getCountArtifactInstancesByTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCountArtifactInstancesByTypeValue(aType, value);
} finally {
@ -463,7 +483,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override
public int getFrequencyPercentage(CorrelationAttribute corAttr) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getFrequencyPercentage(corAttr);
} finally {
@ -484,7 +504,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCountUniqueCaseDataSourceTuplesHavingTypeValue(aType, value);
} finally {
@ -492,10 +512,9 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
}
@Override
public Long getCountUniqueDataSources() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCountUniqueDataSources();
} finally {
@ -516,7 +535,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public Long getCountArtifactInstancesByCaseDataSource(String caseUUID, String dataSourceID) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCountArtifactInstancesByCaseDataSource(caseUUID, dataSourceID);
} finally {
@ -530,7 +549,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void bulkInsertArtifacts() throws EamDbException {
try{
try {
acquireExclusiveLock();
super.bulkInsertArtifacts();
} finally {
@ -543,7 +562,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void bulkInsertCases(List<CorrelationCase> cases) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.bulkInsertCases(cases);
} finally {
@ -552,18 +571,18 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
/**
* Sets an eamArtifact instance to the given knownStatus.
* knownStatus should be BAD if the file has been tagged with a notable tag and
* UNKNOWN otherwise. If eamArtifact
* exists, it is updated. If eamArtifact does not exist it is added with the
* given status.
* Sets an eamArtifact instance to the given knownStatus. knownStatus should
* be BAD if the file has been tagged with a notable tag and UNKNOWN
* otherwise. If eamArtifact exists, it is updated. If eamArtifact does not
* exist it is added with the given status.
*
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
* @param knownStatus The status to change the artifact to. Should never be KNOWN
* @param knownStatus The status to change the artifact to. Should never be
* KNOWN
*/
@Override
public void setArtifactInstanceKnownStatus(CorrelationAttribute eamArtifact, TskData.FileKnown knownStatus) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.setArtifactInstanceKnownStatus(eamArtifact, knownStatus);
} finally {
@ -582,7 +601,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationAttributeInstance> getArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getArtifactInstancesKnownBad(aType, value);
} finally {
@ -600,7 +619,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public Long getCountArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCountArtifactInstancesKnownBad(aType, value);
} finally {
@ -622,7 +641,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getListCasesHavingArtifactInstancesKnownBad(aType, value);
} finally {
@ -632,12 +651,13 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
* Remove a reference set and all values contained in it.
*
* @param referenceSetID
* @throws EamDbException
*/
@Override
public void deleteReferenceSet(int referenceSetID) throws EamDbException{
try{
public void deleteReferenceSet(int referenceSetID) throws EamDbException {
try {
acquireExclusiveLock();
super.deleteReferenceSet(referenceSetID);
} finally {
@ -647,6 +667,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
* Check if the given hash is in a specific reference set
*
* @param value
* @param referenceSetID
* @param correlationTypeID
@ -654,7 +675,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public boolean isValueInReferenceSet(String value, int referenceSetID, int correlationTypeID) throws EamDbException {
try{
try {
acquireSharedLock();
return super.isValueInReferenceSet(value, referenceSetID, correlationTypeID);
} finally {
@ -663,8 +684,10 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
/**
* Check whether a reference set with the given name/version is in the central repo.
* Used to check for name collisions when creating reference sets.
* Check whether a reference set with the given name/version is in the
* central repo. Used to check for name collisions when creating reference
* sets.
*
* @param referenceSetName
* @param version
* @return true if a matching set is found
@ -672,7 +695,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public boolean referenceSetExists(String referenceSetName, String version) throws EamDbException {
try{
try {
acquireSharedLock();
return super.referenceSetExists(referenceSetName, version);
} finally {
@ -690,7 +713,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public boolean isArtifactKnownBadByReference(CorrelationAttribute.Type aType, String value) throws EamDbException {
try{
try {
acquireSharedLock();
return super.isArtifactKnownBadByReference(aType, value);
} finally {
@ -709,7 +732,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public long newOrganization(EamOrganization eamOrg) throws EamDbException {
try{
try {
acquireExclusiveLock();
return super.newOrganization(eamOrg);
} finally {
@ -726,7 +749,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<EamOrganization> getOrganizations() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getOrganizations();
} finally {
@ -745,7 +768,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public EamOrganization getOrganizationByID(int orgID) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getOrganizationByID(orgID);
} finally {
@ -755,7 +778,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override
public void updateOrganization(EamOrganization updatedOrganization) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.updateOrganization(updatedOrganization);
} finally {
@ -765,13 +788,14 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override
public void deleteOrganization(EamOrganization organizationToDelete) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.deleteOrganization(organizationToDelete);
} finally {
releaseExclusiveLock();
}
}
/**
* Add a new Global Set
*
@ -783,7 +807,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public int newReferenceSet(EamGlobalSet eamGlobalSet) throws EamDbException {
try{
try {
acquireExclusiveLock();
return super.newReferenceSet(eamGlobalSet);
} finally {
@ -802,7 +826,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public EamGlobalSet getReferenceSetByID(int referenceSetID) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getReferenceSetByID(referenceSetID);
} finally {
@ -821,7 +845,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<EamGlobalSet> getAllReferenceSets(CorrelationAttribute.Type correlationType) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getAllReferenceSets(correlationType);
} finally {
@ -833,14 +857,13 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* Add a new reference instance
*
* @param eamGlobalFileInstance The reference instance to add
* @param correlationType Correlation Type that this Reference
* Instance is
* @param correlationType Correlation Type that this Reference Instance is
*
* @throws EamDbException
*/
@Override
public void addReferenceInstance(EamGlobalFileInstance eamGlobalFileInstance, CorrelationAttribute.Type correlationType) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.addReferenceInstance(eamGlobalFileInstance, correlationType);
} finally {
@ -855,7 +878,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void bulkInsertReferenceTypeEntries(Set<EamGlobalFileInstance> globalInstances, CorrelationAttribute.Type contentType) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.bulkInsertReferenceTypeEntries(globalInstances, contentType);
} finally {
@ -875,7 +898,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<EamGlobalFileInstance> getReferenceInstancesByTypeValue(CorrelationAttribute.Type aType, String aValue) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getReferenceInstancesByTypeValue(aType, aValue);
} finally {
@ -894,7 +917,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public int newCorrelationType(CorrelationAttribute.Type newType) throws EamDbException {
try{
try {
acquireExclusiveLock();
return super.newCorrelationType(newType);
} finally {
@ -913,7 +936,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationAttribute.Type> getDefinedCorrelationTypes() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getDefinedCorrelationTypes();
} finally {
@ -932,7 +955,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationAttribute.Type> getEnabledCorrelationTypes() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getEnabledCorrelationTypes();
} finally {
@ -951,7 +974,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public List<CorrelationAttribute.Type> getSupportedCorrelationTypes() throws EamDbException {
try{
try {
acquireSharedLock();
return super.getSupportedCorrelationTypes();
} finally {
@ -968,7 +991,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public void updateCorrelationType(CorrelationAttribute.Type aType) throws EamDbException {
try{
try {
acquireExclusiveLock();
super.updateCorrelationType(aType);
} finally {
@ -987,7 +1010,7 @@ public class SqliteEamDb extends AbstractSqlEamDb {
*/
@Override
public CorrelationAttribute.Type getCorrelationTypeById(int typeId) throws EamDbException {
try{
try {
acquireSharedLock();
return super.getCorrelationTypeById(typeId);
} finally {
@ -997,11 +1020,12 @@ public class SqliteEamDb extends AbstractSqlEamDb {
/**
* Upgrade the schema of the database (if needed)
*
* @throws EamDbException
*/
@Override
public void upgradeSchema() throws EamDbException, SQLException {
try{
try {
acquireExclusiveLock();
super.upgradeSchema();
} finally {
@ -1010,50 +1034,52 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
/**
* Gets an exclusive lock (if applicable).
* Will return the lock if successful, null if unsuccessful because locking
* isn't supported, and throw an exception if we should have been able to get the
* lock but failed (meaning the database is in use).
* Gets an exclusive lock (if applicable). Will return the lock if
* successful, null if unsuccessful because locking isn't supported, and
* throw an exception if we should have been able to get the lock but failed
* (meaning the database is in use).
*
* @return the lock, or null if locking is not supported
* @throws EamDbException if the coordination service is running but we fail to get the lock
* @throws EamDbException if the coordination service is running but we fail
* to get the lock
*/
@Override
public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{
public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException {
// Multiple users are not supported for SQLite
return null;
}
/**
* Acquire the lock that provides exclusive access to the case database.
* Call this method in a try block with a call to
* the lock release method in an associated finally block.
* Call this method in a try block with a call to the lock release method in
* an associated finally block.
*/
private void acquireExclusiveLock() {
rwLock.writeLock().lock();
}
/**
* Release the lock that provides exclusive access to the database.
* This method should always be called in the finally
* block of a try block in which the lock was acquired.
* Release the lock that provides exclusive access to the database. This
* method should always be called in the finally block of a try block in
* which the lock was acquired.
*/
private void releaseExclusiveLock() {
rwLock.writeLock().unlock();
}
/**
* Acquire the lock that provides shared access to the case database.
* Call this method in a try block with a call to the
* lock release method in an associated finally block.
* Acquire the lock that provides shared access to the case database. Call
* this method in a try block with a call to the lock release method in an
* associated finally block.
*/
private void acquireSharedLock() {
rwLock.readLock().lock();
}
/**
* Release the lock that provides shared access to the database.
* This method should always be called in the finally block
* of a try block in which the lock was acquired.
* Release the lock that provides shared access to the database. This method
* should always be called in the finally block of a try block in which the
* lock was acquired.
*/
private void releaseSharedLock() {
rwLock.readLock().unlock();

View File

@ -0,0 +1,58 @@
/*
*
* 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.commonfilesearch;
import java.util.Map;
import static org.sleuthkit.autopsy.commonfilesearch.CommonFilesMetadataBuilder.SELECT_PREFIX;
/**
* Provides logic for selecting common files from all data sources for all files to source for EamDB query.
*/
public class AllDataSourcesEamDbCommonFilesAlgorithm extends CommonFilesMetadataBuilder {
private static final String WHERE_CLAUSE = "%s md5 in (select md5 from tsk_files where (known != 1 OR known IS NULL)%s GROUP BY md5) order by md5"; //NON-NLS
/**
* Implements the algorithm for getting common files across all data
* sources.
*
* @param dataSourceIdMap a map of obj_id to datasource name
* @param filterByMediaMimeType match only on files whose mime types can be broadly categorized as media types
* @param filterByDocMimeType match only on files whose mime types can be broadly categorized as document types
*/
AllDataSourcesEamDbCommonFilesAlgorithm(Map<Long, String> dataSourceIdMap, boolean filterByMediaMimeType, boolean filterByDocMimeType) {
super(dataSourceIdMap, filterByMediaMimeType, filterByDocMimeType);
}
@Override
protected String buildSqlSelectStatement() {
Object[] args = new String[]{SELECT_PREFIX, determineMimeTypeFilter()};
return String.format(WHERE_CLAUSE, args);
}
@Override
protected String buildTabTitle() {
final String buildCategorySelectionString = this.buildCategorySelectionString();
final String titleTemplate = Bundle.CommonFilesMetadataBuilder_buildTabTitle_titleEamDb();
return String.format(titleTemplate, new Object[]{buildCategorySelectionString});
}
}

View File

@ -1,15 +1,21 @@
CommonFilesPanel.searchButton.text=Search
CommonFilesPanel.withinDataSourceRadioButton.text=At least one instance of a given MD5 must appear in the data source selected below:
CommonFilesPanel.allDataSourcesRadioButton.text=Files can be in any data source
CommonFilesPanel.withinDataSourceRadioButton.text=At least one match must appear in the data source selected below:
CommonFilesPanel.allDataSourcesRadioButton.text=Matches may be from any data source
CommonFilesPanel.cancelButton.text=Cancel
CommonFilesPanel.cancelButton.actionCommand=Cancel
CommonFilesPanel.selectedFileCategoriesButton.text=Match on the following file categories:
CommonFilesPanel.selectedFileCategoriesButton.toolTipText=Select from the options below...
CommonFilesPanel.pictureVideoCheckbox.text=Pictures and Videos
CommonFilesPanel.documentsCheckbox.text=Documents
CommonFilesPanel.commonFilesSearchLabel.text=<html>Find duplicate files in the current case.</html>
CommonFilesPanel.allFileCategoriesRadioButton.toolTipText=No filtering applied to results...
CommonFilesPanel.allFileCategoriesRadioButton.text=Match on all file types
CommonFilesPanel.text=Indicate which data sources to consider while searching for duplicates:
CommonFilesPanel.categoriesLabel.text=Indicate which file types to include in results:
CommonFilesPanel.errorText.text=In order to search, you must select a file category.
CommonFilesPanel.commonFilesSearchLabel1.text=<html>Find Common Files.</html>
CommonFilesPanel.jRadioButton1.text=jRadioButton1
CommonFilesPanel.jRadioButton2.text=Correlate amongst external cases (compares files in current case with Central Repo)
CommonFilesPanel.intraCaseRadio.label=Correlate within current case only
CommonFilesPanel.interCaseRadio.label=Correlate amongst all known cases (uses Central Repo)
CommonFilesPanel.anCentralRepoCaseRadio.text_1=Matches may be from any Central Repo case
CommonFilesPanel.specificCentralRepoCaseRadio.text_1=Matches must be from the following Central Repo case:

View File

@ -22,16 +22,25 @@ package org.sleuthkit.autopsy.commonfilesearch;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeCommonInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationCase;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDb;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbException;
import static org.sleuthkit.autopsy.timeline.datamodel.eventtype.ArtifactEventType.LOGGER;
import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
@ -202,6 +211,64 @@ abstract class CommonFilesMetadataBuilder {
return new CommonFilesMetadata(commonFiles);
}
/**
* TODO Refactor, abstract shared code above, call this method via new AllDataSourcesEamDbCommonFilesAlgorithm Class
* @param correlationCase Optionally null, otherwise a case, or could be a CR case ID
* @return
* @throws TskCoreException
* @throws NoCurrentCaseException
* @throws SQLException
* @throws EamDbException
*/
public CommonFilesMetadata findEamDbCommonFiles(CorrelationCase correlationCase) throws TskCoreException, NoCurrentCaseException, SQLException, EamDbException {
CommonFilesMetadata metaData = this.findCommonFiles();
Map<String, Md5Metadata> commonFiles = metaData.getMetadata();
List<String> values = Arrays.asList((String[]) commonFiles.keySet().toArray());
Map<String, Md5Metadata> interCaseCommonFiles = metaData.getMetadata();
try {
EamDb dbManager = EamDb.getInstance();
Collection<CorrelationAttributeCommonInstance> artifactInstances = dbManager.getArtifactInstancesByCaseValues(correlationCase, values).stream()
.collect(Collectors.toList());
for (CorrelationAttributeCommonInstance instance : artifactInstances) {
//Long objectId = 1L; //TODO, need to retrieve ALL (even count < 2) AbstractFiles from this case to us for objectId for CR matches;
String md5 = instance.getValue();
String dataSource = instance.getCorrelationDataSource().getName();
if (md5 == null || HashUtility.isNoDataMd5(md5)) {
continue;
}
//Builds a 3rd list which contains instances which are in commonFiles map, uses current case objectId
if (commonFiles.containsKey(md5)) {
// TODO sloppy, but we don't *have* all the information for the rows in the CR, so what do we do?
Long objectId = commonFiles.get(md5).getMetadata().iterator().next().getObjectId();
if(interCaseCommonFiles.containsKey(md5)) {
//Add to intercase metaData
final Md5Metadata md5Metadata = interCaseCommonFiles.get(md5);
md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource));
} else {
// Create new intercase metadata
final Md5Metadata md5Metadata = commonFiles.get(md5);
md5Metadata.addFileInstanceMetadata(new FileInstanceMetadata(objectId, dataSource));
interCaseCommonFiles.put(md5, md5Metadata);
}
} else {
// TODO This should never happen. All current case files with potential matches are in comonFiles Map.
}
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS
}
// Builds intercase-only matches metadata
return new CommonFilesMetadata(interCaseCommonFiles);
}
/**
* Should be used by subclasses, in their
* <code>buildSqlSelectStatement()</code> function to create an SQL boolean
@ -235,7 +302,8 @@ abstract class CommonFilesMetadataBuilder {
@NbBundle.Messages({
"CommonFilesMetadataBuilder.buildTabTitle.titleAll=Common Files (All Data Sources, %s)",
"CommonFilesMetadataBuilder.buildTabTitle.titleSingle=Common Files (Match Within Data Source: %s, %s)"
"CommonFilesMetadataBuilder.buildTabTitle.titleSingle=Common Files (Match Within Data Source: %s, %s)",
"CommonFilesMetadataBuilder.buildTabTitle.titleEamDb=Common Files (Central Repository Source(s), %s)",
})
protected abstract String buildTabTitle();

View File

@ -6,6 +6,10 @@
</Component>
<Component class="javax.swing.ButtonGroup" name="fileTypeFilterButtonGroup">
</Component>
<Component class="javax.swing.ButtonGroup" name="interIntraButtonGroup">
</Component>
<Component class="javax.swing.ButtonGroup" name="caseSelectionButtonGroup">
</Component>
</NonVisualComponents>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
@ -23,30 +27,17 @@
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="errorText" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="categoriesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="commonFilesSearchLabel" min="-2" max="-2" attributes="0"/>
<Component id="dataSourceLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="commonFilesSearchLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="categoriesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="6" pref="6" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
<Component id="selectDataSourceComboBox" min="-2" pref="261" max="-2" attributes="0"/>
</Group>
<Component id="withinDataSourceRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="allDataSourcesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="allFileCategoriesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="selectedFileCategoriesButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
@ -58,27 +49,75 @@
</Group>
</Group>
</Group>
</Group>
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="withinDataSourceRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="allDataSourcesRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="47" max="-2" attributes="0"/>
<Component id="selectDataSourceComboBox" min="-2" pref="261" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="interCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="anCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
<Component id="specificCentralRepoCaseRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Component id="caseComboBox" min="-2" pref="261" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</Group>
</Group>
<EmptySpace min="0" pref="13" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="errorText" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="commonFilesSearchLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Component id="dataSourceLabel" min="-2" max="-2" attributes="0"/>
<Component id="commonFilesSearchLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="intraCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="allDataSourcesRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="withinDataSourceRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="selectDataSourceComboBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="interCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="anCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="specificCentralRepoCaseRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="caseComboBox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="categoriesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="selectedFileCategoriesButton" min="-2" max="-2" attributes="0"/>
@ -94,6 +133,7 @@
<Component id="searchButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="errorText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -116,7 +156,6 @@
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="dataSourcesButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.allDataSourcesRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@ -154,14 +193,6 @@
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="commonFilesSearchLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.commonFilesSearchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -231,14 +262,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="documentsCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="dataSourceLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="categoriesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -257,5 +280,79 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="commonFilesSearchLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.commonFilesSearchLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="intraCaseRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="interIntraButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="label" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.intraCaseRadio.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="intraCaseRadioActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="interCaseRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="interIntraButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.jRadioButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="interCaseRadioActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="anCentralRepoCaseRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="caseSelectionButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.anCentralRepoCaseRadio.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="specificCentralRepoCaseRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="caseSelectionButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/commonfilesearch/Bundle.properties" key="CommonFilesPanel.specificCentralRepoCaseRadio.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="caseComboBox">
<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>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View File

@ -273,7 +273,10 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
builder = new SingleDataSource(dataSourceId, CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments);
setTitleForSingleSource(dataSourceId);
}
}// else if(false) {
// TODO, is CR cases, add option chosen CorrelationCase ID lookup
// builder = new AllDataSourcesEamDbCommonFilesAlgorithm(CommonFilesPanel.this.dataSourceMap, filterByMedia, filterByDocuments);
//}
this.tabTitle = builder.buildTabTitle();
@ -338,19 +341,25 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
dataSourcesButtonGroup = new javax.swing.ButtonGroup();
fileTypeFilterButtonGroup = new javax.swing.ButtonGroup();
interIntraButtonGroup = new javax.swing.ButtonGroup();
caseSelectionButtonGroup = new javax.swing.ButtonGroup();
searchButton = new javax.swing.JButton();
allDataSourcesRadioButton = new javax.swing.JRadioButton();
withinDataSourceRadioButton = new javax.swing.JRadioButton();
selectDataSourceComboBox = new javax.swing.JComboBox<>();
commonFilesSearchLabel = new javax.swing.JLabel();
cancelButton = new javax.swing.JButton();
allFileCategoriesRadioButton = new javax.swing.JRadioButton();
selectedFileCategoriesButton = new javax.swing.JRadioButton();
pictureVideoCheckbox = new javax.swing.JCheckBox();
documentsCheckbox = new javax.swing.JCheckBox();
dataSourceLabel = new javax.swing.JLabel();
categoriesLabel = new javax.swing.JLabel();
errorText = new javax.swing.JLabel();
commonFilesSearchLabel1 = new javax.swing.JLabel();
intraCaseRadio = new javax.swing.JRadioButton();
interCaseRadio = new javax.swing.JRadioButton();
anCentralRepoCaseRadio = new javax.swing.JRadioButton();
specificCentralRepoCaseRadio = new javax.swing.JRadioButton();
caseComboBox = new javax.swing.JComboBox<>();
org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.searchButton.text")); // NOI18N
searchButton.setEnabled(false);
@ -362,7 +371,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
});
dataSourcesButtonGroup.add(allDataSourcesRadioButton);
allDataSourcesRadioButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(allDataSourcesRadioButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.allDataSourcesRadioButton.text")); // NOI18N
allDataSourcesRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
allDataSourcesRadioButton.addActionListener(new java.awt.event.ActionListener() {
@ -388,9 +396,6 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}
});
org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel.text")); // NOI18N
commonFilesSearchLabel.setFocusable(false);
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.text")); // NOI18N
cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.cancelButton.actionCommand")); // NOI18N
cancelButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
@ -435,42 +440,62 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
}
});
org.openide.awt.Mnemonics.setLocalizedText(dataSourceLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.text")); // NOI18N
dataSourceLabel.setName(""); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(categoriesLabel, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.categoriesLabel.text")); // NOI18N
categoriesLabel.setName(""); // NOI18N
errorText.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(errorText, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.errorText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(commonFilesSearchLabel1, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.commonFilesSearchLabel1.text")); // NOI18N
commonFilesSearchLabel1.setFocusable(false);
interIntraButtonGroup.add(intraCaseRadio);
intraCaseRadio.setSelected(true);
intraCaseRadio.setLabel(org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.intraCaseRadio.label")); // NOI18N
intraCaseRadio.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
intraCaseRadioActionPerformed(evt);
}
});
interIntraButtonGroup.add(interCaseRadio);
org.openide.awt.Mnemonics.setLocalizedText(interCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.jRadioButton2.text")); // NOI18N
interCaseRadio.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
interCaseRadioActionPerformed(evt);
}
});
caseSelectionButtonGroup.add(anCentralRepoCaseRadio);
anCentralRepoCaseRadio.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(anCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.anCentralRepoCaseRadio.text_1")); // NOI18N
anCentralRepoCaseRadio.setEnabled(false);
caseSelectionButtonGroup.add(specificCentralRepoCaseRadio);
org.openide.awt.Mnemonics.setLocalizedText(specificCentralRepoCaseRadio, org.openide.util.NbBundle.getMessage(CommonFilesPanel.class, "CommonFilesPanel.specificCentralRepoCaseRadio.text_1")); // NOI18N
specificCentralRepoCaseRadio.setEnabled(false);
caseComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
caseComboBox.setEnabled(false);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(errorText)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(searchButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)
.addContainerGap())
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(categoriesLabel)
.addComponent(commonFilesSearchLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(dataSourceLabel)
.addGroup(layout.createSequentialGroup()
.addGap(6, 6, 6)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(29, 29, 29)
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(withinDataSourceRadioButton)
.addComponent(allDataSourcesRadioButton)
.addComponent(allFileCategoriesRadioButton)
.addComponent(selectedFileCategoriesButton)
.addGroup(layout.createSequentialGroup()
@ -478,22 +503,60 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pictureVideoCheckbox)
.addComponent(documentsCheckbox))))))
.addGap(19, 19, 19))))
.addGap(277, 277, 277))
.addComponent(intraCaseRadio)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(withinDataSourceRadioButton)
.addComponent(allDataSourcesRadioButton)))))
.addGroup(layout.createSequentialGroup()
.addGap(47, 47, 47)
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(interCaseRadio)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(anCentralRepoCaseRadio)
.addComponent(specificCentralRepoCaseRadio)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)))))))
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(errorText)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(searchButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(commonFilesSearchLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(commonFilesSearchLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(dataSourceLabel)
.addComponent(intraCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(allDataSourcesRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(withinDataSourceRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selectDataSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(interCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(anCentralRepoCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(specificCentralRepoCaseRadio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(caseComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(categoriesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(selectedFileCategoriesButton)
@ -507,7 +570,8 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cancelButton)
.addComponent(searchButton)
.addComponent(errorText)))
.addComponent(errorText))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
@ -555,6 +619,27 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
this.toggleErrorTextAndSearchBox();
}//GEN-LAST:event_documentsCheckboxActionPerformed
private void intraCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_intraCaseRadioActionPerformed
this.allDataSourcesRadioButton.setEnabled(true);
this.withinDataSourceRadioButton.setEnabled(true);
this.selectDataSourceComboBox.setEnabled(true);
this.anCentralRepoCaseRadio.setEnabled(false);
this.specificCentralRepoCaseRadio.setEnabled(false);
this.caseComboBox.setEnabled(false);
}//GEN-LAST:event_intraCaseRadioActionPerformed
private void interCaseRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interCaseRadioActionPerformed
this.anCentralRepoCaseRadio.setEnabled(true);
this.specificCentralRepoCaseRadio.setEnabled(true);
this.caseComboBox.setEnabled(true);
this.allDataSourcesRadioButton.setEnabled(false);
this.withinDataSourceRadioButton.setEnabled(false);
this.selectDataSourceComboBox.setEnabled(false);
}//GEN-LAST:event_interCaseRadioActionPerformed
private void toggleErrorTextAndSearchBox() {
if (!this.pictureVideoCheckbox.isSelected() && !this.documentsCheckbox.isSelected() && !this.allFileCategoriesRadioButton.isSelected()) {
this.searchButton.setEnabled(false);
@ -599,18 +684,24 @@ public final class CommonFilesPanel extends javax.swing.JPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton allDataSourcesRadioButton;
private javax.swing.JRadioButton allFileCategoriesRadioButton;
private javax.swing.JRadioButton anCentralRepoCaseRadio;
private javax.swing.JButton cancelButton;
private javax.swing.JComboBox<String> caseComboBox;
private javax.swing.ButtonGroup caseSelectionButtonGroup;
private javax.swing.JLabel categoriesLabel;
private javax.swing.JLabel commonFilesSearchLabel;
private javax.swing.JLabel dataSourceLabel;
private javax.swing.JLabel commonFilesSearchLabel1;
private javax.swing.ButtonGroup dataSourcesButtonGroup;
private javax.swing.JCheckBox documentsCheckbox;
private javax.swing.JLabel errorText;
private javax.swing.ButtonGroup fileTypeFilterButtonGroup;
private javax.swing.JRadioButton interCaseRadio;
private javax.swing.ButtonGroup interIntraButtonGroup;
private javax.swing.JRadioButton intraCaseRadio;
private javax.swing.JCheckBox pictureVideoCheckbox;
private javax.swing.JButton searchButton;
private javax.swing.JComboBox<String> selectDataSourceComboBox;
private javax.swing.JRadioButton selectedFileCategoriesButton;
private javax.swing.JRadioButton specificCentralRepoCaseRadio;
private javax.swing.JRadioButton withinDataSourceRadioButton;
// End of variables declaration//GEN-END:variables
}