19 package org.sleuthkit.autopsy.casemodule;
 
   21 import java.awt.event.ActionEvent;
 
   23 import java.io.IOException;
 
   24 import java.util.ArrayList;
 
   25 import java.util.Arrays;
 
   26 import java.util.Deque;
 
   27 import java.util.Iterator;
 
   28 import java.util.LinkedList;
 
   29 import java.util.List;
 
   30 import java.util.logging.Level;
 
   31 import javax.swing.JMenuItem;
 
   32 import org.apache.commons.lang.ArrayUtils;
 
   33 import org.openide.filesystems.FileUtil;
 
   34 import org.openide.util.HelpCtx;
 
   35 import org.openide.util.NbBundle;
 
   36 import org.openide.util.actions.CallableSystemAction;
 
   37 import org.openide.util.actions.Presenter;
 
   46 final class RecentCases 
extends CallableSystemAction implements Presenter.Menu {
 
   48     private static final long serialVersionUID = 1L;
 
   49     private static final int LENGTH = 6;
 
   50     private static final String NAME_PROP_KEY = 
"LBL_RecentCase_Name"; 
 
   51     private static final String PATH_PROP_KEY = 
"LBL_RecentCase_Path"; 
 
   52     private static final RecentCase BLANK_RECENTCASE = 
new RecentCase(
"", 
"");
 
   53     private final static RecentCases instance = 
new RecentCases();
 
   54     private final Deque<RecentCase> recentCases; 
 
   62     static public RecentCases getInstance() {
 
   63         instance.refreshRecentCases();
 
   70     private RecentCases() {
 
   72         for (
int i = 0; i < LENGTH; i++) {
 
   74                 if (ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i)) == null) {
 
   75                     ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i), 
"");
 
   77                 if (ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i)) == null) {
 
   78                     ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i), 
"");
 
   80             } 
