mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
Merge pull request #6223 from gdicristofaro/6721-finishUserActivity
6721 finish user activity
This commit is contained in:
commit
86d0debe66
@ -0,0 +1,2 @@
|
|||||||
|
DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=Call Log
|
||||||
|
DataSourceUserActivitySummary_getRecentAccounts_emailMessage=Email Message
|
@ -22,6 +22,7 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -35,6 +36,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
|||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute.Type;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
import org.sleuthkit.datamodel.TskData.TSK_FS_META_FLAG_ENUM;
|
import org.sleuthkit.datamodel.TskData.TSK_FS_META_FLAG_ENUM;
|
||||||
@ -225,7 +227,7 @@ final class DataSourceInfoUtilities {
|
|||||||
private DataSourceInfoUtilities() {
|
private DataSourceInfoUtilities() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Map of lists of artifacts sorted by the given attribute.
|
* Create a Map of lists of artifacts sorted by the given attribute.
|
||||||
*
|
*
|
||||||
* @param skCase SleuthkitCase instance.
|
* @param skCase SleuthkitCase instance.
|
||||||
@ -357,4 +359,64 @@ final class DataSourceInfoUtilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves attribute from artifact if exists. Returns null if attribute is
|
||||||
|
* null or underlying call throws exception.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
* @param attributeType The attribute type to retrieve from the artifact.
|
||||||
|
*
|
||||||
|
* @return The attribute or null if could not be received.
|
||||||
|
*/
|
||||||
|
private static BlackboardAttribute getAttributeOrNull(BlackboardArtifact artifact, Type attributeType) {
|
||||||
|
try {
|
||||||
|
return artifact.getAttribute(attributeType);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the string value of a certain attribute type from an artifact.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
* @param attributeType The attribute type.
|
||||||
|
*
|
||||||
|
* @return The 'getValueString()' value or null if the attribute or String
|
||||||
|
* could not be retrieved.
|
||||||
|
*/
|
||||||
|
static String getStringOrNull(BlackboardArtifact artifact, Type attributeType) {
|
||||||
|
BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType);
|
||||||
|
return (attr == null) ? null : attr.getValueString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the long value of a certain attribute type from an artifact.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
* @param attributeType The attribute type.
|
||||||
|
*
|
||||||
|
* @return The 'getValueLong()' value or null if the attribute could not be
|
||||||
|
* retrieved.
|
||||||
|
*/
|
||||||
|
static Long getLongOrNull(BlackboardArtifact artifact, Type attributeType) {
|
||||||
|
BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType);
|
||||||
|
return (attr == null) ? null : attr.getValueLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the long value of a certain attribute type from an artifact and
|
||||||
|
* converts to date (seconds since epoch).
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
* @param attributeType The attribute type.
|
||||||
|
*
|
||||||
|
* @return The date determined from the 'getValueLong()' as seconds from
|
||||||
|
* epoch or null if the attribute could not be retrieved or is 0.
|
||||||
|
*/
|
||||||
|
static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType) {
|
||||||
|
Long longVal = getLongOrNull(artifact, attributeType);
|
||||||
|
return (longVal == null || longVal == 0) ? null : new Date(longVal * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2020 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.datasourcesummary.datamodel;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides summary information about top domains in a datasource. At this time,
|
|
||||||
* the data being provided is fictitious and is done as a placeholder.
|
|
||||||
*/
|
|
||||||
public class DataSourceTopDomainsSummary {
|
|
||||||
|
|
||||||
private static final long SLEEP_TIME = 5000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function to calculate a result from 2 parameters.
|
|
||||||
*/
|
|
||||||
interface Function2<A1, A2, O> {
|
|
||||||
|
|
||||||
O apply(A1 a1, A2 a2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of recent domains based on the datasource.
|
|
||||||
*
|
|
||||||
* @param dataSource The datasource to query for recent domains.
|
|
||||||
* @param count The max count of items to return.
|
|
||||||
*
|
|
||||||
* @return The list of items retrieved from the database.
|
|
||||||
*
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
|
||||||
public List<TopDomainsResult> getRecentDomains(DataSource dataSource, int count) throws InterruptedException {
|
|
||||||
Thread.sleep(SLEEP_TIME);
|
|
||||||
final String dId = Long.toString(dataSource.getId());
|
|
||||||
final Function2<String, Integer, String> getId = (s, idx) -> String.format("d:%s, f:%s, i:%d", dId, s, idx);
|
|
||||||
return IntStream.range(0, count)
|
|
||||||
.mapToObj(num -> new TopDomainsResult(
|
|
||||||
getId.apply("domain", num),
|
|
||||||
getId.apply("url", num),
|
|
||||||
(long) num,
|
|
||||||
new Date(((long) num) * 1000 * 60 * 60 * 24)
|
|
||||||
))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,533 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 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.datasourcesummary.datamodel;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.TranslationException;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides summary information about user activity in a datasource. At this
|
||||||
|
* time, the data being provided for domains is fictitious and is done as a
|
||||||
|
* placeholder.
|
||||||
|
*/
|
||||||
|
public class DataSourceUserActivitySummary {
|
||||||
|
|
||||||
|
private static final BlackboardArtifact.Type TYPE_DEVICE_ATTACHED = new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
|
||||||
|
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DATETIME = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DATETIME_ACCESSED = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DEVICE_ID = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_ID);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DEVICE_MAKE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DEVICE_MODEL = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_TEXT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_TEXT);
|
||||||
|
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DATETIME_RCVD = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_RCVD);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DATETIME_SENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_SENT);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DATETIME_START = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_START);
|
||||||
|
private static final BlackboardAttribute.Type TYPE_DATETIME_END = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_END);
|
||||||
|
|
||||||
|
private static final Comparator<TopAccountResult> TOP_ACCOUNT_RESULT_DATE_COMPARE = (a, b) -> a.getLastAccess().compareTo(b.getLastAccess());
|
||||||
|
private static final Comparator<TopWebSearchResult> TOP_WEBSEARCH_RESULT_DATE_COMPARE = (a, b) -> a.getDateAccessed().compareTo(b.getDateAccessed());
|
||||||
|
private static final String ROOT_HUB_IDENTIFIER = "ROOT_HUB";
|
||||||
|
|
||||||
|
private static final long SLEEP_TIME = 5000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to calculate a result from 2 parameters.
|
||||||
|
*/
|
||||||
|
interface Function2<A1, A2, O> {
|
||||||
|
|
||||||
|
O apply(A1 a1, A2 a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of recent domains based on the datasource.
|
||||||
|
*
|
||||||
|
* @param dataSource The datasource to query for recent domains.
|
||||||
|
* @param count The max count of items to return.
|
||||||
|
*
|
||||||
|
* @return The list of items retrieved from the database.
|
||||||
|
*
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
public List<TopDomainsResult> getRecentDomains(DataSource dataSource, int count) throws InterruptedException {
|
||||||
|
Thread.sleep(SLEEP_TIME);
|
||||||
|
final String dId = Long.toString(dataSource.getId());
|
||||||
|
final Function2<String, Integer, String> getId = (s, idx) -> String.format("d:%s, f:%s, i:%d", dId, s, idx);
|
||||||
|
return IntStream.range(0, count)
|
||||||
|
.mapToObj(num -> new TopDomainsResult(
|
||||||
|
getId.apply("domain", num),
|
||||||
|
getId.apply("url", num),
|
||||||
|
(long) num,
|
||||||
|
new Date(((long) num) * 1000 * 60 * 60 * 24)
|
||||||
|
))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SleuthkitCaseProvider caseProvider;
|
||||||
|
private final TextTranslationService translationService;
|
||||||
|
private final java.util.logging.Logger logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*/
|
||||||
|
public DataSourceUserActivitySummary() {
|
||||||
|
this(SleuthkitCaseProvider.DEFAULT, TextTranslationService.getInstance(),
|
||||||
|
org.sleuthkit.autopsy.coreutils.Logger.getLogger(DataSourceUserActivitySummary.class.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor with external dependencies specified. This constructor
|
||||||
|
* is designed with unit testing in mind since mocked dependencies can be
|
||||||
|
* utilized.
|
||||||
|
*
|
||||||
|
* @param provider The object providing the current SleuthkitCase.
|
||||||
|
* @param translationService The translation service.
|
||||||
|
* @param logger The logger to use.
|
||||||
|
*/
|
||||||
|
public DataSourceUserActivitySummary(
|
||||||
|
SleuthkitCaseProvider provider,
|
||||||
|
TextTranslationService translationService,
|
||||||
|
java.util.logging.Logger logger) {
|
||||||
|
|
||||||
|
this.caseProvider = provider;
|
||||||
|
this.translationService = translationService;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an IllegalArgumentException if count <= 0.
|
||||||
|
*
|
||||||
|
* @param count The count being checked.
|
||||||
|
*/
|
||||||
|
private void assertValidCount(int count) {
|
||||||
|
if (count <= 0) {
|
||||||
|
throw new IllegalArgumentException("Count must be greater than 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to obtain a web search result record from a blackboard artifact.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
*
|
||||||
|
* @return The TopWebSearchResult or null if the search string or date
|
||||||
|
* accessed cannot be determined.
|
||||||
|
*/
|
||||||
|
private static TopWebSearchResult getWebSearchResult(BlackboardArtifact artifact) {
|
||||||
|
String searchString = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT);
|
||||||
|
Date dateAccessed = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED);
|
||||||
|
return (StringUtils.isNotBlank(searchString) && dateAccessed != null)
|
||||||
|
? new TopWebSearchResult(searchString, dateAccessed)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves most recent web searches by most recent date grouped by search
|
||||||
|
* term.
|
||||||
|
*
|
||||||
|
* @param dataSource The data source.
|
||||||
|
* @param count The maximum number of records to be shown (must be >
|
||||||
|
* 0).
|
||||||
|
*
|
||||||
|
* @return The list of most recent web searches where most recent search
|
||||||
|
* appears first.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
public List<TopWebSearchResult> getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
assertValidCount(count);
|
||||||
|
|
||||||
|
// get the artifacts
|
||||||
|
List<BlackboardArtifact> webSearchArtifacts = caseProvider.get().getBlackboard()
|
||||||
|
.getArtifacts(ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId());
|
||||||
|
|
||||||
|
// group by search string (case insensitive)
|
||||||
|
Collection<List<TopWebSearchResult>> resultGroups = webSearchArtifacts
|
||||||
|
.stream()
|
||||||
|
// get items where search string and date is not null
|
||||||
|
.map(DataSourceUserActivitySummary::getWebSearchResult)
|
||||||
|
// remove null records
|
||||||
|
.filter(result -> result != null)
|
||||||
|
// get these messages grouped by search to string
|
||||||
|
.collect(Collectors.groupingBy((result) -> result.getSearchString().toUpperCase()))
|
||||||
|
.values();
|
||||||
|
|
||||||
|
// get the most recent date for each search term
|
||||||
|
List<TopWebSearchResult> results = resultGroups
|
||||||
|
.stream()
|
||||||
|
// get the most recent access per search type
|
||||||
|
.map((list) -> list.stream().max(TOP_WEBSEARCH_RESULT_DATE_COMPARE).get())
|
||||||
|
// get most recent searches first
|
||||||
|
.sorted(TOP_WEBSEARCH_RESULT_DATE_COMPARE.reversed())
|
||||||
|
.limit(count)
|
||||||
|
// get as list
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// get translation if possible
|
||||||
|
if (translationService.hasProvider()) {
|
||||||
|
for (TopWebSearchResult result : results) {
|
||||||
|
result.setTranslatedResult(getTranslationOrNull(result.getSearchString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the translation of the original text if possible and differs from
|
||||||
|
* the original. Otherwise, return null.
|
||||||
|
*
|
||||||
|
* @param original The original text.
|
||||||
|
*
|
||||||
|
* @return The translated text or null if no translation can be determined
|
||||||
|
* or exists.
|
||||||
|
*/
|
||||||
|
private String getTranslationOrNull(String original) {
|
||||||
|
if (!translationService.hasProvider() || StringUtils.isBlank(original)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String translated = null;
|
||||||
|
try {
|
||||||
|
translated = translationService.translate(original);
|
||||||
|
} catch (NoServiceProviderException | TranslationException ex) {
|
||||||
|
logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", original), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is no translation or the translation is the same as the original, return null.
|
||||||
|
if (StringUtils.isBlank(translated)
|
||||||
|
|| translated.toUpperCase().trim().equals(original.toUpperCase().trim())) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return translated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves most recent devices used by most recent date attached.
|
||||||
|
*
|
||||||
|
* @param dataSource The data source.
|
||||||
|
* @param count The maximum number of records to be shown (must be >
|
||||||
|
* 0).
|
||||||
|
*
|
||||||
|
* @return The list of most recent devices attached where most recent device
|
||||||
|
* attached appears first.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
public List<TopDeviceAttachedResult> getRecentDevices(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
assertValidCount(count);
|
||||||
|
|
||||||
|
return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED,
|
||||||
|
dataSource, TYPE_DATETIME, DataSourceInfoUtilities.SortOrder.DESCENDING, 0)
|
||||||
|
.stream()
|
||||||
|
.map(artifact -> {
|
||||||
|
return new TopDeviceAttachedResult(
|
||||||
|
DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_ID),
|
||||||
|
DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME),
|
||||||
|
DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MAKE),
|
||||||
|
DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MODEL)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
// remove Root Hub identifier
|
||||||
|
.filter(result -> {
|
||||||
|
return result.getDeviceModel() == null
|
||||||
|
|| !result.getDeviceModel().trim().toUpperCase().equals(ROOT_HUB_IDENTIFIER);
|
||||||
|
})
|
||||||
|
.limit(count)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a TopAccountResult from a TSK_MESSAGE blackboard artifact.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
*
|
||||||
|
* @return The TopAccountResult or null if the account type or message date
|
||||||
|
* cannot be determined.
|
||||||
|
*/
|
||||||
|
private static TopAccountResult getMessageAccountResult(BlackboardArtifact artifact) {
|
||||||
|
String type = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE);
|
||||||
|
Date date = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME);
|
||||||
|
return (StringUtils.isNotBlank(type) && date != null)
|
||||||
|
? new TopAccountResult(type, date)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a TopAccountResult from a blackboard artifact. The date is
|
||||||
|
* maximum of any found dates for attribute types provided.
|
||||||
|
*
|
||||||
|
* @param artifact The artifact.
|
||||||
|
* @param messageType The type of message this is.
|
||||||
|
* @param dateAttrs The date attribute types.
|
||||||
|
*
|
||||||
|
* @return The TopAccountResult or null if the account type or max date are
|
||||||
|
* not provided.
|
||||||
|
*/
|
||||||
|
private static TopAccountResult getAccountResult(BlackboardArtifact artifact, String messageType, BlackboardAttribute.Type... dateAttrs) {
|
||||||
|
String type = messageType;
|
||||||
|
|
||||||
|
Date latestDate = null;
|
||||||
|
if (dateAttrs != null) {
|
||||||
|
latestDate = Stream.of(dateAttrs)
|
||||||
|
.map((attr) -> DataSourceInfoUtilities.getDateOrNull(artifact, attr))
|
||||||
|
.filter((date) -> date != null)
|
||||||
|
.max((a, b) -> a.compareTo(b))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (StringUtils.isNotBlank(type) && latestDate != null)
|
||||||
|
? new TopAccountResult(type, latestDate)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves most recent account used by most recent date for a message
|
||||||
|
* sent.
|
||||||
|
*
|
||||||
|
* @param dataSource The data source.
|
||||||
|
* @param count The maximum number of records to be shown (must be >
|
||||||
|
* 0).
|
||||||
|
*
|
||||||
|
* @return The list of most recent accounts used where the most recent
|
||||||
|
* account by last message sent occurs first.
|
||||||
|
*
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"DataSourceUserActivitySummary_getRecentAccounts_emailMessage=Email Message",
|
||||||
|
"DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=Call Log",})
|
||||||
|
public List<TopAccountResult> getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException {
|
||||||
|
assertValidCount(count);
|
||||||
|
|
||||||
|
Stream<TopAccountResult> messageResults = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(), dataSource.getId())
|
||||||
|
.stream()
|
||||||
|
.map((art) -> getMessageAccountResult(art));
|
||||||
|
|
||||||
|
Stream<TopAccountResult> emailResults = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID(), dataSource.getId())
|
||||||
|
.stream()
|
||||||
|
.map((art) -> {
|
||||||
|
return getAccountResult(
|
||||||
|
art,
|
||||||
|
Bundle.DataSourceUserActivitySummary_getRecentAccounts_emailMessage(),
|
||||||
|
TYPE_DATETIME_RCVD,
|
||||||
|
TYPE_DATETIME_SENT);
|
||||||
|
});
|
||||||
|
|
||||||
|
Stream<TopAccountResult> calllogResults = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_CALLLOG.getTypeID(), dataSource.getId())
|
||||||
|
.stream()
|
||||||
|
.map((art) -> {
|
||||||
|
return getAccountResult(
|
||||||
|
art,
|
||||||
|
Bundle.DataSourceUserActivitySummary_getRecentAccounts_calllogMessage(),
|
||||||
|
TYPE_DATETIME_START,
|
||||||
|
TYPE_DATETIME_END);
|
||||||
|
});
|
||||||
|
|
||||||
|
Stream<TopAccountResult> allResults = Stream.concat(messageResults, Stream.concat(emailResults, calllogResults));
|
||||||
|
|
||||||
|
// get them grouped by account type
|
||||||
|
Collection<List<TopAccountResult>> groupedResults = allResults
|
||||||
|
// remove null records
|
||||||
|
.filter(result -> result != null)
|
||||||
|
// get these messages grouped by account type
|
||||||
|
.collect(Collectors.groupingBy(TopAccountResult::getAccountType))
|
||||||
|
.values();
|
||||||
|
|
||||||
|
// get account type sorted by most recent date
|
||||||
|
return groupedResults
|
||||||
|
.stream()
|
||||||
|
// get the most recent access per account type
|
||||||
|
.map((accountGroup) -> accountGroup.stream().max(TOP_ACCOUNT_RESULT_DATE_COMPARE).get())
|
||||||
|
// get most recent accounts accessed
|
||||||
|
.sorted(TOP_ACCOUNT_RESULT_DATE_COMPARE.reversed())
|
||||||
|
// limit to count
|
||||||
|
.limit(count)
|
||||||
|
// get as list
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object containing information about a web search artifact.
|
||||||
|
*/
|
||||||
|
public static class TopWebSearchResult {
|
||||||
|
|
||||||
|
private final String searchString;
|
||||||
|
private final Date dateAccessed;
|
||||||
|
private String translatedResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param searchString The search string.
|
||||||
|
* @param dateAccessed The latest date searched.
|
||||||
|
*/
|
||||||
|
public TopWebSearchResult(String searchString, Date dateAccessed) {
|
||||||
|
this.searchString = searchString;
|
||||||
|
this.dateAccessed = dateAccessed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The translated result if one was determined.
|
||||||
|
*/
|
||||||
|
public String getTranslatedResult() {
|
||||||
|
return translatedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the translated result for this web search.
|
||||||
|
*
|
||||||
|
* @param translatedResult The translated result.
|
||||||
|
*/
|
||||||
|
public void setTranslatedResult(String translatedResult) {
|
||||||
|
this.translatedResult = translatedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The search string.
|
||||||
|
*/
|
||||||
|
public String getSearchString() {
|
||||||
|
return searchString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The date for the search.
|
||||||
|
*/
|
||||||
|
public Date getDateAccessed() {
|
||||||
|
return dateAccessed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A record of a device attached.
|
||||||
|
*/
|
||||||
|
public static class TopDeviceAttachedResult {
|
||||||
|
|
||||||
|
private final String deviceId;
|
||||||
|
private final Date dateAccessed;
|
||||||
|
private final String deviceMake;
|
||||||
|
private final String deviceModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param deviceId The device id.
|
||||||
|
* @param dateAccessed The date last attached.
|
||||||
|
* @param deviceMake The device make.
|
||||||
|
* @param deviceModel The device model.
|
||||||
|
*/
|
||||||
|
public TopDeviceAttachedResult(String deviceId, Date dateAccessed, String deviceMake, String deviceModel) {
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
this.dateAccessed = dateAccessed;
|
||||||
|
this.deviceMake = deviceMake;
|
||||||
|
this.deviceModel = deviceModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The device id.
|
||||||
|
*/
|
||||||
|
public String getDeviceId() {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The date last attached.
|
||||||
|
*/
|
||||||
|
public Date getDateAccessed() {
|
||||||
|
return dateAccessed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The device make.
|
||||||
|
*/
|
||||||
|
public String getDeviceMake() {
|
||||||
|
return deviceMake;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The device model.
|
||||||
|
*/
|
||||||
|
public String getDeviceModel() {
|
||||||
|
return deviceModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A record of an account and the last time it was used determined by
|
||||||
|
* messages.
|
||||||
|
*/
|
||||||
|
public static class TopAccountResult {
|
||||||
|
|
||||||
|
private final String accountType;
|
||||||
|
private final Date lastAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param accountType The account type.
|
||||||
|
* @param lastAccess The date the account was last accessed.
|
||||||
|
*/
|
||||||
|
public TopAccountResult(String accountType, Date lastAccess) {
|
||||||
|
this.accountType = accountType;
|
||||||
|
this.lastAccess = lastAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The account type.
|
||||||
|
*/
|
||||||
|
public String getAccountType() {
|
||||||
|
return accountType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The date the account was last accessed.
|
||||||
|
*/
|
||||||
|
public Date getLastAccess() {
|
||||||
|
return lastAccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,12 +40,9 @@ abstract class BaseDataSourceSummaryPanel extends JPanel {
|
|||||||
* @param dataSource The datasource to use in this panel.
|
* @param dataSource The datasource to use in this panel.
|
||||||
*/
|
*/
|
||||||
synchronized void setDataSource(DataSource dataSource) {
|
synchronized void setDataSource(DataSource dataSource) {
|
||||||
DataSource oldDataSource = this.dataSource;
|
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
if (this.dataSource != oldDataSource) {
|
this.executor.cancelRunning();
|
||||||
this.executor.cancelRunning();
|
onNewDataSource(this.dataSource);
|
||||||
onNewDataSource(this.dataSource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,4 +31,7 @@ DataSourceSummaryDetailsPanel.unallocatedSizeValue.text=
|
|||||||
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category
|
||||||
DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type
|
DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type
|
||||||
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs
|
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs
|
||||||
|
DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts
|
||||||
|
DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches
|
||||||
|
DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached
|
||||||
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
||||||
|
@ -69,9 +69,17 @@ DataSourceSummaryTabbedPane_detailsTab_title=Container
|
|||||||
DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History
|
DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History
|
||||||
DataSourceSummaryTabbedPane_userActivityTab_title=User Activity
|
DataSourceSummaryTabbedPane_userActivityTab_title=User Activity
|
||||||
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs
|
DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs
|
||||||
|
DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts
|
||||||
|
DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches
|
||||||
|
DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached
|
||||||
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains
|
||||||
DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists
|
DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists
|
||||||
DataSourceSummaryUserActivityPanel_tab_title=User Activity
|
DataSourceSummaryUserActivityPanel_tab_title=User Activity
|
||||||
|
DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type
|
||||||
|
DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed
|
||||||
|
DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed
|
||||||
|
DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id
|
||||||
|
DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model
|
||||||
DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain
|
DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain
|
||||||
DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access
|
DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access
|
||||||
DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL
|
DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL
|
||||||
@ -79,4 +87,7 @@ DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times
|
|||||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder
|
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder
|
||||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run
|
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run
|
||||||
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program
|
DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program
|
||||||
|
DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed
|
||||||
|
DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String
|
||||||
|
DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated
|
||||||
ViewSummaryInformationAction.name.text=View Summary Information
|
ViewSummaryInformationAction.name.text=View Summary Information
|
||||||
|
@ -45,7 +45,8 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane {
|
|||||||
// A pair of the tab name and the corresponding BaseDataSourceSummaryTabs to be displayed.
|
// A pair of the tab name and the corresponding BaseDataSourceSummaryTabs to be displayed.
|
||||||
private final List<Pair<String, BaseDataSourceSummaryPanel>> tabs = new ArrayList<>(Arrays.asList(
|
private final List<Pair<String, BaseDataSourceSummaryPanel>> tabs = new ArrayList<>(Arrays.asList(
|
||||||
Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()),
|
Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()),
|
||||||
Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryUserActivityPanel())));
|
Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel())
|
||||||
|
));
|
||||||
|
|
||||||
private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();
|
private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
<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,-58,0,0,2,-42"/>
|
<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,3,-35,0,0,2,-42"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
@ -45,10 +45,10 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[720, 450]"/>
|
<Dimension value="[32767, 450]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[720, 450]"/>
|
<Dimension value="[10, 450]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -97,13 +97,13 @@
|
|||||||
<Properties>
|
<Properties>
|
||||||
<Property name="alignmentX" type="float" value="0.0"/>
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[700, 187]"/>
|
<Dimension value="[32767, 106]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[700, 187]"/>
|
<Dimension value="[10, 106]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[700, 187]"/>
|
<Dimension value="[10, 106]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -166,13 +166,13 @@
|
|||||||
<Properties>
|
<Properties>
|
||||||
<Property name="alignmentX" type="float" value="0.0"/>
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[700, 187]"/>
|
<Dimension value="[32767, 106]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[700, 187]"/>
|
<Dimension value="[10, 106]"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
<Dimension value="[700, 187]"/>
|
<Dimension value="[10, 106]"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -181,6 +181,213 @@
|
|||||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler4">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="topWebSearchLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryUserActivityPanel.topWebSearchLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler5">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="topWebSearches">
|
||||||
|
<Properties>
|
||||||
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="topWebSearchesTable"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler6">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="topDevicesAttachedLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler7">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="recentDevicesAttached">
|
||||||
|
<Properties>
|
||||||
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="topDevicesAttachedTable"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler8">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 20]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="recentAccountsLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties" key="DataSourceSummaryUserActivityPanel.recentAccountsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler9">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 2]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Container class="javax.swing.JPanel" name="topAccounts">
|
||||||
|
<Properties>
|
||||||
|
<Property name="alignmentX" type="float" value="0.0"/>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[32767, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[10, 106]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="topAccountsTable"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
|
@ -22,17 +22,21 @@ import java.awt.Component;
|
|||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopDomainsSummary;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopAccountResult;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopDeviceAttachedResult;
|
||||||
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopWebSearchResult;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult;
|
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.HorizontalAlign;
|
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;
|
||||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
||||||
@ -52,107 +56,232 @@ import org.sleuthkit.datamodel.DataSource;
|
|||||||
"DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain",
|
"DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain",
|
||||||
"DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL",
|
"DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL",
|
||||||
"DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access",
|
"DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access",
|
||||||
"DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists",})
|
"DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type",
|
||||||
|
"DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",})
|
||||||
public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPanel {
|
public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPanel {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault());
|
private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault());
|
||||||
private static final int TOP_PROGS_COUNT = 10;
|
private static final int TOP_PROGS_COUNT = 10;
|
||||||
private static final int TOP_DOMAINS_COUNT = 10;
|
private static final int TOP_DOMAINS_COUNT = 10;
|
||||||
|
private static final int TOP_SEARCHES_COUNT = 10;
|
||||||
private final JTablePanel<TopProgramsResult> topProgramsTable;
|
private static final int TOP_ACCOUNTS_COUNT = 5;
|
||||||
private final JTablePanel<TopDomainsResult> recentDomainsTable;
|
private static final int TOP_DEVICES_COUNT = 10;
|
||||||
private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
|
|
||||||
private final List<JTablePanel<?>> tables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new DataSourceUserActivityPanel.
|
* Gets a string formatted date or returns empty string if the date is null.
|
||||||
|
*
|
||||||
|
* @param date The date.
|
||||||
|
*
|
||||||
|
* @return The formatted date string or empty string if the date is null.
|
||||||
|
*/
|
||||||
|
private static String getFormatted(Date date) {
|
||||||
|
return date == null ? "" : DATETIME_FORMAT.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up recent programs table
|
||||||
|
private final JTablePanel<TopProgramsResult> topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList(
|
||||||
|
// program name column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(),
|
||||||
|
(prog) -> {
|
||||||
|
return new DefaultCellModel(prog.getProgramName())
|
||||||
|
.setTooltip(prog.getProgramPath());
|
||||||
|
},
|
||||||
|
250),
|
||||||
|
// program folder column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header(),
|
||||||
|
(prog) -> {
|
||||||
|
return new DefaultCellModel(
|
||||||
|
getShortFolderName(
|
||||||
|
prog.getProgramPath(),
|
||||||
|
prog.getProgramName()));
|
||||||
|
},
|
||||||
|
150),
|
||||||
|
// run count column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(),
|
||||||
|
(prog) -> {
|
||||||
|
String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes());
|
||||||
|
return new DefaultCellModel(runTimes);
|
||||||
|
},
|
||||||
|
80),
|
||||||
|
// last run date column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header(),
|
||||||
|
(prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())),
|
||||||
|
150)
|
||||||
|
));
|
||||||
|
|
||||||
|
// set up recent domains table
|
||||||
|
private final JTablePanel<TopDomainsResult> recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList(
|
||||||
|
// domain column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(),
|
||||||
|
(recentDomain) -> new DefaultCellModel(recentDomain.getDomain()),
|
||||||
|
250),
|
||||||
|
// url column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header(),
|
||||||
|
(recentDomain) -> new DefaultCellModel(recentDomain.getUrl()),
|
||||||
|
250),
|
||||||
|
// last accessed column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(),
|
||||||
|
(recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())),
|
||||||
|
150)
|
||||||
|
));
|
||||||
|
|
||||||
|
// top web searches table
|
||||||
|
private final JTablePanel<TopWebSearchResult> topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList(
|
||||||
|
// search string column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header(),
|
||||||
|
(webSearch) -> new DefaultCellModel(webSearch.getSearchString()),
|
||||||
|
250
|
||||||
|
),
|
||||||
|
// last accessed
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(),
|
||||||
|
(webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())),
|
||||||
|
150
|
||||||
|
),
|
||||||
|
// translated value
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header(),
|
||||||
|
(webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()),
|
||||||
|
250
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
// top devices attached table
|
||||||
|
private final JTablePanel<TopDeviceAttachedResult> topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList(
|
||||||
|
// device id column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(),
|
||||||
|
(device) -> new DefaultCellModel(device.getDeviceId()),
|
||||||
|
250
|
||||||
|
),
|
||||||
|
// last accessed
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(),
|
||||||
|
(device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())),
|
||||||
|
150
|
||||||
|
),
|
||||||
|
// make and model
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(),
|
||||||
|
(device) -> {
|
||||||
|
String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim();
|
||||||
|
String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim();
|
||||||
|
String makeModelString = (make.isEmpty() || model.isEmpty())
|
||||||
|
? make + model
|
||||||
|
: String.format("%s - %s", make, model);
|
||||||
|
return new DefaultCellModel(makeModelString);
|
||||||
|
},
|
||||||
|
250
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
// top accounts table
|
||||||
|
private final JTablePanel<TopAccountResult> topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList(
|
||||||
|
// account type column
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header(),
|
||||||
|
(account) -> new DefaultCellModel(account.getAccountType()),
|
||||||
|
250
|
||||||
|
),
|
||||||
|
// last accessed
|
||||||
|
new ColumnModel<>(
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header(),
|
||||||
|
(account) -> new DefaultCellModel(getFormatted(account.getLastAccess())),
|
||||||
|
150
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
private final List<JTablePanel<?>> tables = Arrays.asList(
|
||||||
|
topProgramsTable,
|
||||||
|
recentDomainsTable,
|
||||||
|
topWebSearchesTable,
|
||||||
|
topDevicesAttachedTable,
|
||||||
|
topAccountsTable
|
||||||
|
);
|
||||||
|
|
||||||
|
private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
|
||||||
|
private final DataSourceTopProgramsSummary topProgramsData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new DataSourceSummaryUserActivityPanel.
|
||||||
*/
|
*/
|
||||||
public DataSourceSummaryUserActivityPanel() {
|
public DataSourceSummaryUserActivityPanel() {
|
||||||
this(new DataSourceTopProgramsSummary(), new DataSourceTopDomainsSummary());
|
this(new DataSourceTopProgramsSummary(), new DataSourceUserActivitySummary());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new DataSourceSummaryUserActivityPanel.
|
* Creates a new DataSourceSummaryUserActivityPanel.
|
||||||
*
|
*
|
||||||
* @param topProgramsData Class from which to obtain top programs data.
|
* @param topProgramsData Class from which to obtain top programs data.
|
||||||
* @param topDomainsData Class from which to obtain recent domains data.
|
* @param userActivityData Class from which to obtain remaining user
|
||||||
|
* activity data.
|
||||||
*/
|
*/
|
||||||
public DataSourceSummaryUserActivityPanel(DataSourceTopProgramsSummary topProgramsData, DataSourceTopDomainsSummary topDomainsData) {
|
public DataSourceSummaryUserActivityPanel(
|
||||||
// set up recent programs table
|
DataSourceTopProgramsSummary topProgramsData,
|
||||||
this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList(new ColumnModel<>(
|
DataSourceUserActivitySummary userActivityData) {
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(),
|
|
||||||
(prog) -> {
|
|
||||||
return new DefaultCellModel(prog.getProgramName())
|
|
||||||
.setTooltip(prog.getProgramPath());
|
|
||||||
},
|
|
||||||
250),
|
|
||||||
new ColumnModel<>(
|
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header(),
|
|
||||||
(prog) -> {
|
|
||||||
return new DefaultCellModel(
|
|
||||||
topProgramsData.getShortFolderName(
|
|
||||||
prog.getProgramPath(),
|
|
||||||
prog.getProgramName()));
|
|
||||||
},
|
|
||||||
150),
|
|
||||||
new ColumnModel<>(
|
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(),
|
|
||||||
(prog) -> {
|
|
||||||
String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes());
|
|
||||||
return new DefaultCellModel(runTimes)
|
|
||||||
.setHorizontalAlignment(HorizontalAlign.RIGHT);
|
|
||||||
},
|
|
||||||
80),
|
|
||||||
new ColumnModel<>(
|
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header(),
|
|
||||||
(prog) -> {
|
|
||||||
String date = prog.getLastRun() == null ? "" : DATETIME_FORMAT.format(prog.getLastRun());
|
|
||||||
return new DefaultCellModel(date)
|
|
||||||
.setHorizontalAlignment(HorizontalAlign.RIGHT);
|
|
||||||
},
|
|
||||||
150)
|
|
||||||
));
|
|
||||||
|
|
||||||
// set up recent domains table
|
this.topProgramsData = topProgramsData;
|
||||||
this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList(new ColumnModel<>(
|
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(),
|
|
||||||
(d) -> new DefaultCellModel(d.getDomain()),
|
|
||||||
250),
|
|
||||||
new ColumnModel<>(
|
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header(),
|
|
||||||
(d) -> new DefaultCellModel(d.getUrl()),
|
|
||||||
250),
|
|
||||||
new ColumnModel<>(
|
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(),
|
|
||||||
(prog) -> {
|
|
||||||
String lastVisit = prog.getLastVisit() == null ? "" : DATETIME_FORMAT.format(prog.getLastVisit());
|
|
||||||
return new DefaultCellModel(lastVisit)
|
|
||||||
.setHorizontalAlignment(HorizontalAlign.RIGHT);
|
|
||||||
},
|
|
||||||
150)
|
|
||||||
));
|
|
||||||
|
|
||||||
this.tables = Arrays.asList(
|
|
||||||
topProgramsTable,
|
|
||||||
recentDomainsTable
|
|
||||||
);
|
|
||||||
|
|
||||||
// set up data acquisition methods
|
// set up data acquisition methods
|
||||||
dataFetchComponents = Arrays.asList(
|
this.dataFetchComponents = Arrays.asList(
|
||||||
new DataFetchComponents<DataSource, List<TopProgramsResult>>(
|
// top programs query
|
||||||
|
new DataFetchComponents<>(
|
||||||
(dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT),
|
(dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT),
|
||||||
(result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
(result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_noDataExists())),
|
Bundle.DataSourceSummaryUserActivityPanel_noDataExists())),
|
||||||
new DataFetchComponents<DataSource, List<TopDomainsResult>>(
|
// top domains query
|
||||||
(dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT),
|
new DataFetchComponents<>(
|
||||||
|
(dataSource) -> userActivityData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT),
|
||||||
(result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
(result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_noDataExists())),
|
||||||
|
// top web searches query
|
||||||
|
new DataFetchComponents<>(
|
||||||
|
(dataSource) -> userActivityData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT),
|
||||||
|
(result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_noDataExists())),
|
||||||
|
// top devices query
|
||||||
|
new DataFetchComponents<>(
|
||||||
|
(dataSource) -> userActivityData.getRecentDevices(dataSource, TOP_DEVICES_COUNT),
|
||||||
|
(result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
||||||
|
Bundle.DataSourceSummaryUserActivityPanel_noDataExists())),
|
||||||
|
// top accounts query
|
||||||
|
new DataFetchComponents<>(
|
||||||
|
(dataSource) -> userActivityData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT),
|
||||||
|
(result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(),
|
||||||
Bundle.DataSourceSummaryUserActivityPanel_noDataExists()))
|
Bundle.DataSourceSummaryUserActivityPanel_noDataExists()))
|
||||||
);
|
);
|
||||||
|
|
||||||
initComponents();
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries DataSourceTopProgramsSummary instance for short folder name.
|
||||||
|
*
|
||||||
|
* @param path The path for the application.
|
||||||
|
* @param appName The application name.
|
||||||
|
*
|
||||||
|
* @return The underlying short folder name if one exists.
|
||||||
|
*/
|
||||||
|
private String getShortFolderName(String path, String appName) {
|
||||||
|
return this.topProgramsData.getShortFolderName(path, appName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNewDataSource(DataSource dataSource) {
|
protected void onNewDataSource(DataSource dataSource) {
|
||||||
// if no data source is present or the case is not open,
|
// if no data source is present or the case is not open,
|
||||||
@ -194,16 +323,27 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan
|
|||||||
javax.swing.JLabel recentDomainsLabel = new javax.swing.JLabel();
|
javax.swing.JLabel recentDomainsLabel = new javax.swing.JLabel();
|
||||||
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
|
javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
|
||||||
javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable;
|
javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable;
|
||||||
|
javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20));
|
||||||
|
javax.swing.JLabel topWebSearchLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
|
||||||
|
javax.swing.JPanel topWebSearches = topWebSearchesTable;
|
||||||
|
javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20));
|
||||||
|
javax.swing.JLabel topDevicesAttachedLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.Box.Filler filler7 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
|
||||||
|
javax.swing.JPanel recentDevicesAttached = topDevicesAttachedTable;
|
||||||
|
javax.swing.Box.Filler filler8 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20));
|
||||||
|
javax.swing.JLabel recentAccountsLabel = new javax.swing.JLabel();
|
||||||
|
javax.swing.Box.Filler filler9 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2));
|
||||||
|
javax.swing.JPanel topAccounts = topAccountsTable;
|
||||||
|
|
||||||
setMaximumSize(null);
|
|
||||||
setLayout(new java.awt.BorderLayout());
|
setLayout(new java.awt.BorderLayout());
|
||||||
|
|
||||||
contentScrollPane.setMaximumSize(null);
|
contentScrollPane.setMaximumSize(null);
|
||||||
contentScrollPane.setMinimumSize(null);
|
contentScrollPane.setMinimumSize(null);
|
||||||
|
|
||||||
contentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
contentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
contentPanel.setMaximumSize(new java.awt.Dimension(720, 450));
|
contentPanel.setMaximumSize(new java.awt.Dimension(32767, 450));
|
||||||
contentPanel.setMinimumSize(new java.awt.Dimension(720, 450));
|
contentPanel.setMinimumSize(new java.awt.Dimension(10, 450));
|
||||||
contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS));
|
contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS));
|
||||||
|
|
||||||
programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||||
@ -213,9 +353,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan
|
|||||||
contentPanel.add(filler1);
|
contentPanel.add(filler1);
|
||||||
|
|
||||||
topProgramsTablePanel.setAlignmentX(0.0F);
|
topProgramsTablePanel.setAlignmentX(0.0F);
|
||||||
topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(700, 187));
|
topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(700, 187));
|
topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(700, 187));
|
topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
contentPanel.add(topProgramsTablePanel);
|
contentPanel.add(topProgramsTablePanel);
|
||||||
contentPanel.add(filler3);
|
contentPanel.add(filler3);
|
||||||
|
|
||||||
@ -225,10 +365,46 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan
|
|||||||
contentPanel.add(filler2);
|
contentPanel.add(filler2);
|
||||||
|
|
||||||
recentDomainsTablePanel.setAlignmentX(0.0F);
|
recentDomainsTablePanel.setAlignmentX(0.0F);
|
||||||
recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(700, 187));
|
recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 187));
|
recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 187));
|
recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
contentPanel.add(recentDomainsTablePanel);
|
contentPanel.add(recentDomainsTablePanel);
|
||||||
|
contentPanel.add(filler4);
|
||||||
|
|
||||||
|
topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topWebSearchLabel.text")); // NOI18N
|
||||||
|
contentPanel.add(topWebSearchLabel);
|
||||||
|
contentPanel.add(filler5);
|
||||||
|
|
||||||
|
topWebSearches.setAlignmentX(0.0F);
|
||||||
|
topWebSearches.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
|
topWebSearches.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
|
topWebSearches.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
|
contentPanel.add(topWebSearches);
|
||||||
|
contentPanel.add(filler6);
|
||||||
|
|
||||||
|
topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N
|
||||||
|
contentPanel.add(topDevicesAttachedLabel);
|
||||||
|
contentPanel.add(filler7);
|
||||||
|
|
||||||
|
recentDevicesAttached.setAlignmentX(0.0F);
|
||||||
|
recentDevicesAttached.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
|
recentDevicesAttached.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
|
recentDevicesAttached.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
|
contentPanel.add(recentDevicesAttached);
|
||||||
|
contentPanel.add(filler8);
|
||||||
|
|
||||||
|
recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentAccountsLabel.text")); // NOI18N
|
||||||
|
contentPanel.add(recentAccountsLabel);
|
||||||
|
contentPanel.add(filler9);
|
||||||
|
|
||||||
|
topAccounts.setAlignmentX(0.0F);
|
||||||
|
topAccounts.setMaximumSize(new java.awt.Dimension(32767, 106));
|
||||||
|
topAccounts.setMinimumSize(new java.awt.Dimension(10, 106));
|
||||||
|
topAccounts.setPreferredSize(new java.awt.Dimension(10, 106));
|
||||||
|
contentPanel.add(topAccounts);
|
||||||
|
|
||||||
contentScrollPane.setViewportView(contentPanel);
|
contentScrollPane.setViewportView(contentPanel);
|
||||||
|
|
||||||
|
@ -19,8 +19,11 @@
|
|||||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@ -80,6 +83,11 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer {
|
|||||||
* @return The horizontal alignment for the text in the cell.
|
* @return The horizontal alignment for the text in the cell.
|
||||||
*/
|
*/
|
||||||
HorizontalAlign getHorizontalAlignment();
|
HorizontalAlign getHorizontalAlignment();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The insets for the cell text.
|
||||||
|
*/
|
||||||
|
Insets getInsets();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,6 +98,7 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer {
|
|||||||
private final String text;
|
private final String text;
|
||||||
private String tooltip;
|
private String tooltip;
|
||||||
private HorizontalAlign horizontalAlignment;
|
private HorizontalAlign horizontalAlignment;
|
||||||
|
private Insets insets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
@ -139,13 +148,31 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Insets getInsets() {
|
||||||
|
return insets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the insets for the text within the cell
|
||||||
|
*
|
||||||
|
* @param insets The insets.
|
||||||
|
*
|
||||||
|
* @return As a utility, returns this.
|
||||||
|
*/
|
||||||
|
public DefaultCellModel setInsets(Insets insets) {
|
||||||
|
this.insets = insets;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getText();
|
return getText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int DEFAULT_ALIGNMENT = JLabel.LEFT;
|
private static final int DEFAULT_ALIGNMENT = JLabel.LEFT;
|
||||||
|
private static final Border DEFAULT_BORDER = BorderFactory.createEmptyBorder(1, 5, 1, 5);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
public Component getTableCellRendererComponent(JTable table, Object value,
|
||||||
@ -186,6 +213,14 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer {
|
|||||||
defaultCell.setToolTipText(null);
|
defaultCell.setToolTipText(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sets the padding for cell text within the cell.
|
||||||
|
Insets insets = cellModel.getInsets();
|
||||||
|
if (insets != null) {
|
||||||
|
defaultCell.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right));
|
||||||
|
} else {
|
||||||
|
defaultCell.setBorder(DEFAULT_BORDER);
|
||||||
|
}
|
||||||
|
|
||||||
// sets the JLabel alignment (left, center, right) or default alignment
|
// sets the JLabel alignment (left, center, right) or default alignment
|
||||||
// if no alignment is specified
|
// if no alignment is specified
|
||||||
int alignment = (cellModel.getHorizontalAlignment() == null)
|
int alignment = (cellModel.getHorizontalAlignment() == null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user