diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 725c050563..81d207abae 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014-2017 Basis Technology Corp. + * Copyright 2014-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -67,7 +67,9 @@ public final class UserPreferences { private static final String APP_NAME = "AppName"; public static final String SETTINGS_PROPERTIES = "AutoIngest"; private static final String MODE = "AutopsyMode"; // NON-NLS - + private static final String MAX_NUM_OF_LOG_FILE = "MaximumNumberOfLogFiles"; + private static final int LOG_FILE_NUM_INT = 10; + // Prevent instantiation. private UserPreferences() { } @@ -369,4 +371,26 @@ public final class UserPreferences { preferences.put(APP_NAME, name); } + /** + * get the maximum number of log files to save + * @return Number of log files + */ + public static int getLogFileCount() { + return preferences.getInt(MAX_NUM_OF_LOG_FILE, LOG_FILE_NUM_INT); + } + + /** + * get the default number of log files to save + * @return LOG_FILE_COUNT + */ + public static int getDefaultLogFileCount() { + return LOG_FILE_NUM_INT; + } + /** + * Set the maximum number of log files to save + * @param count number of log files + */ + public static void setLogFileCount(int count) { + preferences.putInt(MAX_NUM_OF_LOG_FILE, count); + } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index c1fc384c5e..36b88c10ca 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -24,7 +24,7 @@ - + @@ -44,18 +44,26 @@ + + + + + - + - + - - + + + + + - + @@ -63,10 +71,11 @@ - - - - + + + + + @@ -245,7 +254,7 @@ - + @@ -436,28 +445,43 @@ - - - - - - - - - - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + @@ -466,22 +490,29 @@ + - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -545,6 +576,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index 17aad44582..f4e2a38671 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -73,7 +73,9 @@ import org.sleuthkit.autopsy.report.ReportBranding; "AutopsyOptionsPanel.browseLogosButton.text=Browse", "AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.invalidPath.text=Path is not valid.", "AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.invalidImageSpecified.text=Invalid image file specified.", - "AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.pathNotSet.text=Agency logo path must be set." + "AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.pathNotSet.text=Agency logo path must be set.", + "AutopsyOptionsPanel.maxLogFileCount.text=Maximum Log Files:", + "AutopsyOptionsPanel.logNumAlert.invalidInput.text=A positive integer is required here." }) final class AutopsyOptionsPanel extends javax.swing.JPanel { @@ -110,6 +112,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { textFieldListener = new TextFieldListener(); agencyLogoPathField.getDocument().addDocumentListener(textFieldListener); + logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount())); } /** @@ -309,6 +312,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { specifyLogoRB.setSelected(!useDefault); agencyLogoPathField.setEnabled(!useDefault); browseLogosButton.setEnabled(!useDefault); + logFileCount.setText(String.valueOf(UserPreferences.getLogFileCount())); try { updateAgencyLogo(path); } catch (IOException ex) { @@ -363,6 +367,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { UserPreferences.setHideSlackFilesInDataSourcesTree(dataSourcesHideSlackCB.isSelected()); UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCB.isSelected()); UserPreferences.setDisplayTimesInLocalTime(useLocalTimeRB.isSelected()); + UserPreferences.setLogFileCount(Integer.parseInt(logFileCount.getText())); if (!agencyLogoPathField.getText().isEmpty()) { File file = new File(agencyLogoPathField.getText()); if (file.exists()) { @@ -394,6 +399,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { if (!isMemFieldValid()) { valid = false; } + if (!isLogNumFieldValid()) { + valid = false; + } return valid; } @@ -476,6 +484,26 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { return true; } + /** + * Check if the logFileCount field is valid. + * + * @return true if the logFileCount is valid false if it is not + */ + private boolean isLogNumFieldValid() { + String count = logFileCount.getText(); + logNumAlert.setText(""); + try { + int count_num = Integer.parseInt(count); + if (count_num < 1) { + logNumAlert.setText(Bundle.AutopsyOptionsPanel_logNumAlert_invalidInput_text()); + return false; + } + } catch (NumberFormatException e) { + logNumAlert.setText(Bundle.AutopsyOptionsPanel_logNumAlert_invalidInput_text()); + return false; + } + return true; + } /** * Listens for registered text fields that have changed and fires a * PropertyChangeEvent accordingly. @@ -540,9 +568,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { memField = new javax.swing.JTextField(); memFieldValidationLabel = new javax.swing.JLabel(); maxMemoryUnitsLabel1 = new javax.swing.JLabel(); + maxLogFileCount = new javax.swing.JLabel(); + logFileCount = new javax.swing.JTextField(); + logNumAlert = new javax.swing.JTextField(); jScrollPane1.setBorder(null); + jPanel1.setPreferredSize(new java.awt.Dimension(671, 488)); + logoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.logoPanel.border.title"))); // NOI18N agencyLogoPathField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoPathField.text")); // NOI18N @@ -712,7 +745,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(dataSourcesHideSlackCB) .addComponent(viewsHideSlackCB) .addComponent(useLocalTimeRB)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(158, Short.MAX_VALUE)))) .addGroup(viewPanelLayout.createSequentialGroup() .addGroup(viewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabelHideSlackFiles) @@ -774,68 +807,103 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(maxMemoryUnitsLabel1, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxMemoryUnitsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(maxLogFileCount, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.maxLogFileCount.text")); // NOI18N + + logFileCount.setHorizontalAlignment(javax.swing.JTextField.TRAILING); + logFileCount.addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + logFileCountKeyReleased(evt); + } + }); + + logNumAlert.setEditable(false); + logNumAlert.setFont(logNumAlert.getFont().deriveFont(logNumAlert.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); + logNumAlert.setForeground(new java.awt.Color(255, 0, 0)); + logNumAlert.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.logNumAlert.text")); // NOI18N + logNumAlert.setBorder(null); + javax.swing.GroupLayout runtimePanelLayout = new javax.swing.GroupLayout(runtimePanel); runtimePanel.setLayout(runtimePanelLayout); runtimePanelLayout.setHorizontalGroup( runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(runtimePanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(maxMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(totalMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(memField, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE) - .addComponent(memFieldValidationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(totalMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(2, 2, 2) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(memFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 263, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)))) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(maxMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(runtimePanelLayout.createSequentialGroup() + .addComponent(maxLogFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(logFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(logNumAlert))) + .addContainerGap()) ); runtimePanelLayout.setVerticalGroup( runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(runtimePanelLayout.createSequentialGroup() .addContainerGap() .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(memFieldValidationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(maxMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(totalMemoryLabel) .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(restartNecessaryWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(maxMemoryUnitsLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(totalMemoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(systemMemoryTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(maxMemoryLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(memField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(maxMemoryUnitsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(memFieldValidationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(runtimePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(maxLogFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(logFileCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(logNumAlert, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(logoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(viewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(runtimePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(viewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(viewPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(viewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(runtimePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); @@ -846,7 +914,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1010, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -854,60 +922,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents - private void useBestViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_useBestViewerRBActionPerformed - - private void keepCurrentViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_keepCurrentViewerRBActionPerformed - - private void dataSourcesHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideKnownCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_dataSourcesHideKnownCBActionPerformed - - private void viewsHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideKnownCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_viewsHideKnownCBActionPerformed - - private void useLocalTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_useLocalTimeRBActionPerformed - - private void useGMTTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_useGMTTimeRBActionPerformed - - private void dataSourcesHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideSlackCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_dataSourcesHideSlackCBActionPerformed - - private void viewsHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideSlackCBActionPerformed - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_viewsHideSlackCBActionPerformed - - private void browseLogosButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLogosButtonActionPerformed - String oldLogoPath = agencyLogoPathField.getText(); - int returnState = fileChooser.showOpenDialog(this); - if (returnState == JFileChooser.APPROVE_OPTION) { - String path = fileChooser.getSelectedFile().getPath(); - try { - updateAgencyLogo(path); - firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - } catch (IOException | IndexOutOfBoundsException ex) { - JOptionPane.showMessageDialog(null, - NbBundle.getMessage(this.getClass(), - "AutopsyOptionsPanel.invalidImageFile.msg"), - NbBundle.getMessage(this.getClass(), "AutopsyOptionsPanel.invalidImageFile.title"), - JOptionPane.ERROR_MESSAGE); - try { - updateAgencyLogo(oldLogoPath); //restore previous setting if new one is invalid - } catch (IOException ex1) { - LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex1); - } - } + private void logFileCountKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_logFileCountKeyReleased + String count = logFileCount.getText(); + if (count.equals(String.valueOf(UserPreferences.getDefaultLogFileCount()))) { + //if it is still the default value don't fire change + return; } - }//GEN-LAST:event_browseLogosButtonActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_logFileCountKeyReleased private void memFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_memFieldKeyReleased String memText = memField.getText(); @@ -918,17 +940,37 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_memFieldKeyReleased - private void defaultLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultLogoRBActionPerformed - agencyLogoPathField.setEnabled(false); - browseLogosButton.setEnabled(false); - try { - updateAgencyLogo(""); - } catch (IOException ex) { - // This should never happen since we're not reading from a file. - LOGGER.log(Level.SEVERE, "Unexpected error occurred while updating the agency logo.", ex); - } + private void useGMTTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useGMTTimeRBActionPerformed firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - }//GEN-LAST:event_defaultLogoRBActionPerformed + }//GEN-LAST:event_useGMTTimeRBActionPerformed + + private void useLocalTimeRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useLocalTimeRBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_useLocalTimeRBActionPerformed + + private void viewsHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideSlackCBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_viewsHideSlackCBActionPerformed + + private void dataSourcesHideSlackCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideSlackCBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_dataSourcesHideSlackCBActionPerformed + + private void viewsHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewsHideKnownCBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_viewsHideKnownCBActionPerformed + + private void dataSourcesHideKnownCBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataSourcesHideKnownCBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_dataSourcesHideKnownCBActionPerformed + + private void keepCurrentViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_keepCurrentViewerRBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_keepCurrentViewerRBActionPerformed + + private void useBestViewerRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useBestViewerRBActionPerformed + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_useBestViewerRBActionPerformed private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed agencyLogoPathField.setEnabled(true); @@ -946,6 +988,41 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_specifyLogoRBActionPerformed + private void defaultLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultLogoRBActionPerformed + agencyLogoPathField.setEnabled(false); + browseLogosButton.setEnabled(false); + try { + updateAgencyLogo(""); + } catch (IOException ex) { + // This should never happen since we're not reading from a file. + LOGGER.log(Level.SEVERE, "Unexpected error occurred while updating the agency logo.", ex); + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_defaultLogoRBActionPerformed + + private void browseLogosButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseLogosButtonActionPerformed + String oldLogoPath = agencyLogoPathField.getText(); + int returnState = fileChooser.showOpenDialog(this); + if (returnState == JFileChooser.APPROVE_OPTION) { + String path = fileChooser.getSelectedFile().getPath(); + try { + updateAgencyLogo(path); + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + } catch (IOException | IndexOutOfBoundsException ex) { + JOptionPane.showMessageDialog(null, + NbBundle.getMessage(this.getClass(), + "AutopsyOptionsPanel.invalidImageFile.msg"), + NbBundle.getMessage(this.getClass(), "AutopsyOptionsPanel.invalidImageFile.title"), + JOptionPane.ERROR_MESSAGE); + try { + updateAgencyLogo(oldLogoPath); //restore previous setting if new one is invalid + } catch (IOException ex1) { + LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex1); + } + } + } + }//GEN-LAST:event_browseLogosButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextField agencyLogoPathField; private javax.swing.JLabel agencyLogoPathFieldValidationLabel; @@ -963,8 +1040,11 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JRadioButton keepCurrentViewerRB; + private javax.swing.JTextField logFileCount; + private javax.swing.JTextField logNumAlert; private javax.swing.JPanel logoPanel; private javax.swing.ButtonGroup logoSourceButtonGroup; + private javax.swing.JLabel maxLogFileCount; private javax.swing.JLabel maxMemoryLabel; private javax.swing.JLabel maxMemoryUnitsLabel; private javax.swing.JLabel maxMemoryUnitsLabel1; diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 6e9b722d71..1aecff7348 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -200,3 +200,4 @@ CriterionChooser.ascendingRadio.text=\u25b2 Ascending\n CriterionChooser.removeButton.text=Remove CriterionChooser.descendingRadio.text=\u25bc Descending AutopsyOptionsPanel.agencyLogoPathFieldValidationLabel.text= +AutopsyOptionsPanel.logNumAlert.text= diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Logger.java b/Core/src/org/sleuthkit/autopsy/coreutils/Logger.java index 16fde58e29..5153e613b2 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Logger.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Logger.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2012-2015 Basis Technology Corp. + * Copyright 2012-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,68 +24,36 @@ import java.util.logging.FileHandler; import java.util.logging.Formatter; import java.util.logging.Handler; import java.sql.Timestamp; -import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.logging.LogRecord; +import org.sleuthkit.autopsy.core.UserPreferences; /** - * Autopsy specialization of the Java Logger class with custom file handlers. + * Autopsy specialization of the Java Logger class with a custom file handler. * Note that the custom loggers are not obtained from the global log manager. */ public final class Logger extends java.util.logging.Logger { private static final String LOG_ENCODING = PlatformUtil.getLogFileEncoding(); private static final int LOG_SIZE = 0; // In bytes, zero is unlimited - private static final int LOG_FILE_COUNT = 10; - private static final String LOG_WITHOUT_STACK_TRACES = "autopsy.log"; //NON-NLS - private static final String LOG_WITH_STACK_TRACES = "autopsy_traces.log"; //NON-NLS + private static final String LOG_FILE_NAME = "autopsy.log"; //NON-NLS private static final Map namesToLoggers = new HashMap<>(); private static final Handler consoleHandler = new java.util.logging.ConsoleHandler(); - private static FileHandler userFriendlyHandler = createFileHandlerWithoutTraces(PlatformUtil.getLogDirectory()); - private static FileHandler developerFriendlyHandler = createFileHandlerWithTraces(PlatformUtil.getLogDirectory()); - - /** - * Creates a custom file handler with a custom message formatter that does - * not include stack traces. - * - * @param logDirectory The directory where the log files should reside. - * - * @return A custom file handler. - */ - private static FileHandler createFileHandlerWithoutTraces(String logDirectory) { - String logFilePath = Paths.get(logDirectory, LOG_WITHOUT_STACK_TRACES).toString(); - try { - FileHandler fileHandler = new FileHandler(logFilePath, LOG_SIZE, LOG_FILE_COUNT); - fileHandler.setEncoding(LOG_ENCODING); - fileHandler.setFormatter(new Formatter() { - @Override - public String format(LogRecord record) { - return (new Date(record.getMillis())).toString() + " " - + record.getSourceClassName() + " " - + record.getSourceMethodName() + "\n" - + record.getLevel() + ": " - + this.formatMessage(record) + "\n"; - } - }); - return fileHandler; - } catch (IOException ex) { - throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS - } - } + private static FileHandler logFileHandler = createFileHandlerWithTraces(PlatformUtil.getLogDirectory()); /** * Creates a custom file handler with a custom message formatter that - * incldues stack traces. + * includes stack traces. * * @param logDirectory The directory where the log files should reside. * * @return A custom file handler. */ private static FileHandler createFileHandlerWithTraces(String logDirectory) { - String logFilePath = Paths.get(logDirectory, LOG_WITH_STACK_TRACES).toString(); + String logFilePath = Paths.get(logDirectory, LOG_FILE_NAME).toString(); try { - FileHandler fileHandler = new FileHandler(logFilePath, LOG_SIZE, LOG_FILE_COUNT); + FileHandler fileHandler = new FileHandler(logFilePath, LOG_SIZE, UserPreferences.getLogFileCount()); fileHandler.setEncoding(LOG_ENCODING); fileHandler.setFormatter(new Formatter() { @Override @@ -120,7 +88,7 @@ public final class Logger extends java.util.logging.Logger { */ synchronized public static void setLogDirectory(String directoryPath) { /* - * Create file handlers for the new directory and swap them into all of + * Create a file handler for the new directory and swap it into all of * the existing loggers using thread-safe Logger methods. The new * handlers are added before the old handlers so that no messages will * be lost, but this makes it possible for log messages to be written @@ -128,25 +96,20 @@ public final class Logger extends java.util.logging.Logger { * add/remove handler calls (currently, the base class handlers * collection is a CopyOnWriteArrayList). */ - FileHandler newUserFriendlyHandler = createFileHandlerWithoutTraces(directoryPath); - FileHandler newDeveloperFriendlyHandler = createFileHandlerWithTraces(directoryPath); + FileHandler newFileHandler = createFileHandlerWithTraces(directoryPath); for (Logger logger : namesToLoggers.values()) { - logger.addHandler(newUserFriendlyHandler); - logger.addHandler(newDeveloperFriendlyHandler); - logger.removeHandler(userFriendlyHandler); - logger.removeHandler(userFriendlyHandler); + logger.addHandler(newFileHandler); + logger.removeHandler(logFileHandler); } /* - * Close the old file handlers and save references to the new handlers + * Close the old file handler and save reference to the new handler * so they can be added to any new loggers. This swap is why this method * and the two overloads of getLogger() are synchronized, serializing - * access to userFriendlyHandler and developerFriendlyHandler. + * access to logFileHandler. */ - userFriendlyHandler.close(); - userFriendlyHandler = newUserFriendlyHandler; - developerFriendlyHandler.close(); - developerFriendlyHandler = newDeveloperFriendlyHandler; + logFileHandler.close(); + logFileHandler = newFileHandler; } /** @@ -178,8 +141,7 @@ public final class Logger extends java.util.logging.Logger { synchronized public static Logger getLogger(String name, String resourceBundleName) { if (!namesToLoggers.containsKey(name)) { Logger logger = new Logger(name, resourceBundleName); - logger.addHandler(userFriendlyHandler); - logger.addHandler(developerFriendlyHandler); + logger.addHandler(logFileHandler); namesToLoggers.put(name, logger); } return namesToLoggers.get(name);