Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
KeywordHit.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2011-2018 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.autopsy.keywordsearch;
20
21import java.sql.ResultSet;
22import java.sql.SQLException;
23import java.util.Comparator;
24import java.util.Objects;
25import java.util.Optional;
26import org.apache.commons.lang3.StringUtils;
27import org.sleuthkit.autopsy.casemodule.Case;
28import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
29import org.sleuthkit.datamodel.BlackboardAttribute;
30import org.sleuthkit.datamodel.SleuthkitCase;
31import org.sleuthkit.datamodel.TskCoreException;
32
40class KeywordHit implements Comparable<KeywordHit> {
41
42 private static final String GET_CONTENT_ID_FROM_ARTIFACT_ID = "SELECT obj_id FROM blackboard_artifacts WHERE artifact_id = ";
43
44 private final long solrObjectId;
45 private final int chunkId;
46 private final String snippet;
47 private final String hit;
48
60 KeywordHit(String solrDocumentId, String snippet, String hit) {
61 this.snippet = StringUtils.stripToEmpty(snippet);
62 this.hit = hit;
63
64 /*
65 * Parse the Solr document id to get the Solr object id and chunk id.
66 * The Solr object id will either be the object id of a file id or an
67 * artifact id from the case database.
68 *
69 * For every object (file or artifact) there will at least two Solr
70 * documents. One contains object metadata (chunk #1) and the second and
71 * subsequent documents contain chunks of the text.
72 */
73 if(!solrDocumentId.isEmpty()) {
74 String[] split = solrDocumentId.split(Server.CHUNK_ID_SEPARATOR);
75 if (split.length == 1) {
76 //chunk 0 has only the bare document id without the chunk id.
77 this.solrObjectId = Long.parseLong(solrDocumentId);
78 this.chunkId = 0;
79 } else {
80 this.solrObjectId = Long.parseLong(split[0]);
81 this.chunkId = Integer.parseInt(split[1]);
82 }
83 } else {
84 this.solrObjectId = 0;
85 this.chunkId = 0;
86 }
87 }
88
89 KeywordHit(int chunkId, long sourceID, String snippet, String hit) {
90 this.snippet = StringUtils.stripToEmpty(snippet);
91 this.hit = hit;
92 this.chunkId = chunkId;
93 this.solrObjectId = sourceID;
94 }
95
96
97 String getHit() {
98 return hit;
99 }
100
101 String getSolrDocumentId() {
102 return Long.toString(solrObjectId) + Server.CHUNK_ID_SEPARATOR + Long.toString(chunkId);
103 }
104
105 Long getSolrObjectId() {
106 return this.solrObjectId;
107 }
108
109 Integer getChunkId() {
110 return this.chunkId;
111 }
112
113 boolean hasSnippet() {
114 return StringUtils.isNotBlank(this.snippet);
115 }
116
117 String getSnippet() {
118 return this.snippet;
119 }
120
132 long getContentID() throws TskCoreException {
133 if (isArtifactHit()) {
134 // If the hit was in an artifact, look up the source content for the artifact.
135 SleuthkitCase caseDb;
136 try {
137 caseDb = Case.getCurrentCaseThrows().getSleuthkitCase();
138 } catch (NoCurrentCaseException ex) {
139 throw new TskCoreException("Exception while getting open case.", ex);
140 }
141 try (SleuthkitCase.CaseDbQuery executeQuery =
142 caseDb.executeQuery(GET_CONTENT_ID_FROM_ARTIFACT_ID + this.solrObjectId);
143 ResultSet resultSet = executeQuery.getResultSet();) {
144 if (resultSet.next()) {
145 return resultSet.getLong("obj_id");
146 } else {
147 throw new TskCoreException("Failed to get obj_id for artifact with artifact_id =" + this.solrObjectId + ". No matching artifact was found.");
148 }
149 } catch (SQLException ex) {
150 throw new TskCoreException("Error getting obj_id for artifact with artifact_id =" + this.solrObjectId, ex);
151 }
152 } else {
153 //else the object id is for content.
154 return this.solrObjectId;
155 }
156 }
157
163 boolean isArtifactHit() {
164 // artifacts have negative obj ids
165 return this.solrObjectId < 0;
166 }
167
173 Optional<Long> getArtifactID() {
174 if (isArtifactHit()) {
175 return Optional.of(solrObjectId);
176 } else {
177 return Optional.empty();
178 }
179 }
180
181 @Override
182 public boolean equals(Object obj) {
183 if (null == obj) {
184 return false;
185 }
186 if (getClass() != obj.getClass()) {
187 return false;
188 }
189 final KeywordHit other = (KeywordHit) obj;
190 return compareTo(other) == 0;
191 }
192
193 @Override
194 public int hashCode() {
195 int hash = 7;
196 hash = 37 * hash + (int) (this.solrObjectId ^ (this.solrObjectId >>> 32));
197 hash = 37 * hash + this.chunkId;
198 hash = 37 * hash + Objects.hashCode(this.snippet);
199 hash = 37 * hash + Objects.hashCode(this.hit);
200 return hash;
201 }
202
203 @Override
204 public int compareTo(KeywordHit other) {
205 return Comparator.comparing(KeywordHit::getSolrObjectId)
206 .thenComparing(KeywordHit::getChunkId)
207 .thenComparing(KeywordHit::getHit)
208 .thenComparing(KeywordHit::getSnippet)
209 .compare(this, other);
210 }
211}

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.