catch (Exception e) {
 
   86         recentCases = 
new LinkedList<>();
 
   88         for (
int i = 0; i < LENGTH; i++) {
 
   89             final RecentCase rc = 
new RecentCase(getName(i), getPath(i));
 
   90             if (!rc.equals(BLANK_RECENTCASE)) {
 
   98     private static void validateCaseIndex(
int i) {
 
   99         if (i < 0 || i >= LENGTH) {
 
  100             throw new IllegalArgumentException(
 
  101                     NbBundle.getMessage(RecentCases.class, 
"RecentCases.exception.caseIdxOutOfRange.msg", i));
 
  105     private static String nameKey(
int i) {
 
  106         validateCaseIndex(i);
 
  107         return NAME_PROP_KEY + Integer.toString(i + 1);
 
  110     private static String pathKey(
int i) {
 
  111         validateCaseIndex(i);
 
  112         return PATH_PROP_KEY + Integer.toString(i + 1);
 
  115     private String getName(
int i) {
 
  117             return ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i));
 
  118         } 
catch (Exception e) {
 
  123     private String getPath(
int i) {
 
  125             return ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i));
 
  126         } 
catch (Exception e) {
 
  131     private void setName(
int i, String name) {
 
  132         ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i), name);
 
  135     private void setPath(
int i, String path) {
 
  136         ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i), path);
 
  139     private void setRecentCase(
int i, RecentCase rc) {
 
  167         static RecentCase createSafe(String name, String unsafePath) {
 
  177             return !(name.isEmpty() || path.isEmpty() || !
new File(path).exists());
 
  184             hash = 13 * hash + (this.name != null ? this.name.hashCode() : 0);
 
  185             hash = 13 * hash + (this.path != null ? this.path.hashCode() : 0);
 
  194             if (getClass() != obj.getClass()) {
 
  198             if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
 
  201             if ((this.path == null) ? (other.path != null) : !this.path.equals(other.path)) {
 
  212     private void refreshRecentCases() {
 
  213         List<RecentCase> toDelete = 
new ArrayList<>();
 
  214         for (RecentCase rc : recentCases) {
 
  219         for (RecentCase deleteMe : toDelete) {
 
  220             removeRecentCase(deleteMe.name, deleteMe.path);
 
  224     private void storeRecentCases() throws IOException {
 
  228         for (RecentCase rc : recentCases) {
 
  229             setRecentCase(i, rc);
 
  235             setRecentCase(i, BLANK_RECENTCASE);
 
  247     public JMenuItem getMenuPresenter() {
 
  248         return new UpdateRecentCases();
 
  257     public void actionPerformed(ActionEvent e) {
 
  258         UpdateRecentCases.setHasRecentCase(
false);
 
  265         } 
catch (IOException ex) {
 
  266             Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, 
"Error: Could not clear the properties file.", ex); 
 
  270     private void addRecentCase(RecentCase rc) {
 
  272         recentCases.remove(rc);
 
  275         if (recentCases.size() == LENGTH) {
 
  276             recentCases.remove();
 
  290     public void addRecentCase(String name, String unsafePath) {
 
  291         RecentCase rc = RecentCase.createSafe(name, unsafePath);
 
  295         this.getMenuPresenter().setVisible(
true); 
 
  299         } 
catch (IOException ex) {
 
  300             Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, 
"Error: Could not update the properties file.", ex); 
 
  314     public void updateRecentCase(String oldName, String oldPath, String newName, String newPath) 
throws Exception {
 
  315         RecentCase oldRc = RecentCase.createSafe(oldName, oldPath);
 
  316         RecentCase newRc = RecentCase.createSafe(newName, newPath);
 
  319         recentCases.removeAll(Arrays.asList(oldRc));
 
  321         addRecentCase(newRc);
 
  323         this.getMenuPresenter().setVisible(
true); 
 
  327         } 
catch (IOException ex) {
 
  328             Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, 
"Error: Could not update the properties file.", ex); 
 
  337     public int getTotalRecentCases() {
 
  338         return recentCases.size();
 
  348     public void removeRecentCase(String name, String path) {
 
  349         RecentCase rc = RecentCase.createSafe(name, path);
 
  352         recentCases.removeAll(Arrays.asList(rc));
 
  354         this.getMenuPresenter().setVisible(
true); 
 
  359         } 
catch (IOException ex) {
 
  360             Logger.getLogger(RecentCases.class.getName()).log(Level.WARNING, 
"Error: Could not update the properties file.", ex); 
 
  370     public String[] getRecentCaseNames() {
 
  371         String[] caseNames = 
new String[LENGTH];
 
  373         Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
 
  375         String currentCaseName = null;
 
  377             currentCaseName = Case.getCurrentCaseThrows().getDisplayName();
 
  378         } 
catch (NoCurrentCaseException ex) {
 
  382         while (mostRecentFirst.hasNext()) {
 
  383             String name = mostRecentFirst.next().name;
 
  384             if ((currentCaseName != null && !name.equals(currentCaseName)) || currentCaseName == null) {
 
  391         while (i < caseNames.length) {
 
  397         return (String[]) ArrayUtils.subarray(caseNames, 0, LENGTH - 1);
 
  406     public String[] getRecentCasePaths() {
 
  407         String[] casePaths = 
new String[LENGTH];
 
  408         String currentCasePath = null;
 
  410             currentCasePath = Case.getCurrentCaseThrows().getMetadata().getFilePath().toString();
 
  411         } 
catch (NoCurrentCaseException ex) {
 
  417         Iterator<RecentCase> mostRecentFirst = recentCases.descendingIterator();
 
  419         while (mostRecentFirst.hasNext()) {
 
  420             String path = mostRecentFirst.next().path;
 
  421             if ((currentCasePath != null && !path.equals(currentCasePath)) || currentCasePath == null) {
 
  428         while (i < casePaths.length) {
 
  434         return (String[]) ArrayUtils.subarray(casePaths, 0, LENGTH - 1);
 
  441     public void performAction() {
 
  450     public String getName() {
 
  452         return NbBundle.getMessage(RecentCases.class, 
"RecentCases.getName.text");
 
  461     public HelpCtx getHelpCtx() {
 
  462         return HelpCtx.DEFAULT_HELP;
 
boolean equals(Object obj)
RecentCase(String name, String path)