19 package org.sleuthkit.autopsy.imagewriter;
21 import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.ScheduledFuture;
28 import java.util.concurrent.ScheduledThreadPoolExecutor;
29 import java.util.concurrent.TimeUnit;
30 import java.util.concurrent.ExecutionException;
31 import java.util.logging.Level;
32 import org.netbeans.api.progress.ProgressHandle;
33 import org.openide.util.NbBundle.Messages;
51 class ImageWriter
implements PropertyChangeListener{
55 private final Long dataSourceId;
58 private Long imageHandle = null;
59 private Future<Integer> finishTask = null;
60 private ProgressHandle progressHandle = null;
61 private ScheduledFuture<?> progressUpdateTask = null;
62 private boolean isCancelled =
false;
63 private boolean isStarted =
false;
64 private final Object currentTasksLock =
new Object();
67 private ScheduledThreadPoolExecutor periodicTasksExecutor = null;
68 private final boolean doUI;
69 private SleuthkitCase caseDb = null;
77 this.dataSourceId = dataSourceId;
78 this.settings = settings;
86 }
catch (IllegalStateException ex){
87 logger.log(Level.SEVERE,
"Unable to load case. Image writer will be cancelled.");
88 this.isCancelled =
true;
95 void subscribeToEvents(){
102 void unsubscribeFromEvents(){
111 public void propertyChange(PropertyChangeEvent evt) {
114 DataSourceAnalysisCompletedEvent
event = (DataSourceAnalysisCompletedEvent)evt;
116 if(event.getDataSource() != null){
117 long imageId =
event.getDataSource().getId();
118 String name =
event.getDataSource().getName();
121 if(imageId != dataSourceId){
125 startFinishImage(name);
129 logger.log(Level.SEVERE,
"DataSourceAnalysisCompletedEvent did not contain a dataSource object");
135 "# {0} - data source name",
136 "ImageWriter.progressBar.message=Finishing acquisition of {0}"
138 private void startFinishImage(String dataSourceName){
140 synchronized(currentTasksLock){
155 imageHandle = image.getImageHandle();
156 }
catch (IllegalStateException ex){
161 logger.log(Level.WARNING, String.format(
"Case closed before ImageWriter could start the finishing process for %s",
164 }
catch (TskCoreException ex){
165 logger.log(Level.SEVERE,
"Error loading image", ex);
169 logger.log(Level.INFO, String.format(
"Finishing VHD image for %s",
173 periodicTasksExecutor =
new ScheduledThreadPoolExecutor(1,
new ThreadFactoryBuilder().setNameFormat(
"image-writer-progress-update-%d").build());
174 progressHandle = ProgressHandle.createHandle(Bundle.ImageWriter_progressBar_message(dataSourceName));
175 progressHandle.start(100);
176 progressUpdateTask = periodicTasksExecutor.scheduleAtFixedRate(
177 new ProgressUpdateTask(progressHandle, imageHandle), 0, 250, TimeUnit.MILLISECONDS);
183 finishTask = Executors.newSingleThreadExecutor().submit(
new Callable<Integer>(){
185 public Integer call()
throws TskCoreException{
187 int result = SleuthkitJNI.finishImageWriter(imageHandle);
193 caseDb.updateImagePath(settings.
getPath(), dataSourceId);
196 }
catch (TskCoreException ex){
197 logger.log(Level.SEVERE,
"Error finishing VHD image", ex);
211 result = finishTask.get();
212 }
catch (InterruptedException | ExecutionException ex){
213 logger.log(Level.SEVERE,
"Error finishing VHD image", ex);
216 synchronized(currentTasksLock){
219 progressUpdateTask.cancel(
true);
220 progressHandle.finish();
221 periodicTasksExecutor.shutdown();
226 logger.log(Level.INFO, String.format(
"Successfully finished writing VHD image for %s", dataSourceName));
228 logger.log(Level.INFO, String.format(
"Finished VHD image for %s with errors", dataSourceName));
238 void cancelIfNotStarted(){
239 synchronized(currentTasksLock){
251 boolean jobIsInProgress(){
252 synchronized(currentTasksLock){
253 return((isStarted) && (! finishTask.isDone()));
262 synchronized(currentTasksLock){
267 SleuthkitJNI.cancelFinishImage(imageHandle);
276 progressUpdateTask.cancel(
true);
277 progressHandle.finish();
287 void waitForJobToFinish(){
288 synchronized(currentTasksLock){
293 }
catch (InterruptedException | ExecutionException ex){
294 Logger.
getLogger(ImageWriter.class.getName()).log(Level.SEVERE,
"Error finishing VHD image", ex);
297 progressUpdateTask.cancel(
true);
307 final long imageHandle;
308 final ProgressHandle progressHandle;
311 this.imageHandle = imageHandle;
312 this.progressHandle = progressHandle;
318 int progress = SleuthkitJNI.getFinishImageProgress(imageHandle);
319 progressHandle.progress(progress);
320 }
catch (Exception ex) {
321 logger.log(Level.SEVERE,
"Unexpected exception in ProgressUpdateTask", ex);
static synchronized IngestManager getInstance()
static boolean runningWithGUI
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
SleuthkitCase getSleuthkitCase()
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
boolean getUpdateDatabasePath()