diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties
index 8ba6b8f14e..db8e9e9808 100644
--- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties
@@ -20,8 +20,6 @@ ServicesMonitor.statusChange.notify.title=Service Status Update
ServicesMonitor.statusChange.notify.msg=Status for {0} is {1}
ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null
ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown
-TextConverter.convert.exception.txt=Unable to convert text {0} to hex text
-TextConverter.convertFromHex.exception.txt=Unable to convert hex text to text
ServicesMonitor.KeywordSearchNull=Cannot find Keyword Search service
ServicesMonitor.InvalidPortNumber=Invalid port number.
ServicesMonitor.remoteCaseDatabase.displayName.text=Multi-user case database service
diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
index 9ca9a4ac02..df63b0fa1f 100755
--- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
@@ -18,20 +18,16 @@
*/
package org.sleuthkit.autopsy.core;
-import java.util.Base64;
+import org.sleuthkit.autopsy.coreutils.TextConverter;
import java.util.prefs.BackingStoreException;
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.PBEParameterSpec;
-import org.openide.util.NbBundle;
+import org.openide.util.Exceptions;
import org.openide.util.NbPreferences;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+import org.sleuthkit.autopsy.coreutils.TextConverterException;
import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
import org.sleuthkit.datamodel.TskData.DbType;
@@ -205,12 +201,16 @@ public final class UserPreferences {
} catch (Exception ex) {
dbType = DbType.SQLITE;
}
- return new CaseDbConnectionInfo(
- preferences.get(EXTERNAL_DATABASE_HOSTNAME_OR_IP, ""),
- preferences.get(EXTERNAL_DATABASE_PORTNUMBER, "5432"),
- preferences.get(EXTERNAL_DATABASE_USER, ""),
- TextConverter.convertHexTextToText(preferences.get(EXTERNAL_DATABASE_PASSWORD, "")),
- dbType);
+ try {
+ return new CaseDbConnectionInfo(
+ preferences.get(EXTERNAL_DATABASE_HOSTNAME_OR_IP, ""),
+ preferences.get(EXTERNAL_DATABASE_PORTNUMBER, "5432"),
+ preferences.get(EXTERNAL_DATABASE_USER, ""),
+ TextConverter.convertHexTextToText(preferences.get(EXTERNAL_DATABASE_PASSWORD, "")),
+ dbType);
+ } catch (TextConverterException ex) {
+ throw new UserPreferencesException("Failure converting password hex text to text.", ex); // NON-NLS
+ }
}
/**
@@ -225,7 +225,11 @@ public final class UserPreferences {
preferences.put(EXTERNAL_DATABASE_HOSTNAME_OR_IP, connectionInfo.getHost());
preferences.put(EXTERNAL_DATABASE_PORTNUMBER, connectionInfo.getPort());
preferences.put(EXTERNAL_DATABASE_USER, connectionInfo.getUserName());
- preferences.put(EXTERNAL_DATABASE_PASSWORD, TextConverter.convertTextToHexText(connectionInfo.getPassword()));
+ try {
+ preferences.put(EXTERNAL_DATABASE_PASSWORD, TextConverter.convertTextToHexText(connectionInfo.getPassword()));
+ } catch (TextConverterException ex) {
+ throw new UserPreferencesException("Failure converting text to password hext text", ex); // NON-NLS
+ }
preferences.put(EXTERNAL_DATABASE_TYPE, connectionInfo.getDbType().toString());
}
@@ -267,7 +271,11 @@ public final class UserPreferences {
preferences.put(MESSAGE_SERVICE_HOST, info.getHost());
preferences.put(MESSAGE_SERVICE_PORT, Integer.toString(info.getPort()));
preferences.put(MESSAGE_SERVICE_USER, info.getUserName());
- preferences.put(MESSAGE_SERVICE_PASSWORD, TextConverter.convertTextToHexText(info.getPassword()));
+ try {
+ preferences.put(MESSAGE_SERVICE_PASSWORD, TextConverter.convertTextToHexText(info.getPassword()));
+ } catch (TextConverterException ex) {
+ throw new UserPreferencesException("Failed to convert password text to hex text.", ex);
+ }
}
/**
@@ -286,11 +294,15 @@ public final class UserPreferences {
port = DEFAULT_PORT_INT;
}
- return new MessageServiceConnectionInfo(
- preferences.get(MESSAGE_SERVICE_HOST, ""),
- port,
- preferences.get(MESSAGE_SERVICE_USER, ""),
- TextConverter.convertHexTextToText(preferences.get(MESSAGE_SERVICE_PASSWORD, "")));
+ try {
+ return new MessageServiceConnectionInfo(
+ preferences.get(MESSAGE_SERVICE_HOST, ""),
+ port,
+ preferences.get(MESSAGE_SERVICE_USER, ""),
+ TextConverter.convertHexTextToText(preferences.get(MESSAGE_SERVICE_PASSWORD, "")));
+ } catch (TextConverterException ex) {
+ throw new UserPreferencesException("Failed to convert password hex text to text.", ex);
+ }
}
/**
@@ -359,66 +371,4 @@ public final class UserPreferences {
preferences.put(APP_NAME, name);
}
- /**
- * Provides ability to convert text to hex text.
- */
- static final class TextConverter {
-
- private static final char[] TMP = "hgleri21auty84fwe".toCharArray(); //NON-NLS
- private static final byte[] SALT = {
- (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
- (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,};
-
- /**
- * Convert text to hex text.
- *
- * @param property Input text string.
- *
- * @return Converted hex string.
- *
- * @throws org.sleuthkit.autopsy.core.UserPreferencesException
- */
- static String convertTextToHexText(String property) throws UserPreferencesException {
- try {
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS
- SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP));
- Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS
- pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
- return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8")));
- } catch (Exception ex) {
- throw new UserPreferencesException(
- NbBundle.getMessage(TextConverter.class, "TextConverter.convert.exception.txt"));
- }
- }
-
- private static String base64Encode(byte[] bytes) {
- return Base64.getEncoder().encodeToString(bytes);
- }
-
- /**
- * Convert hex text back to text.
- *
- * @param property Input hex text string.
- *
- * @return Converted text string.
- *
- * @throws org.sleuthkit.autopsy.core.UserPreferencesException
- */
- static String convertHexTextToText(String property) throws UserPreferencesException {
- try {
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS
- SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP));
- Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS
- pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
- return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
- } catch (Exception ex) {
- throw new UserPreferencesException(
- NbBundle.getMessage(TextConverter.class, "TextConverter.convertFromHex.exception.txt"));
- }
- }
-
- private static byte[] base64Decode(String property) {
- return Base64.getDecoder().decode(property);
- }
- }
}
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form
index 8957d55bb1..8e379954e9 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.form
@@ -45,222 +45,212 @@
-
+
-
+
-
+
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java
index 5b7cf32634..8ad63473d4 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java
@@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
- * Copyright 2011-2017 Basis Technology Corp.
+ * Copyright 2011-2013 Basis Technology Corp.
* Contact: carrier sleuthkit org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,12 +26,14 @@ import java.awt.event.ActionListener;
import java.awt.datatransfer.StringSelection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.swing.JMenuItem;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumn;
import org.apache.commons.lang.StringUtils;
import org.openide.nodes.Node;
import org.openide.util.Lookup;
@@ -50,7 +52,7 @@ import org.netbeans.swing.etable.ETable;
/**
* Instances of this class display the BlackboardArtifacts associated with the
- * Content represented by a Node. Each BlackboardArtifact is rendered as an HTML
+ * Content represented by a Node. Each BlackboardArtifact is rendered displayed in a JTable
* representation of its BlackboardAttributes.
*/
@ServiceProvider(service = DataContentViewer.class, position = 3)
@@ -75,6 +77,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
Bundle.DataContentViewerArtifact_attrsTableHeader_type(),
Bundle.DataContentViewerArtifact_attrsTableHeader_value(),
Bundle.DataContentViewerArtifact_attrsTableHeader_sources()};
+ private static final int[] COLUMN_WIDTHS = {100, 800, 100};
public DataContentViewerArtifact() {
initResultsTable();
@@ -86,30 +89,32 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private void initResultsTable() {
resultsTable = new ETable();
-
resultsTable.setModel(new javax.swing.table.DefaultTableModel() {
private static final long serialVersionUID = 1L;
- @Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
-
});
resultsTable.setCellSelectionEnabled(true);
- resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
- resultsTable.setColumnHidingAllowed(false);
resultsTable.getTableHeader().setReorderingAllowed(false);
- resultsTable.setRowSorter(null); //null sorter turns off sorting
+ resultsTable.setColumnHidingAllowed(false);
+ resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
updateColumnSizes();
}
private void updateColumnSizes() {
resultsTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN);
- if (resultsTable.getColumnModel().getColumnCount() > 0) {
- resultsTable.getColumnModel().getColumn(0).setPreferredWidth(100);
- resultsTable.getColumnModel().getColumn(1).setPreferredWidth(800);
- resultsTable.getColumnModel().getColumn(2).setPreferredWidth(100);
+ Enumeration columns = resultsTable.getColumnModel().getColumns();
+ while (columns.hasMoreElements()) {
+ TableColumn col = columns.nextElement();
+ if (col.getHeaderValue().equals(COLUMN_HEADERS[0])) {
+ col.setPreferredWidth(COLUMN_WIDTHS[0]);
+ } else if (col.getHeaderValue().equals(COLUMN_HEADERS[1])) {
+ col.setPreferredWidth(COLUMN_WIDTHS[1]);
+ } else if (col.getHeaderValue().equals(COLUMN_HEADERS[2])) {
+ col.setPreferredWidth(COLUMN_WIDTHS[2]);
+ }
}
}
@@ -119,13 +124,12 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
- //
+ // //GEN-BEGIN:initComponents
private void initComponents() {
rightClickMenu = new javax.swing.JPopupMenu();
copyMenuItem = new javax.swing.JMenuItem();
selectAllMenuItem = new javax.swing.JMenuItem();
- jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel();
totalPageLabel = new javax.swing.JLabel();
ofLabel = new javax.swing.JLabel();
@@ -145,9 +149,6 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
setPreferredSize(new java.awt.Dimension(622, 58));
- jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
- jScrollPane1.setPreferredSize(new java.awt.Dimension(622, 58));
-
jPanel1.setPreferredSize(new java.awt.Dimension(620, 58));
totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.totalPageLabel.text")); // NOI18N
@@ -197,7 +198,8 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
}
});
- resultsTableScrollPane.setPreferredSize(new java.awt.Dimension(620, 271));
+ resultsTableScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+ resultsTableScrollPane.setPreferredSize(new java.awt.Dimension(620, 34));
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
@@ -218,13 +220,13 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
.addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap(366, Short.MAX_VALUE))
.addComponent(resultsTableScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
- .addContainerGap(277, Short.MAX_VALUE)
+ .addContainerGap(280, Short.MAX_VALUE)
.addComponent(artifactLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(85, Short.MAX_VALUE)))
+ .addContainerGap(84, Short.MAX_VALUE)))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -239,47 +241,45 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
.addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(resultsTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE))
+ .addComponent(resultsTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE)
+ .addGap(0, 0, 0))
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(artifactLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 40, Short.MAX_VALUE)))
+ .addGap(0, 401, Short.MAX_VALUE)))
);
- jScrollPane1.setViewportView(jPanel1);
-
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 622, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
- }//
+ }// //GEN-END:initComponents
- private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {
- currentPage = currentPage - 1;
- currentPageLabel.setText(Integer.toString(currentPage));
- artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName());
- startNewTask(new SelectedArtifactChangedTask(currentPage));
- }
-
- private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {
+ private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
currentPage = currentPage + 1;
currentPageLabel.setText(Integer.toString(currentPage));
artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName());
startNewTask(new SelectedArtifactChangedTask(currentPage));
- }
+ }//GEN-LAST:event_nextPageButtonActionPerformed
- // Variables declaration - do not modify
+ private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
+ currentPage = currentPage - 1;
+ currentPageLabel.setText(Integer.toString(currentPage));
+ artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName());
+ startNewTask(new SelectedArtifactChangedTask(currentPage));
+ }//GEN-LAST:event_prevPageButtonActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel artifactLabel;
private javax.swing.JMenuItem copyMenuItem;
private javax.swing.JLabel currentPageLabel;
private javax.swing.JPanel jPanel1;
- private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton nextPageButton;
private javax.swing.JLabel ofLabel;
private javax.swing.JLabel pageLabel;
@@ -289,7 +289,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private javax.swing.JPopupMenu rightClickMenu;
private javax.swing.JMenuItem selectAllMenuItem;
private javax.swing.JLabel totalPageLabel;
- // End of variables declaration
+ // End of variables declaration//GEN-END:variables
private ETable resultsTable;
private void customizeComponents() {
@@ -548,10 +548,6 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
currentPageLabel.setText(Integer.toString(currentPage));
artifactLabel.setText(viewUpdate.tableContents.getArtifactDisplayName());
- // @@@ This can take a long time. Perhaps a faster HTML renderer can be found.
- // Note that the rendering appears to be done on a background thread, since the
- // wait cursor reset below happens before the new text hits the JTextPane. On the
- // other hand, the UI is unresponsive...
DefaultTableModel tModel = ((DefaultTableModel) resultsTable.getModel());
tModel.setDataVector(viewUpdate.tableContents.getRows(), COLUMN_HEADERS);
updateColumnSizes();
@@ -740,8 +736,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
List artifactContents = getArtifactContents();
ResultsTableArtifact artifactContent = artifactContents.get(pageIndex - 1);
- // It may take a considerable amount of time to fetch the attributes of the selected artifact and render them
- // as HTML, so check for cancellation.
+ // It may take a considerable amount of time to fetch the attributes of the selected artifact so check for cancellation.
if (isCancelled()) {
return null;
}
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties
index f633003d1d..e16d1e4fbd 100644
--- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties
@@ -20,4 +20,6 @@ PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, fre
PlatformUtil.getAllMemUsageInfo.usageText={0}\n\
{1}\n\
Process Virtual Memory\: {2}
-StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract
\ No newline at end of file
+StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract
+TextConverter.convert.exception.txt=Unable to convert text {0} to hex text
+TextConverter.convertFromHex.exception.txt=Unable to convert hex text to text
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java
new file mode 100644
index 0000000000..b69a411a96
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverter.java
@@ -0,0 +1,88 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.coreutils;
+
+import java.util.Base64;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import org.openide.util.NbBundle;
+
+/**
+ * Provides ability to convert text to hex text.
+ */
+public final class TextConverter {
+
+ private static final char[] TMP = "hgleri21auty84fwe".toCharArray(); //NON-NLS
+ private static final byte[] SALT = {(byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12};
+
+ /**
+ * Convert text to hex text.
+ *
+ * @param property Input text string.
+ *
+ * @return Converted hex string.
+ *
+ * @throws org.sleuthkit.autopsy.coreutils.TextConverterException
+ */
+ public static String convertTextToHexText(String property) throws TextConverterException {
+ try {
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS
+ SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP));
+ Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS
+ pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
+ return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8")));
+ } catch (Exception ex) {
+ throw new TextConverterException(NbBundle.getMessage(TextConverter.class, "TextConverter.convert.exception.txt"));
+ }
+ }
+
+ public static String base64Encode(byte[] bytes) {
+ return Base64.getEncoder().encodeToString(bytes);
+ }
+
+ /**
+ * Convert hex text back to text.
+ *
+ * @param property Input hex text string.
+ *
+ * @return Converted text string.
+ *
+ * @throws org.sleuthkit.autopsy.coreutils.TextConverterException
+ */
+ public static String convertHexTextToText(String property) throws TextConverterException {
+ try {
+ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); //NON-NLS
+ SecretKey key = keyFactory.generateSecret(new PBEKeySpec(TMP));
+ Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); //NON-NLS
+ pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
+ return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
+ } catch (Exception ex) {
+ throw new TextConverterException(NbBundle.getMessage(TextConverter.class, "TextConverter.convertFromHex.exception.txt"));
+ }
+ }
+
+ public static byte[] base64Decode(String property) {
+ return Base64.getDecoder().decode(property);
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java
new file mode 100644
index 0000000000..3634d021e2
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/TextConverterException.java
@@ -0,0 +1,30 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
+ * Contact: carrier sleuthkit 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.coreutils;
+
+/**
+ *
+ */
+public class TextConverterException extends Exception {
+
+ public TextConverterException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java
index 0d34d62fdd..c25e4c52b0 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/KeywordHits.java
@@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
- *
- * Copyright 2011-2016 Basis Technology Corp.
+ *
+ * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier sleuthkit 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.
@@ -33,6 +33,8 @@ import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import java.util.logging.Level;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
@@ -68,18 +70,18 @@ public class KeywordHits implements AutopsyVisitableItem {
// String used in the instance MAP so that exact matches and substring can fit into the same
// data structure as regexps, even though they don't use instances.
private final String DEFAULT_INSTANCE_NAME = "DEFAULT_INSTANCE_NAME";
-
+
public KeywordHits(SleuthkitCase skCase) {
this.skCase = skCase;
keywordResults = new KeywordResults();
}
-
- /* All of these maps and code assume the following:
- * Regexps will have an 'instance' layer that shows the specific words that matched the regexp
- * Exact match and substring will not have the instance layer and instead will have the specific hits
- * below their term.
- */
+ /*
+ * All of these maps and code assume the following: Regexps will have an
+ * 'instance' layer that shows the specific words that matched the regexp
+ * Exact match and substring will not have the instance layer and instead
+ * will have the specific hits below their term.
+ */
private final class KeywordResults extends Observable {
// Map from listName/Type to Map of keywords/regexp to Map of instance terms to Set of artifact Ids
@@ -104,11 +106,12 @@ public class KeywordHits implements AutopsyVisitableItem {
}
/**
- * Get keywords used in a given list. Will be regexp patterns for regexps
- * and search term for non-regexps.
- *
+ * Get keywords used in a given list. Will be regexp patterns for
+ * regexps and search term for non-regexps.
+ *
* @param listName Keyword list name
- * @return
+ *
+ * @return
*/
List getKeywords(String listName) {
List keywords;
@@ -118,15 +121,16 @@ public class KeywordHits implements AutopsyVisitableItem {
Collections.sort(keywords);
return keywords;
}
-
+
/**
- * Get specific keyword terms that were found for a given list
- * and keyword combination. For example, a specific phone number for a
- * phone number regexp. Will be the default instance for non-regexp searches.
- *
+ * Get specific keyword terms that were found for a given list and
+ * keyword combination. For example, a specific phone number for a phone
+ * number regexp. Will be the default instance for non-regexp searches.
+ *
* @param listName Keyword list name
- * @param keyword search term (regexp pattern or exact match term)
- * @return
+ * @param keyword search term (regexp pattern or exact match term)
+ *
+ * @return
*/
List getKeywordInstances(String listName, String keyword) {
List instances;
@@ -139,10 +143,14 @@ public class KeywordHits implements AutopsyVisitableItem {
/**
* Get artifact ids for a given list, keyword, and instance triple
- * @param listName Keyword list name
- * @param keyword search term (regexp pattern or exact match term)
- * @param keywordInstance specific term that matched (or default instance name)
- * @return
+ *
+ * @param listName Keyword list name
+ * @param keyword search term (regexp pattern or exact match
+ * term)
+ * @param keywordInstance specific term that matched (or default
+ * instance name)
+ *
+ * @return
*/
Set getArtifactIds(String listName, String keyword, String keywordInstance) {
synchronized (topLevelMap) {
@@ -151,11 +159,13 @@ public class KeywordHits implements AutopsyVisitableItem {
}
/**
- * Add a hit for a regexp to the internal data structure.
- * @param listMap Maps keywords/regexp to instances to artifact IDs
- * @param regExp Regular expression that was used in search
+ * Add a hit for a regexp to the internal data structure.
+ *
+ * @param listMap Maps keywords/regexp to instances to artifact
+ * IDs
+ * @param regExp Regular expression that was used in search
* @param keywordInstance Specific term that matched regexp
- * @param artifactId Artifact id of file that had hit
+ * @param artifactId Artifact id of file that had hit
*/
void addRegExpToList(Map>> listMap, String regExp, String keywordInstance, Long artifactId) {
if (listMap.containsKey(regExp) == false) {
@@ -171,12 +181,13 @@ public class KeywordHits implements AutopsyVisitableItem {
// add this ID to the instance
instanceMap.get(keywordInstance).add(artifactId);
}
-
-
+
/**
- * Add a hit for a exactmatch (or substring) to the internal data structure.
- * @param listMap Maps keywords/regexp to instances to artifact IDs
- * @param keyWord Term that was hit
+ * Add a hit for a exactmatch (or substring) to the internal data
+ * structure.
+ *
+ * @param listMap Maps keywords/regexp to instances to artifact IDs
+ * @param keyWord Term that was hit
* @param artifactId Artifact id of file that had hit
*/
void addNonRegExpMatchToList(Map>> listMap, String keyWord, Long artifactId) {
@@ -191,10 +202,13 @@ public class KeywordHits implements AutopsyVisitableItem {
}
instanceMap.get(DEFAULT_INSTANCE_NAME).add(artifactId);
}
-
+
/**
- * Populate data structure for the tree based on the keyword hit artifacts
- * @param artifactIds Maps Artifact ID to map of attribute types to attribute values
+ * Populate data structure for the tree based on the keyword hit
+ * artifacts
+ *
+ * @param artifactIds Maps Artifact ID to map of attribute types to
+ * attribute values
*/
void populateTreeMaps(Map> artifactIds) {
synchronized (topLevelMap) {
@@ -223,7 +237,7 @@ public class KeywordHits implements AutopsyVisitableItem {
String reg = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID()));
// new in 4.4
String kwType = attributes.get(Long.valueOf(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_SEARCH_TYPE.getTypeID()));
-
+
// part of a list
if (listName != null) {
// get or create list entry
@@ -231,7 +245,7 @@ public class KeywordHits implements AutopsyVisitableItem {
listsMap.put(listName, new LinkedHashMap<>());
}
Map>> listMap = listsMap.get(listName);
-
+
// substring, treated same as exact match
// Enum for "1" is defined in KeywordSearch.java
if ((kwType != null) && (kwType.equals("1"))) {
@@ -241,8 +255,7 @@ public class KeywordHits implements AutopsyVisitableItem {
} else {
addNonRegExpMatchToList(listMap, word, id);
}
- }
- else if (reg != null) {
+ } else if (reg != null) {
addRegExpToList(listMap, reg, word, id);
} else {
addNonRegExpMatchToList(listMap, word, id);
@@ -259,11 +272,11 @@ public class KeywordHits implements AutopsyVisitableItem {
} // literal, single term
else {
addNonRegExpMatchToList(literalMap, word, id);
- }
+ }
}
topLevelMap.putAll(listsMap);
}
-
+
setChanged();
notifyObservers();
}
@@ -299,9 +312,9 @@ public class KeywordHits implements AutopsyVisitableItem {
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS
long typeId = resultSet.getLong("attribute_type_id"); //NON-NLS
if (!artifactIds.containsKey(artifactId)) {
- artifactIds.put(artifactId, new LinkedHashMap());
+ artifactIds.put(artifactId, new LinkedHashMap<>());
}
- if (valueStr != null && !valueStr.equals("")) {
+ if (StringUtils.isNotEmpty(valueStr)) {
artifactIds.get(artifactId).put(typeId, valueStr);
} else {
// Keyword Search Type is an int
@@ -366,7 +379,7 @@ public class KeywordHits implements AutopsyVisitableItem {
}
/**
- * Creates the list nodes
+ * Creates the list nodes
*/
private class ListFactory extends ChildFactory.Detachable implements Observer {
@@ -458,8 +471,9 @@ public class KeywordHits implements AutopsyVisitableItem {
}
}
- /**
- * Represents the keyword search lists (or default groupings if list was not given)
+ /**
+ * Represents the keyword search lists (or default groupings if list was not
+ * given)
*/
public class ListNode extends DisplayableItemNode implements Observer {
@@ -583,17 +597,17 @@ public class KeywordHits implements AutopsyVisitableItem {
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/keyword_hits.png"); //NON-NLS
updateDisplayName();
keywordResults.addObserver(this);
+
}
private void updateDisplayName() {
- int totalDescendants = 0;
-
- for (String instance : keywordResults.getKeywordInstances(setName, keyword)) {
- Set ids = keywordResults.getArtifactIds(setName, keyword, instance);
- totalDescendants += ids.size();
- }
-
- super.setDisplayName(keyword + " (" + totalDescendants + ")");
+ super.setDisplayName(keyword + " (" + countTotalDescendants() + ")");
+ }
+
+ private int countTotalDescendants() {
+ return keywordResults.getKeywordInstances(setName, keyword).stream()
+ .mapToInt(instance -> keywordResults.getArtifactIds(setName, keyword, instance).size())
+ .sum();
}
@Override
@@ -605,12 +619,7 @@ public class KeywordHits implements AutopsyVisitableItem {
public boolean isLeafTypeNode() {
List instances = keywordResults.getKeywordInstances(setName, keyword);
// is this an exact/substring match (i.e. did we use the DEFAULT name)?
- if (instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME)) {
- return true;
- }
- else {
- return false;
- }
+ return instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME);
}
@Override
@@ -635,7 +644,7 @@ public class KeywordHits implements AutopsyVisitableItem {
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.name"),
NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.displayName"),
NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"),
- keywordResults.getKeywordInstances(setName, keyword).size()));
+ countTotalDescendants()));
return s;
}
@@ -645,42 +654,50 @@ public class KeywordHits implements AutopsyVisitableItem {
return getClass().getName();
}
}
-
+
// Allows us to pass in either longs or strings
// as they keys for different types of nodes at the
// same level. Probably a better way to do this, but
// it works.
- class RegExpInstanceKey {
+ private class RegExpInstanceKey {
+
private final boolean isRegExp;
private String strKey;
private Long longKey;
- public RegExpInstanceKey(String key) {
+
+ RegExpInstanceKey(String key) {
isRegExp = true;
strKey = key;
}
- public RegExpInstanceKey(Long key) {
+
+ RegExpInstanceKey(Long key) {
isRegExp = false;
longKey = key;
}
+
boolean isRegExp() {
return isRegExp;
}
+
Long getIdKey() {
return longKey;
}
+
String getRegExpKey() {
return strKey;
}
}
/**
- * Creates the nodes for a given regexp that represent the specific terms that were found
+ * Creates the nodes for a given regexp that represent the specific terms
+ * that were found
*/
public class RegExpInstancesFactory extends ChildFactory.Detachable implements Observer {
+
private final String keyword;
private final String setName;
-
- private Map nodesMap = new HashMap<>();
+
+ private final Map nodesMap = new HashMap<>();
public RegExpInstancesFactory(String setName, String keyword) {
super();
@@ -700,15 +717,15 @@ public class KeywordHits implements AutopsyVisitableItem {
@Override
protected boolean createKeys(List list) {
- List instances = keywordResults.getKeywordInstances(setName, keyword);
+ List instances = keywordResults.getKeywordInstances(setName, keyword);
// The keys are different depending on what we are displaying.
// regexp get another layer to show instances.
// Exact/substring matches don't.
if ((instances.size() == 1) && (instances.get(0).equals(DEFAULT_INSTANCE_NAME))) {
- for (Long id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME) ) {
+ for (Long id : keywordResults.getArtifactIds(setName, keyword, DEFAULT_INSTANCE_NAME)) {
RegExpInstanceKey key = new RegExpInstanceKey(id);
if (!nodesMap.containsKey(key)) {
- nodesMap.put(key, createNode(key));
+ nodesMap.put(key, createNode(key));
}
list.add(key);
}
@@ -720,7 +737,7 @@ public class KeywordHits implements AutopsyVisitableItem {
}
list.add(key);
}
-
+
}
return true;
}
@@ -731,23 +748,24 @@ public class KeywordHits implements AutopsyVisitableItem {
}
private DisplayableItemNode createNode(RegExpInstanceKey key) {
- // if it isn't a regexp, then skip the 'instance' layer of the tree
+ // if it isn't a regexp, then skip the 'instance' layer of the tree
if (key.isRegExp() == false) {
return createBlackboardArtifactNode(key.getIdKey());
} else {
return new RegExpInstanceNode(setName, keyword, key.getRegExpKey());
}
-
+
}
+
@Override
public void update(Observable o, Object arg) {
refresh(true);
}
-
+
}
-
+
/**
- * Represents a specific term that was found from a regexp
+ * Represents a specific term that was found from a regexp
*/
public class RegExpInstanceNode extends DisplayableItemNode implements Observer {
@@ -756,7 +774,7 @@ public class KeywordHits implements AutopsyVisitableItem {
private final String instance;
public RegExpInstanceNode(String setName, String keyword, String instance) {
- super(Children.create(new HitsFactory(setName, keyword, instance), true), Lookups.singleton(keyword));
+ super(Children.create(new HitsFactory(setName, keyword, instance), true), Lookups.singleton(instance));
super.setName(instance); //the instance represents the name of the keyword hit at this point as the keyword is the regex
this.setName = setName;
this.keyword = keyword;
@@ -803,7 +821,7 @@ public class KeywordHits implements AutopsyVisitableItem {
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.name"),
NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.displayName"),
NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"),
- keywordResults.getKeywordInstances(setName, keyword).size()));
+ keywordResults.getArtifactIds(setName, keyword, instance).size()));
return s;
}
@@ -814,12 +832,14 @@ public class KeywordHits implements AutopsyVisitableItem {
}
}
- /**
+ /**
* Create a blackboard node for the given Keyword Hit artifact
+ *
* @param artifactId
+ *
* @return Node or null on error
*/
- private BlackboardArtifactNode createBlackboardArtifactNode (Long artifactId) {
+ private BlackboardArtifactNode createBlackboardArtifactNode(Long artifactId) {
if (skCase == null) {
return null;
}
@@ -869,7 +889,7 @@ public class KeywordHits implements AutopsyVisitableItem {
}
return null;
}
-
+
/**
* Creates nodes for individual files that had hits
*/
@@ -878,8 +898,8 @@ public class KeywordHits implements AutopsyVisitableItem {
private final String keyword;
private final String setName;
private final String instance;
-
- private Map nodesMap = new HashMap<>();
+
+ private final Map nodesMap = new HashMap<>();
public HitsFactory(String setName, String keyword, String instance) {
super();
@@ -900,11 +920,11 @@ public class KeywordHits implements AutopsyVisitableItem {
@Override
protected boolean createKeys(List list) {
- for (Long id : keywordResults.getArtifactIds(setName, keyword, instance) ) {
+ for (Long id : keywordResults.getArtifactIds(setName, keyword, instance)) {
if (!nodesMap.containsKey(id)) {
- nodesMap.put(id, createBlackboardArtifactNode(id));
+ nodesMap.put(id, createBlackboardArtifactNode(id));
}
- list.add(id);
+ list.add(id);
}
return true;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java
index d2f147419d..d8c24d1a58 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamCaseEditDetailsDialog.java
@@ -524,7 +524,7 @@ public class EamCaseEditDetailsDialog extends JDialog {
private void updateDb() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
LOGGER.log(Level.SEVERE, "Enteprise artifacts manager database not enabled"); // NON-NLS
return;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java
index 7b7f2db346..7c13f22530 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/actions/EamEditCaseInfoAction.java
@@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.actions;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
@@ -29,7 +28,7 @@ import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case;
-import org.sleuthkit.autopsy.coreutils.ModuleSettings;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb;
/**
* Action to update case details in enterprise artifacts manager database
@@ -53,8 +52,7 @@ public final class EamEditCaseInfoAction extends CallableSystemAction implements
@Override
public boolean isEnabled() {
- boolean enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS
- return enabled && Case.isCaseOpen();
+ return EamDb.isEnabled() && Case.isCaseOpen();
}
@Override
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java
index e0ad406386..f4679d52a6 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/contentviewer/DataContentViewerOtherCases.java
@@ -504,8 +504,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
@Override
public boolean isSupported(Node node) {
- EamDb dbManager = EamDb.getInstance();
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
return false;
}
@@ -516,8 +515,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
@Override
@Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifacts manager database."})
public void setNode(Node node) {
- EamDb dbManager = EamDb.getInstance();
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
return;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java
index 55145ec8b1..4c7c0e09a4 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/AbstractSqlEamDb.java
@@ -45,8 +45,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
private final static Logger LOGGER = Logger.getLogger(AbstractSqlEamDb.class.getName());
- protected static final int SCHEMA_VERSION = 1;
- protected final List DEFAULT_ARTIFACT_TYPES = new ArrayList<>();
+ protected final List DEFAULT_ARTIFACT_TYPES;
private int bulkArtifactsCount;
private int bulkGlobalArtifactsCount;
@@ -67,7 +66,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkArtifacts = new HashMap<>();
bulkGlobalArtifacts = new HashMap<>();
- loadDefaultArtifactTypes();
+ DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
bulkArtifacts.put(type.getName(), new ArrayList<>());
@@ -75,56 +74,6 @@ public abstract class AbstractSqlEamDb implements EamDb {
}
}
- /**
- * Load the default correlation artifact types
- */
- private void loadDefaultArtifactTypes() {
- DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("FILES", true, true)); // NON-NLS
- DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("DOMAIN", true, false)); // NON-NLS
- DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("EMAIL", true, false)); // NON-NLS
- DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("PHONE", true, false)); // NON-NLS
- DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("USBID", true, false)); // NON-NLS
- }
-
- /**
- * Store the default Correlation Artifact Types in the db.
- *
- * This should be called immediately following the database schema being
- * loaded.
- *
- * @throws EamDbException
- */
- private void storeDefaultArtifactTypes() throws EamDbException {
- for (EamArtifact.Type defType : DEFAULT_ARTIFACT_TYPES) {
- newCorrelationArtifactType(defType);
- }
- }
-
- /**
- * Store the schema version into the db_info table.
- *
- * This should be called immediately following the database schema being
- * loaded.
- *
- * @throws EamDbException
- */
- private void storeSchemaVersion() throws EamDbException {
- newDbInfo("SCHEMA_VERSION", String.valueOf(SCHEMA_VERSION));
- }
-
- /**
- * Insert all default content into a freshly initialized/reset database.
- *
- * This should be called immediately following the database schema being
- * reset or initialized.
- *
- * @throws EamDbException
- */
- protected void insertDefaultContent() throws EamDbException {
- storeDefaultArtifactTypes();
- storeSchemaVersion();
- }
-
/**
* Check to see if the database schema exists and is the current version. -
* If it doesn't exist, initialize it and load default content. - If it is
@@ -133,86 +82,30 @@ public abstract class AbstractSqlEamDb implements EamDb {
*
* Note: this should be call after the connectionPool is initialized.
*/
- protected void confirmDatabaseSchema() throws EamDbException {
- int schema_version;
- try {
- schema_version = Integer.parseInt(getDbInfo("SCHEMA_VERSION"));
- } catch (EamDbException | NumberFormatException ex) {
- // error likely means we have not initialized the schema
- schema_version = 0;
- LOGGER.log(Level.WARNING, "Could not find SCHEMA_VERSION in db_info table, assuming database is not initialized.", ex); // NON-NLS
- }
-
- if (0 == schema_version) {
- initializeDatabaseSchema();
- insertDefaultContent();
- } else if (SCHEMA_VERSION > schema_version) {
- // FUTURE: upgrade schema
- }
- // else, schema is current
- }
-
- /**
- * Create the schema for the selected database implementation
- */
- protected abstract void initializeDatabaseSchema() throws EamDbException;
+// protected void confirmDatabaseSchema() throws EamDbException {
+// int schema_version;
+// try {
+// schema_version = Integer.parseInt(getDbInfo("SCHEMA_VERSION"));
+// } catch (EamDbException | NumberFormatException ex) {
+// // error likely means we have not initialized the schema
+// schema_version = 0;
+// LOGGER.log(Level.WARNING, "Could not find SCHEMA_VERSION in db_info table, assuming database is not initialized.", ex); // NON-NLS
+// }
+//
+// if (0 == schema_version) {
+//// initializeDatabaseSchema();
+// insertDefaultContent();
+// } else if (SCHEMA_VERSION > schema_version) {
+// // FUTURE: upgrade schema
+// }
+// // else, schema is current
+// }
/**
* Setup and create a connection to the selected database implementation
*/
protected abstract Connection connect() throws EamDbException;
- /**
- * Close the in-use connection and return it to the pool.
- *
- * @param conn An open connection
- *
- * @throws EamDbException
- */
- protected void closeConnection(Connection conn) throws EamDbException {
- if (null != conn) {
- try {
- conn.close();
- } catch (SQLException ex) {
- throw new EamDbException("Error closing Connection.", ex);
- }
- }
- }
-
- /**
- * Close the prepared statement.
- *
- * @param preparedStatement
- *
- * @throws EamDbException
- */
- protected void closePreparedStatement(PreparedStatement preparedStatement) throws EamDbException {
- if (null != preparedStatement) {
- try {
- preparedStatement.close();
- } catch (SQLException ex) {
- throw new EamDbException("Error closing PreparedStatement.", ex);
- }
- }
- }
-
- /**
- * Close the resultSet.
- *
- * @param resultSet
- *
- * @throws EamDbException
- */
- protected void closeResultSet(ResultSet resultSet) throws EamDbException {
- if (null != resultSet) {
- try {
- resultSet.close();
- } catch (SQLException ex) {
- throw new EamDbException("Error closing ResultSet.", ex);
- }
- }
- }
-
/**
* Get the list of tags recognized as "Bad"
*
@@ -260,8 +153,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error adding new name/value pair to db_info.", ex);
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -293,9 +186,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting value for name.", ex);
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return value;
@@ -323,8 +216,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error updating value for name.", ex);
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -366,8 +259,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new case.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -406,8 +299,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error updating case.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -442,9 +335,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting case details.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return eamCaseResult;
@@ -479,9 +372,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting all cases.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return cases;
@@ -510,8 +403,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new data source.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -537,8 +430,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error updating case.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -557,7 +450,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
- String sql = "SELECT * FROM data_sources WHERE device_id=?";
+ String sql = "SELECT * FROM data_sources WHERE device_id=?"; // NON-NLS
try {
preparedStatement = conn.prepareStatement(sql);
@@ -569,9 +462,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting case details.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return eamDataSourceResult;
@@ -603,9 +496,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting all data sources.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return dataSources;
@@ -651,8 +544,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new artifact into artifacts table.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -697,9 +590,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return artifactInstances;
@@ -749,9 +642,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return artifactInstances;
@@ -790,9 +683,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting count of artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return instanceCount;
@@ -852,9 +745,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return instanceCount;
@@ -897,9 +790,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return instanceCount;
@@ -953,9 +846,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error counting artifact instances by caseName/dataSource.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return instanceCount;
@@ -1035,8 +928,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
} finally {
- closePreparedStatement(bulkPs);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(bulkPs);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1088,8 +981,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting bulk cases.", ex); // NON-NLS
} finally {
- closePreparedStatement(bulkPs);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(bulkPs);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1154,10 +1047,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting/setting artifact instance knownStatus=Bad.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedUpdate);
- closePreparedStatement(preparedQuery);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedUpdate);
+ EamDbUtil.closePreparedStatement(preparedQuery);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1202,9 +1095,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return artifactInstances;
@@ -1241,9 +1134,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting count of known bad artifact instances.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return badInstances;
@@ -1292,9 +1185,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return caseNames.stream().collect(Collectors.toList());
@@ -1332,9 +1225,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error determining if artifact is globally known bad.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
return 0 < badInstances;
@@ -1365,8 +1258,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new organization.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1397,9 +1290,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting all organizations.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1430,9 +1323,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting organization by id.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1477,10 +1370,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new global set.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement1);
- closePreparedStatement(preparedStatement2);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement1);
+ EamDbUtil.closePreparedStatement(preparedStatement2);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1511,9 +1404,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting global set by id.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement1);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement1);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1542,8 +1435,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new global file instance into global_files table.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1606,8 +1499,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
} finally {
- closePreparedStatement(bulkPs);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(bulkPs);
+ EamDbUtil.closeConnection(conn);
}
}
}
@@ -1640,9 +1533,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting global set by id.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement1);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement1);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1671,8 +1564,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error inserting new correlation artifact type.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1704,9 +1597,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting all correlation artifact types.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1738,9 +1631,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting enabled correlation artifact types.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1772,9 +1665,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting supported correlation artifact types.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1802,8 +1695,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -1836,9 +1729,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) {
throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS
} finally {
- closePreparedStatement(preparedStatement);
- closeResultSet(resultSet);
- closeConnection(conn);
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ EamDbUtil.closeResultSet(resultSet);
+ EamDbUtil.closeConnection(conn);
}
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java
index 090341023c..dd33b5e0e9 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamArtifact.java
@@ -36,6 +36,19 @@ public class EamArtifact implements Serializable {
private Type artifactType;
private final List artifactInstances;
+ /**
+ * Load the default correlation artifact types
+ */
+ public static List getDefaultArtifactTypes() {
+ List DEFAULT_ARTIFACT_TYPES = new ArrayList<>();
+ DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("FILES", true, true)); // NON-NLS
+ DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("DOMAIN", true, false)); // NON-NLS
+ DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("EMAIL", true, false)); // NON-NLS
+ DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("PHONE", true, false)); // NON-NLS
+ DEFAULT_ARTIFACT_TYPES.add(new EamArtifact.Type("USBID", true, false)); // NON-NLS
+ return DEFAULT_ARTIFACT_TYPES;
+ }
+
public EamArtifact(Type artifactType, String artifactValue) {
this.ID = "";
this.artifactType = artifactType;
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java
index a5b71de42a..0f7a1839cc 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDb.java
@@ -24,11 +24,12 @@ import java.util.List;
* Main interface for interacting with the database
*/
public interface EamDb {
+ public static final int SCHEMA_VERSION = 1;
/**
- * Get the instance; default to SQLITE.
+ * Get the instance
*
- * @return The EamDb instance
+ * @return The EamDb instance or null if one is not configured.
*
* @throws EamDbException
*/
@@ -40,8 +41,9 @@ public interface EamDb {
return PostgresEamDb.getInstance();
case SQLITE:
- default:
return SqliteEamDb.getInstance();
+ default:
+ return null;
}
}
@@ -65,7 +67,9 @@ public interface EamDb {
*
* @return Is the database enabled
*/
- boolean isEnabled();
+ static boolean isEnabled() {
+ return EamDbPlatformEnum.getSelectedPlatform() != EamDbPlatformEnum.DISABLED;
+ }
/**
* Get the list of tags recognized as "Bad"
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java
index bc02377430..2b117d326d 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbPlatformEnum.java
@@ -24,7 +24,8 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
*
*/
public enum EamDbPlatformEnum {
- SQLITE("SQLite", true),
+ DISABLED("Disabled", true),
+ SQLITE("SQLite", false),
POSTGRESQL("PostgreSQL", false);
private final String platformName;
@@ -44,6 +45,8 @@ public enum EamDbPlatformEnum {
if (null != selectedPlatformString) {
selected = this.toString().equalsIgnoreCase(selectedPlatformString);
+ } else if (this == DISABLED) {
+ selected = true;
}
}
@@ -56,13 +59,13 @@ public enum EamDbPlatformEnum {
this.selected = selected;
}
- private Boolean isSelected() {
+ public Boolean isSelected() {
return selected;
}
public static EamDbPlatformEnum fromString(String pName) {
if (null == pName) {
- return SQLITE;
+ return DISABLED;
}
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
@@ -70,14 +73,14 @@ public enum EamDbPlatformEnum {
return p;
}
}
- return SQLITE;
+ return DISABLED;
}
/**
* Save the selected platform to the config file.
*/
public static void saveSelectedPlatform() {
- EamDbPlatformEnum selectedPlatform = SQLITE;
+ EamDbPlatformEnum selectedPlatform = DISABLED;
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
if (p.isSelected()) {
selectedPlatform = p;
@@ -103,7 +106,7 @@ public enum EamDbPlatformEnum {
* Get the selected platform.
*
* @return The selected platform, or if not platform is selected, default to
- * SQLITE.
+ * DISABLED.
*/
public static EamDbPlatformEnum getSelectedPlatform() {
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
@@ -111,6 +114,6 @@ public enum EamDbPlatformEnum {
return p;
}
}
- return SQLITE;
+ return DISABLED;
}
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java
new file mode 100644
index 0000000000..3d5dbe3d5c
--- /dev/null
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/EamDbUtil.java
@@ -0,0 +1,184 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import java.util.logging.Level;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import static org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb.SCHEMA_VERSION;
+
+/**
+ *
+ */
+public class EamDbUtil {
+ private final static Logger LOGGER = Logger.getLogger(EamDbUtil.class.getName());
+
+ /**
+ * Close the prepared statement.
+ *
+ * @param preparedStatement
+ *
+ * @throws EamDbException
+ */
+ public static void closePreparedStatement(PreparedStatement preparedStatement) {
+ if (null != preparedStatement) {
+ try {
+ preparedStatement.close();
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error closing PreparedStatement.", ex);
+ }
+ }
+ }
+
+ /**
+ * Close the resultSet.
+ *
+ * @param resultSet
+ *
+ * @throws EamDbException
+ */
+ public static void closeResultSet(ResultSet resultSet) {
+ if (null != resultSet) {
+ try {
+ resultSet.close();
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex);
+ }
+ }
+ }
+
+ /**
+ * Close the in-use connection and return it to the pool.
+ *
+ * @param conn An open connection
+ *
+ * @throws EamDbException
+ */
+ public static void closeConnection(Connection conn) {
+ if (null != conn) {
+ try {
+ conn.close();
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error closing Connection.", ex);
+ }
+ }
+ }
+
+ /**
+ * Insert the default artifact types into the database.
+ *
+ * @param conn Open connection to use.
+ * @return true on success, else false
+ */
+ public static boolean insertDefaultArtifactTypes(Connection conn) {
+ PreparedStatement preparedStatement = null;
+ List DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
+ String sql = "INSERT INTO artifact_types(name, supported, enabled) VALUES (?, ?, ?)";
+
+ try {
+ preparedStatement = conn.prepareStatement(sql);
+ for (EamArtifact.Type newType : DEFAULT_ARTIFACT_TYPES) {
+ preparedStatement.setString(1, newType.getName());
+ preparedStatement.setInt(2, newType.isSupported() ? 1 : 0);
+ preparedStatement.setInt(3, newType.isEnabled() ? 1 : 0);
+ preparedStatement.addBatch();
+ }
+ preparedStatement.executeBatch();
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error inserting default correlation artifact types.", ex); // NON-NLS
+ return false;
+ } finally {
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ }
+ return true;
+ }
+
+ /**
+ * Store the schema version into the db_info table.
+ *
+ * This should be called immediately following the database schema being
+ * loaded.
+ *
+ * @param conn Open connection to use.
+ * @return true on success, else false
+ */
+ public static boolean insertSchemaVersion(Connection conn) {
+ PreparedStatement preparedStatement = null;
+ String sql = "INSERT INTO db_info (name, value) VALUES (?, ?)";
+ try {
+ preparedStatement = conn.prepareStatement(sql);
+ preparedStatement.setString(1, "SCHEMA_VERSION");
+ preparedStatement.setString(2, String.valueOf(SCHEMA_VERSION));
+ preparedStatement.executeUpdate();
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error adding schema version to db_info.", ex);
+ return false;
+ } finally {
+ EamDbUtil.closePreparedStatement(preparedStatement);
+ }
+ return true;
+ }
+
+ /**
+ * Query to see if the SCHEMA_VERSION is set in the db.
+ *
+ * @return true if set, else false.
+ */
+ public static boolean schemaVersionIsSet(Connection conn) {
+ if (null == conn) {
+ return false;
+ }
+
+ ResultSet resultSet = null;
+ try {
+ Statement tester = conn.createStatement();
+ String sql = "SELECT value FROM db_info WHERE name='SCHEMA_VERSION'";
+ resultSet = tester.executeQuery(sql);
+ if (resultSet.next()) {
+ String value = resultSet.getString("value");
+ }
+ } catch (SQLException ex) {
+ return false;
+ } finally {
+ EamDbUtil.closeResultSet(resultSet);
+ }
+ return true;
+ }
+
+ /**
+ * Use the current settings and the validation query
+ * to test the connection to the database.
+ *
+ * @return true if successfull query execution, else false.
+ */
+ public static boolean executeValidationQuery(Connection conn, String validationQuery) {
+ if (null == conn) {
+ return false;
+ }
+
+ ResultSet resultSet = null;
+ try {
+ Statement tester = conn.createStatement();
+ resultSet = tester.executeQuery(validationQuery);
+ if (resultSet.next()) {
+ return true;
+ }
+ } catch (SQLException ex) {
+ return false;
+ } finally {
+ EamDbUtil.closeResultSet(resultSet);
+ }
+
+ return false;
+ }
+}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java
index 52f60b1950..0815d9997b 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDb.java
@@ -90,10 +90,10 @@ public class PostgresEamDb extends AbstractSqlEamDb {
} catch (SQLException ex) {
//LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
} finally {
- closeConnection(conn);
+ EamDbUtil.closeConnection(conn);
}
- insertDefaultContent();
+ dbSettings.insertDefaultDatabaseContent();
}
/**
@@ -113,12 +113,10 @@ public class PostgresEamDb extends AbstractSqlEamDb {
connectionURL.append(dbSettings.getPort());
connectionURL.append("/");
connectionURL.append(dbSettings.getDbName());
- connectionURL.append("?user=");
- connectionURL.append(dbSettings.getUserName());
- connectionURL.append("&password=");
- connectionURL.append(dbSettings.getPassword());
-
+
connectionPool.setUrl(connectionURL.toString());
+ connectionPool.setUsername(dbSettings.getUserName());
+ connectionPool.setPassword(dbSettings.getPassword());
// tweak pool configuration
connectionPool.setInitialSize(5); // start with 5 connections
@@ -126,175 +124,6 @@ public class PostgresEamDb extends AbstractSqlEamDb {
connectionPool.setValidationQuery(dbSettings.getValidationQuery());
}
- /**
- * Initialize the database schema.
- *
- * Requires valid connectionPool.
- *
- * This method is called from within connect(), so we cannot call connect()
- * to get a connection. This method is called after setupConnectionPool(),
- * so it is safe to assume that a valid connectionPool exists. The
- * implementation of connect() is synchronized, so we can safely use the
- * connectionPool object directly.
- */
- @Override
- protected void initializeDatabaseSchema() throws EamDbException {
- // The "id" column is an alias for the built-in 64-bit int "rowid" column.
- // It is autoincrementing by default and must be of type "integer primary key".
- // We've omitted the autoincrement argument because we are not currently
- // using the id value to search for specific rows, so we do not care
- // if a rowid is re-used after an existing rows was previously deleted.
- StringBuilder createOrganizationsTable = new StringBuilder();
- createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
- createOrganizationsTable.append("id SERIAL PRIMARY KEY,");
- createOrganizationsTable.append("org_name text NOT NULL,");
- createOrganizationsTable.append("poc_name text NOT NULL,");
- createOrganizationsTable.append("poc_email text NOT NULL,");
- createOrganizationsTable.append("poc_phone text NOT NULL");
- createOrganizationsTable.append(")");
-
- // NOTE: The organizations will only have a small number of rows, so
- // an index is probably not worthwhile.
-
- StringBuilder createCasesTable = new StringBuilder();
- createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
- createCasesTable.append("id SERIAL PRIMARY KEY,");
- createCasesTable.append("case_uid text NOT NULL,");
- createCasesTable.append("org_id integer,");
- createCasesTable.append("case_name text NOT NULL,");
- createCasesTable.append("creation_date text NOT NULL,");
- createCasesTable.append("case_number text NOT NULL,");
- createCasesTable.append("examiner_name text NOT NULL,");
- createCasesTable.append("examiner_email text NOT NULL,");
- createCasesTable.append("examiner_phone text NOT NULL,");
- createCasesTable.append("notes text NOT NULL,");
- createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
- createCasesTable.append(")");
-
- // NOTE: when there are few cases in the cases table, these indices may not be worthwhile
- String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
- String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
-
- StringBuilder createDataSourcesTable = new StringBuilder();
- createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
- createDataSourcesTable.append("id SERIAL PRIMARY KEY,");
- createDataSourcesTable.append("device_id text NOT NULL,");
- createDataSourcesTable.append("name text NOT NULL,");
- createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE (device_id)");
- createDataSourcesTable.append(")");
-
- String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
-
- StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
- createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
- createGlobalReferenceSetsTable.append("id SERIAL PRIMARY KEY,");
- createGlobalReferenceSetsTable.append("org_id integer,");
- createGlobalReferenceSetsTable.append("set_name text NOT NULL,");
- createGlobalReferenceSetsTable.append("version text NOT NULL,");
- createGlobalReferenceSetsTable.append("import_date text NOT NULL,");
- createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
- createGlobalReferenceSetsTable.append(")");
-
- String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
-
- StringBuilder createGlobalFilesTable = new StringBuilder();
- createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
- createGlobalFilesTable.append("id SERIAL PRIMARY KEY,");
- createGlobalFilesTable.append("global_reference_set_id integer,");
- createGlobalFilesTable.append("value text NOT NULL,");
- createGlobalFilesTable.append("known_status text NOT NULL,");
- createGlobalFilesTable.append("comment text NOT NULL,");
- createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE (global_reference_set_id,value),");
- createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
- createGlobalFilesTable.append(")");
-
- String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
- String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
-
- StringBuilder createArtifactTypesTable = new StringBuilder();
- createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
- createArtifactTypesTable.append("id SERIAL PRIMARY KEY,");
- createArtifactTypesTable.append("name text NOT NULL,");
- createArtifactTypesTable.append("supported integer NOT NULL,");
- createArtifactTypesTable.append("enabled integer NOT NULL,");
- createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
- createArtifactTypesTable.append(")");
-
- // NOTE: there are API methods that query by one of: name, supported, or enabled.
- // Only name is currently implemented, but, there will only be a small number
- // of artifact_types, so there is no benefit to having any indices.
- StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
- createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
- createArtifactInstancesTableTemplate.append("id SERIAL PRIMARY KEY,");
- createArtifactInstancesTableTemplate.append("case_id integer,");
- createArtifactInstancesTableTemplate.append("data_source_id integer,");
- createArtifactInstancesTableTemplate.append("value text NOT NULL,");
- createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
- createArtifactInstancesTableTemplate.append("known_status text NOT NULL,");
- createArtifactInstancesTableTemplate.append("comment text NOT NULL,");
- createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique_ UNIQUE (case_id, data_source_id, value, file_path),");
- createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
- createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
- createArtifactInstancesTableTemplate.append(")");
-
- // TODO: do we need any more indices?
- String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
- String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
- String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
- String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
-
- StringBuilder createDbInfoTable = new StringBuilder();
- createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
- createDbInfoTable.append("id SERIAL PRIMARY KEY NOT NULL,");
- createDbInfoTable.append("name text NOT NULL,");
- createDbInfoTable.append("value text NOT NULL");
- createDbInfoTable.append(")");
-
- // NOTE: the db_info table currenly only has 1 row, so having an index
- // provides no benefit.
-
- Connection conn = null;
- try {
- conn = connectionPool.getConnection();
- Statement stmt = conn.createStatement();
-
- stmt.execute(createOrganizationsTable.toString());
-
- stmt.execute(createCasesTable.toString());
- stmt.execute(casesIdx1);
- stmt.execute(casesIdx2);
-
- stmt.execute(createDataSourcesTable.toString());
- stmt.execute(dataSourceIdx1);
-
- stmt.execute(createGlobalReferenceSetsTable.toString());
- stmt.execute(globalReferenceSetsIdx1);
-
- stmt.execute(createGlobalFilesTable.toString());
- stmt.execute(globalFilesIdx1);
- stmt.execute(globalFilesIdx2);
-
- stmt.execute(createArtifactTypesTable.toString());
-
- stmt.execute(createDbInfoTable.toString());
-
- // Create a separate table for each artifact type
- String type_name;
- for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
- type_name = type.getName();
- stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
- stmt.execute(String.format(instancesIdx1, type_name, type_name));
- stmt.execute(String.format(instancesIdx2, type_name, type_name));
- stmt.execute(String.format(instancesIdx3, type_name, type_name));
- stmt.execute(String.format(instancesIdx4, type_name, type_name));
- }
- } catch (SQLException ex) {
- throw new EamDbException("Error initializing db schema.", ex); // NON-NLS
- } finally {
- closeConnection(conn);
- }
- }
-
/**
* Lazily setup Singleton connection on first request.
*
@@ -305,13 +134,12 @@ public class PostgresEamDb extends AbstractSqlEamDb {
@Override
protected Connection connect() throws EamDbException {
synchronized (this) {
- if (!dbSettings.isEnabled()) {
+ if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS
}
if (connectionPool == null) {
setupConnectionPool();
- confirmDatabaseSchema();
}
}
@@ -322,11 +150,6 @@ public class PostgresEamDb extends AbstractSqlEamDb {
}
}
- @Override
- public boolean isEnabled() {
- return dbSettings.isEnabled();
- }
-
@Override
public List getBadTags() {
return dbSettings.getBadTags();
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java
index 7b08740354..58d99981a6 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/PostgresEamDbSettings.java
@@ -20,15 +20,20 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Properties;
import java.util.logging.Level;
+import java.util.regex.Pattern;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
+import org.sleuthkit.autopsy.coreutils.TextConverter;
+import org.sleuthkit.autopsy.coreutils.TextConverterException;
/**
* Settings for the Postgres implementation of the enterprise artifacts manager
@@ -39,7 +44,7 @@ public final class PostgresEamDbSettings {
private final static Logger LOGGER = Logger.getLogger(PostgresEamDbSettings.class.getName());
private final String DEFAULT_HOST = "localhost"; // NON-NLS
private final int DEFAULT_PORT = 5432;
- private final String DEFAULT_DBNAME = "enterpriseartifactmanagerdb"; // NON-NLS
+ private final String DEFAULT_DBNAME = "enterpriseartifacts"; // NON-NLS
private final int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_USERNAME = "";
private final String DEFAULT_PASSWORD = "";
@@ -47,8 +52,8 @@ public final class PostgresEamDbSettings {
private final String VALIDATION_QUERY = "SELECT version()"; // NON-NLS
private final String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS
private final String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS
-
- private boolean enabled;
+ private final String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case
+ private final String DB_USER_NAMES_REGEX = "[a-zA-Z]\\w*";
private String host;
private int port;
private String dbName;
@@ -62,8 +67,6 @@ public final class PostgresEamDbSettings {
}
public void loadSettings() {
- enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS
-
host = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS
if (host == null || host.isEmpty()) {
host = DEFAULT_HOST;
@@ -110,6 +113,13 @@ public final class PostgresEamDbSettings {
password = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.password"); // NON-NLS
if (password == null || password.isEmpty()) {
password = DEFAULT_PASSWORD;
+ } else {
+ try {
+ password = TextConverter.convertHexTextToText(password);
+ } catch (TextConverterException ex) {
+ LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex);
+ password = DEFAULT_PASSWORD;
+ }
}
String badTagsStr = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.badTags"); // NON-NLS
@@ -120,69 +130,338 @@ public final class PostgresEamDbSettings {
}
public void saveSettings() {
- ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host", getHost()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port", Integer.toString(port)); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.user", getUserName()); // NON-NLS
- ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.password", getPassword()); // NON-NLS
+ try {
+ ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.password", TextConverter.convertTextToHexText(getPassword())); // NON-NLS
+ } catch (TextConverterException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to convert password from text to hex text.", ex);
+ }
+
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.badTags", String.join(",", badTags)); // NON-NLS
}
/**
* Get the full connection URL as a String
*
+ * @param usePostgresDb Connect to the 'postgres' database when testing
+ * connectivity and creating the main database.
+ *
* @return
*/
- public String getConnectionURL() {
+ public String getConnectionURL(boolean usePostgresDb) {
StringBuilder url = new StringBuilder();
url.append(getJDBCBaseURI());
url.append(getHost());
url.append("/"); // NON-NLS
- url.append(getDbName());
- url.append("?user="); // NON-NLS
- url.append(getUserName());
- url.append("&password="); // NON-NLS
- url.append(getPassword());
+ if (usePostgresDb) {
+ url.append("postgres"); // NON-NLS
+ } else {
+ url.append(getDbName());
+ }
return url.toString();
}
- public boolean testSettings() {
- // Open a new ephemeral client here to test that we can connect
- ResultSet resultSet = null;
- Connection conn = null;
+ /**
+ * Use the current settings to get an ephemeral client connection for testing.
+ *
+ * @return Connection or null.
+ */
+ private Connection getEphemeralConnection(boolean usePostgresDb) {
+ Connection conn;
try {
- String url = getConnectionURL();
+ String url = getConnectionURL(usePostgresDb);
+ Properties props = new Properties();
+ props.setProperty("user", getUserName());
+ props.setProperty("password", getPassword());
+
Class.forName(getDriver());
- conn = DriverManager.getConnection(url);
- Statement tester = conn.createStatement();
- resultSet = tester.executeQuery(getValidationQuery());
- if (resultSet.next()) {
- LOGGER.log(Level.INFO, "Testing connection to postgresql success."); // NON-NLS
- }
+ conn = DriverManager.getConnection(url, props);
} catch (ClassNotFoundException | SQLException ex) {
- LOGGER.log(Level.INFO, "Testing connection to postgresql failed.", ex); // NON-NLS
+ // TODO: Determine why a connection failure (ConnectionException) re-throws
+ // the SQLException and does not print this log message?
+ LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to postgresql."); // NON-NLS
+ conn = null;
+ }
+ return conn;
+ }
+
+ /**
+ * Use the current settings and the validation query
+ * to test the connection to the database.
+ *
+ * @return true if successfull connection, else false.
+ */
+ public boolean verifyConnection() {
+ Connection conn = getEphemeralConnection(true);
+ if (null == conn) {
+ return false;
+ }
+
+ boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
+ EamDbUtil.closeConnection(conn);
+ return result;
+ }
+
+ /**
+ * Check to see if the database exists.
+ *
+ * @return true if exists, else false
+ */
+ public boolean verifyDatabaseExists() {
+ Connection conn = getEphemeralConnection(true);
+ if (null == conn) {
return false;
- } finally {
- if (null != resultSet) {
- try {
- resultSet.close();
- } catch (SQLException ex) {
- LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex); // NON-NLS
- }
- }
- if (null != conn) {
- try {
- conn.close();
- } catch (SQLException ex) {
- LOGGER.log(Level.SEVERE, "Error closing test connection.", ex); // NON-NLS
- }
- }
}
+ String sql = "SELECT datname FROM pg_catalog.pg_database WHERE lower(datname) = lower(?) LIMIT 1"; // NON-NLS
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, getDbName());
+ rs = ps.executeQuery();
+ if (rs.next()) {
+ return true;
+ }
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to execute database existance query.", ex); // NON-NLS
+ return false;
+ } finally {
+ EamDbUtil.closePreparedStatement(ps);
+ EamDbUtil.closeResultSet(rs);
+ EamDbUtil.closeConnection(conn);
+ }
+ return false;
+ }
+
+ /**
+ * Use the current settings and the schema version query
+ * to test the database schema.
+ *
+ * @return true if successfull connection, else false.
+ */
+ public boolean verifyDatabaseSchema() {
+ Connection conn = getEphemeralConnection(false);
+ if (null == conn) {
+ return false;
+ }
+
+ boolean result = EamDbUtil.schemaVersionIsSet(conn);
+
+ EamDbUtil.closeConnection(conn);
+ return result;
+ }
+
+ public boolean createDatabase() {
+ Connection conn = getEphemeralConnection(true);
+ if (null == conn) {
+ return false;
+ }
+
+ String sql = "CREATE DATABASE %s OWNER %s"; // NON-NLS
+ try {
+ Statement stmt;
+ stmt = conn.createStatement();
+ stmt.execute(String.format(sql, getDbName(), getUserName()));
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to execute create database statement.", ex); // NON-NLS
+ return false;
+ } finally {
+ EamDbUtil.closeConnection(conn);
+ }
return true;
+
+ }
+ /**
+ * Initialize the database schema.
+ *
+ * Requires valid connectionPool.
+ *
+ * This method is called from within connect(), so we cannot call connect()
+ * to get a connection. This method is called after setupConnectionPool(),
+ * so it is safe to assume that a valid connectionPool exists. The
+ * implementation of connect() is synchronized, so we can safely use the
+ * connectionPool object directly.
+ */
+ public boolean initializeDatabaseSchema() {
+ // The "id" column is an alias for the built-in 64-bit int "rowid" column.
+ // It is autoincrementing by default and must be of type "integer primary key".
+ // We've omitted the autoincrement argument because we are not currently
+ // using the id value to search for specific rows, so we do not care
+ // if a rowid is re-used after an existing rows was previously deleted.
+ StringBuilder createOrganizationsTable = new StringBuilder();
+ createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
+ createOrganizationsTable.append("id SERIAL PRIMARY KEY,");
+ createOrganizationsTable.append("org_name text NOT NULL,");
+ createOrganizationsTable.append("poc_name text NOT NULL,");
+ createOrganizationsTable.append("poc_email text NOT NULL,");
+ createOrganizationsTable.append("poc_phone text NOT NULL");
+ createOrganizationsTable.append(")");
+
+ // NOTE: The organizations will only have a small number of rows, so
+ // an index is probably not worthwhile.
+
+ StringBuilder createCasesTable = new StringBuilder();
+ createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
+ createCasesTable.append("id SERIAL PRIMARY KEY,");
+ createCasesTable.append("case_uid text NOT NULL,");
+ createCasesTable.append("org_id integer,");
+ createCasesTable.append("case_name text NOT NULL,");
+ createCasesTable.append("creation_date text NOT NULL,");
+ createCasesTable.append("case_number text NOT NULL,");
+ createCasesTable.append("examiner_name text NOT NULL,");
+ createCasesTable.append("examiner_email text NOT NULL,");
+ createCasesTable.append("examiner_phone text NOT NULL,");
+ createCasesTable.append("notes text NOT NULL,");
+ createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
+ createCasesTable.append(")");
+
+ // NOTE: when there are few cases in the cases table, these indices may not be worthwhile
+ String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
+ String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
+
+ StringBuilder createDataSourcesTable = new StringBuilder();
+ createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
+ createDataSourcesTable.append("id SERIAL PRIMARY KEY,");
+ createDataSourcesTable.append("device_id text NOT NULL,");
+ createDataSourcesTable.append("name text NOT NULL,");
+ createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE (device_id)");
+ createDataSourcesTable.append(")");
+
+ String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
+
+ StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
+ createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
+ createGlobalReferenceSetsTable.append("id SERIAL PRIMARY KEY,");
+ createGlobalReferenceSetsTable.append("org_id integer,");
+ createGlobalReferenceSetsTable.append("set_name text NOT NULL,");
+ createGlobalReferenceSetsTable.append("version text NOT NULL,");
+ createGlobalReferenceSetsTable.append("import_date text NOT NULL,");
+ createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
+ createGlobalReferenceSetsTable.append(")");
+
+ String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
+
+ StringBuilder createGlobalFilesTable = new StringBuilder();
+ createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
+ createGlobalFilesTable.append("id SERIAL PRIMARY KEY,");
+ createGlobalFilesTable.append("global_reference_set_id integer,");
+ createGlobalFilesTable.append("value text NOT NULL,");
+ createGlobalFilesTable.append("known_status text NOT NULL,");
+ createGlobalFilesTable.append("comment text NOT NULL,");
+ createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE (global_reference_set_id,value),");
+ createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
+ createGlobalFilesTable.append(")");
+
+ String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
+ String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
+
+ StringBuilder createArtifactTypesTable = new StringBuilder();
+ createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
+ createArtifactTypesTable.append("id SERIAL PRIMARY KEY,");
+ createArtifactTypesTable.append("name text NOT NULL,");
+ createArtifactTypesTable.append("supported integer NOT NULL,");
+ createArtifactTypesTable.append("enabled integer NOT NULL,");
+ createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
+ createArtifactTypesTable.append(")");
+
+ // NOTE: there are API methods that query by one of: name, supported, or enabled.
+ // Only name is currently implemented, but, there will only be a small number
+ // of artifact_types, so there is no benefit to having any indices.
+ StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
+ createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
+ createArtifactInstancesTableTemplate.append("id SERIAL PRIMARY KEY,");
+ createArtifactInstancesTableTemplate.append("case_id integer,");
+ createArtifactInstancesTableTemplate.append("data_source_id integer,");
+ createArtifactInstancesTableTemplate.append("value text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("known_status text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("comment text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique_ UNIQUE (case_id, data_source_id, value, file_path),");
+ createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
+ createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
+ createArtifactInstancesTableTemplate.append(")");
+
+ // TODO: do we need any more indices?
+ String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
+ String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
+ String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
+ String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
+
+ StringBuilder createDbInfoTable = new StringBuilder();
+ createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
+ createDbInfoTable.append("id SERIAL PRIMARY KEY NOT NULL,");
+ createDbInfoTable.append("name text NOT NULL,");
+ createDbInfoTable.append("value text NOT NULL");
+ createDbInfoTable.append(")");
+
+ // NOTE: the db_info table currenly only has 1 row, so having an index
+ // provides no benefit.
+
+ Connection conn = null;
+ try {
+ conn = getEphemeralConnection(false);
+ if (null == conn) {
+ return false;
+ }
+ Statement stmt = conn.createStatement();
+
+ stmt.execute(createOrganizationsTable.toString());
+
+ stmt.execute(createCasesTable.toString());
+ stmt.execute(casesIdx1);
+ stmt.execute(casesIdx2);
+
+ stmt.execute(createDataSourcesTable.toString());
+ stmt.execute(dataSourceIdx1);
+
+ stmt.execute(createGlobalReferenceSetsTable.toString());
+ stmt.execute(globalReferenceSetsIdx1);
+
+ stmt.execute(createGlobalFilesTable.toString());
+ stmt.execute(globalFilesIdx1);
+ stmt.execute(globalFilesIdx2);
+
+ stmt.execute(createArtifactTypesTable.toString());
+
+ stmt.execute(createDbInfoTable.toString());
+
+ // Create a separate table for each artifact type
+ List DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
+ String type_name;
+ for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
+ type_name = type.getName();
+ stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
+ stmt.execute(String.format(instancesIdx1, type_name, type_name));
+ stmt.execute(String.format(instancesIdx2, type_name, type_name));
+ stmt.execute(String.format(instancesIdx3, type_name, type_name));
+ stmt.execute(String.format(instancesIdx4, type_name, type_name));
+ }
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
+ return false;
+ } finally {
+ EamDbUtil.closeConnection(conn);
+ }
+ return true;
+ }
+
+ public boolean insertDefaultDatabaseContent() {
+ Connection conn = getEphemeralConnection(false);
+ if (null == conn) {
+ return false;
+ }
+
+ boolean result = EamDbUtil.insertDefaultArtifactTypes(conn)
+ && EamDbUtil.insertSchemaVersion(conn);
+ EamDbUtil.closeConnection(conn);
+
+ return result;
}
public boolean isChanged() {
@@ -198,20 +477,6 @@ public final class PostgresEamDbSettings {
|| !userName.equals(userNameString) || !password.equals(userPasswordString);
}
- /**
- * @return the enabled
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * @param enabled the enabled to set
- */
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
/**
* @return the host
*/
@@ -226,7 +491,7 @@ public final class PostgresEamDbSettings {
if (null != host && !host.isEmpty()) {
this.host = host;
} else {
- throw new EamDbException("Error invalid host for database connection. Cannot be null or empty."); // NON-NLS
+ throw new EamDbException("Invalid host name. Cannot be empty."); // NON-NLS
}
}
@@ -244,27 +509,31 @@ public final class PostgresEamDbSettings {
if (port > 0 && port < 65535) {
this.port = port;
} else {
- throw new EamDbException("Error invalid port for database connection."); // NON-NLS
+ throw new EamDbException("Invalid port. Must be a number greater than 0."); // NON-NLS
}
}
/**
+ * To prevent issues where one command can honor case and another cannot,
+ * we will force the dbname to lower case.
+ *
* @return the dbName
*/
public String getDbName() {
- return dbName;
+ return dbName.toLowerCase();
}
/**
* @param dbName the dbName to set
*/
public void setDbName(String dbName) throws EamDbException {
- if (dbName != null && !dbName.isEmpty()) {
- this.dbName = dbName;
- } else {
- throw new EamDbException("Error invalid name for database connection. Cannot be null or empty."); // NON-NLS
-
+ if (dbName == null || dbName.isEmpty()) {
+ throw new EamDbException("Invalid database name. Cannot be empty."); // NON-NLS
+ } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
+ throw new EamDbException("Invalid database name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS
}
+
+ this.dbName = dbName.toLowerCase();
}
/**
@@ -281,7 +550,7 @@ public final class PostgresEamDbSettings {
if (bulkThreshold > 0) {
this.bulkThreshold = bulkThreshold;
} else {
- throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS
+ throw new EamDbException("Invalid bulk threshold for database connection."); // NON-NLS
}
}
@@ -296,11 +565,12 @@ public final class PostgresEamDbSettings {
* @param userName the userName to set
*/
public void setUserName(String userName) throws EamDbException {
- if (userName != null && !userName.isEmpty()) {
- this.userName = userName;
- } else {
- throw new EamDbException("Error invalid user name for database connection. Cannot be null or empty."); // NON-NLS
+ if (userName == null || userName.isEmpty()) {
+ throw new EamDbException("Invalid user name. Cannot be empty."); // NON-NLS
+ } else if (!Pattern.matches(DB_USER_NAMES_REGEX, userName)) {
+ throw new EamDbException("Invalid user name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS
}
+ this.userName = userName;
}
/**
@@ -314,11 +584,10 @@ public final class PostgresEamDbSettings {
* @param password the password to set
*/
public void setPassword(String password) throws EamDbException {
- if (password != null && !password.isEmpty()) {
- this.password = password;
- } else {
- throw new EamDbException("Error invalid user password for database connection. Cannot be null or empty."); // NON-NLS
+ if (password == null || password.isEmpty()) {
+ throw new EamDbException("Invalid user password. Cannot be empty."); // NON-NLS
}
+ this.password = password;
}
/**
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java
index 3e43ca97c1..e720955308 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDb.java
@@ -19,8 +19,6 @@
package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
@@ -38,13 +36,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
private static SqliteEamDb instance;
- protected static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF";
- protected static final String PRAGMA_SYNC_NORMAL = "PRAGMA synchronous = NORMAL";
- private static final String PRAGMA_JOURNAL_WAL = "PRAGMA journal_mode = WAL";
- private static final String PRAGMA_READ_UNCOMMITTED_TRUE = "PRAGMA read_uncommitted = True";
- private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'";
- private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096";
- private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON";
private BasicDataSource connectionPool = null;
private final SqliteEamDbSettings dbSettings;
@@ -97,12 +88,12 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
dropContent.executeUpdate("VACUUM");
- insertDefaultContent();
+ dbSettings.insertDefaultDatabaseContent();
} catch (SQLException ex) {
LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
} finally {
- closeConnection(conn);
+ EamDbUtil.closeConnection(conn);
}
}
@@ -130,202 +121,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
connectionPool.setValidationQuery(dbSettings.getValidationQuery());
}
- /**
- * Verify the EAM db directory exists. If it doesn't, then create it.
- *
- * @throws EamDbException
- */
- private void verifyDBDirectory() throws EamDbException {
- File dbDir = new File(dbSettings.getDbDirectory());
- if (!dbDir.exists()) {
- LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", dbSettings.getDbDirectory()); // NON-NLS
- try {
- Files.createDirectories(dbDir.toPath());
- } catch (IOException ex) {
- throw new EamDbException("Failed to create sqlite database directory. ", ex); // NON-NLS
- }
- } else if (dbDir.exists() && !dbDir.isDirectory()) {
- LOGGER.log(Level.INFO, "Failed to create sqlite database directory. Path already exists and is not a directory: {0}", dbSettings.getDbDirectory()); // NON-NLS
- }
-
- }
-
- /**
- * Initialize the database schema.
- *
- * Requires valid connectionPool.
- *
- * This method is called from within connect(), so we cannot call connect()
- * to get a connection. This method is called after setupConnectionPool(),
- * so it is safe to assume that a valid connectionPool exists. The
- * implementation of connect() is synchronized, so we can safely use the
- * connectionPool object directly.
- */
- @Override
- protected void initializeDatabaseSchema() throws EamDbException {
- // The "id" column is an alias for the built-in 64-bit int "rowid" column.
- // It is autoincrementing by default and must be of type "integer primary key".
- // We've omitted the autoincrement argument because we are not currently
- // using the id value to search for specific rows, so we do not care
- // if a rowid is re-used after an existing rows was previously deleted.
- StringBuilder createOrganizationsTable = new StringBuilder();
- createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
- createOrganizationsTable.append("id integer primary key autoincrement NOT NULL,");
- createOrganizationsTable.append("org_name text NOT NULL,");
- createOrganizationsTable.append("poc_name text NOT NULL,");
- createOrganizationsTable.append("poc_email text NOT NULL,");
- createOrganizationsTable.append("poc_phone text NOT NULL");
- createOrganizationsTable.append(")");
-
- // NOTE: The organizations will only have a small number of rows, so
- // an index is probably not worthwhile.
-
- StringBuilder createCasesTable = new StringBuilder();
- createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
- createCasesTable.append("id integer primary key autoincrement NOT NULL,");
- createCasesTable.append("case_uid text NOT NULL,");
- createCasesTable.append("org_id integer,");
- createCasesTable.append("case_name text NOT NULL,");
- createCasesTable.append("creation_date text NOT NULL,");
- createCasesTable.append("case_number text NOT NULL,");
- createCasesTable.append("examiner_name text NOT NULL,");
- createCasesTable.append("examiner_email text NOT NULL,");
- createCasesTable.append("examiner_phone text NOT NULL,");
- createCasesTable.append("notes text NOT NULL,");
- createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null,");
- createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE(case_uid)");
- createCasesTable.append(")");
-
- // NOTE: when there are few cases in the cases table, these indices may not be worthwhile
- String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
- String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
-
- StringBuilder createDataSourcesTable = new StringBuilder();
- createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
- createDataSourcesTable.append("id integer primary key autoincrement NOT NULL,");
- createDataSourcesTable.append("device_id text NOT NULL,");
- createDataSourcesTable.append("name text NOT NULL,");
- createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE(device_id)");
- createDataSourcesTable.append(")");
-
- String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
-
- StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
- createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
- createGlobalReferenceSetsTable.append("id integer primary key autoincrement NOT NULL,");
- createGlobalReferenceSetsTable.append("org_id integer,");
- createGlobalReferenceSetsTable.append("set_name text NOT NULL,");
- createGlobalReferenceSetsTable.append("version text NOT NULL,");
- createGlobalReferenceSetsTable.append("import_date text NOT NULL,");
- createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
- createGlobalReferenceSetsTable.append(")");
-
- String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
-
- StringBuilder createGlobalFilesTable = new StringBuilder();
- createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
- createGlobalFilesTable.append("id integer primary key autoincrement NOT NULL,");
- createGlobalFilesTable.append("global_reference_set_id integer,");
- createGlobalFilesTable.append("value text NOT NULL,");
- createGlobalFilesTable.append("known_status text NOT NULL,");
- createGlobalFilesTable.append("comment text NOT NULL,");
- createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE(global_reference_set_id, value)");
- createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
- createGlobalFilesTable.append(")");
-
- String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
- String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
-
- StringBuilder createArtifactTypesTable = new StringBuilder();
- createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
- createArtifactTypesTable.append("id integer primary key autoincrement NOT NULL,");
- createArtifactTypesTable.append("name text NOT NULL,");
- createArtifactTypesTable.append("supported integer NOT NULL,");
- createArtifactTypesTable.append("enabled integer NOT NULL,");
- createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
- createArtifactTypesTable.append(")");
-
- // NOTE: there are API methods that query by one of: name, supported, or enabled.
- // Only name is currently implemented, but, there will only be a small number
- // of artifact_types, so there is no benefit to having any indices.
- StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
- createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
- createArtifactInstancesTableTemplate.append("id integer primary key autoincrement NOT NULL,");
- createArtifactInstancesTableTemplate.append("case_id integer,");
- createArtifactInstancesTableTemplate.append("data_source_id integer,");
- createArtifactInstancesTableTemplate.append("value text NOT NULL,");
- createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
- createArtifactInstancesTableTemplate.append("known_status text NOT NULL,");
- createArtifactInstancesTableTemplate.append("comment text NOT NULL,");
- createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique UNIQUE(case_id, data_source_id, value, file_path),");
- createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
- createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
- createArtifactInstancesTableTemplate.append(")");
-
- // TODO: do we need any more indices?
- String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
- String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
- String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
- String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
-
- StringBuilder createDbInfoTable = new StringBuilder();
- createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
- createDbInfoTable.append("id integer primary key NOT NULL,");
- createDbInfoTable.append("name text NOT NULL,");
- createDbInfoTable.append("value text NOT NULL");
- createDbInfoTable.append(")");
-
- // NOTE: the db_info table currenly only has 1 row, so having an index
- // provides no benefit.
-
- Connection conn = null;
- try {
- conn = connectionPool.getConnection();
- Statement stmt = conn.createStatement();
- stmt.execute(PRAGMA_JOURNAL_WAL);
- stmt.execute(PRAGMA_SYNC_OFF);
- stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE);
- stmt.execute(PRAGMA_ENCODING_UTF8);
- stmt.execute(PRAGMA_PAGE_SIZE_4096);
- stmt.execute(PRAGMA_FOREIGN_KEYS_ON);
-
- stmt.execute(createOrganizationsTable.toString());
-
- stmt.execute(createCasesTable.toString());
- stmt.execute(casesIdx1);
- stmt.execute(casesIdx2);
-
- stmt.execute(createDataSourcesTable.toString());
- stmt.execute(dataSourceIdx1);
-
- stmt.execute(createGlobalReferenceSetsTable.toString());
- stmt.execute(globalReferenceSetsIdx1);
-
- stmt.execute(createGlobalFilesTable.toString());
- stmt.execute(globalFilesIdx1);
- stmt.execute(globalFilesIdx2);
-
- stmt.execute(createArtifactTypesTable.toString());
-
- stmt.execute(createDbInfoTable.toString());
-
- // Create a separate table for each artifact type
- String type_name;
- for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
- type_name = type.getName();
- stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
- stmt.execute(String.format(instancesIdx1, type_name, type_name));
- stmt.execute(String.format(instancesIdx2, type_name, type_name));
- stmt.execute(String.format(instancesIdx3, type_name, type_name));
- stmt.execute(String.format(instancesIdx4, type_name, type_name));
- }
- } catch (SQLException ex) {
- throw new EamDbException("Error initializing db schema.", ex); // NON-NLS
- } finally {
- closeConnection(conn);
- }
- }
-
/**
* Lazily setup Singleton connection on first request.
*
@@ -336,14 +131,12 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override
protected Connection connect() throws EamDbException {
synchronized (this) {
- if (!dbSettings.isEnabled()) {
+ if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS
}
if (connectionPool == null) {
- verifyDBDirectory();
setupConnectionPool();
- confirmDatabaseSchema();
}
try {
@@ -354,11 +147,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
}
}
- @Override
- public boolean isEnabled() {
- return dbSettings.isEnabled();
- }
-
@Override
public List getBadTags() {
return dbSettings.getBadTags();
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java
index ede8e04d51..742863ab33 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/datamodel/SqliteEamDbSettings.java
@@ -23,13 +23,13 @@ import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.DriverManager;
-import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
+import java.util.regex.Pattern;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
@@ -41,14 +41,20 @@ public final class SqliteEamDbSettings {
private final static Logger LOGGER = Logger.getLogger(SqliteEamDbSettings.class.getName());
private final String DEFAULT_DBNAME = "EnterpriseArtifacts.db"; // NON-NLS
- private final String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "Autopsy" + File.separator + "eamdb"; // NON-NLS
+ private final String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "enterprise_artifacts_manager"; // NON-NLS
private final int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_BAD_TAGS = "Evidence"; // NON-NLS
private final String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS
private final String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS
private final String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS
-
- private boolean enabled;
+ private static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF";
+ private static final String PRAGMA_SYNC_NORMAL = "PRAGMA synchronous = NORMAL";
+ private static final String PRAGMA_JOURNAL_WAL = "PRAGMA journal_mode = WAL";
+ private static final String PRAGMA_READ_UNCOMMITTED_TRUE = "PRAGMA read_uncommitted = True";
+ private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'";
+ private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096";
+ private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON";
+ private final String DB_NAMES_REGEX = "[a-zA-Z]\\w*(\\.db)?";
private String dbName;
private String dbDirectory;
private int bulkThreshold;
@@ -59,8 +65,6 @@ public final class SqliteEamDbSettings {
}
public void loadSettings() {
- enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS
-
dbName = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS
if (dbName == null || dbName.isEmpty()) {
dbName = DEFAULT_DBNAME;
@@ -93,29 +97,48 @@ public final class SqliteEamDbSettings {
}
public void saveSettings() {
- createAndVerifyDirectory();
+ createDbDirectory();
- ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory", getDbDirectory()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.badTags", String.join(",", badTags)); // NON-NLS
}
- public boolean createAndVerifyDirectory() {
+ /**
+ * Verify that the db directory path exists.
+ *
+ * @return true if exists, else false
+ */
+ public boolean dbDirectoryExists() {
// Ensure dbDirectory is a valid directory
File dbDir = new File(getDbDirectory());
+
if (!dbDir.exists()) {
- LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", getDbDirectory()); // NON-NLS
+ return false;
+ } else if (!dbDir.isDirectory()) {
+ return false;
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Create the db directory if it does not exist.
+ *
+ * @return true is successfully created or already exists, else false
+ */
+ public boolean createDbDirectory() {
+ if (!dbDirectoryExists()) {
try {
+ File dbDir = new File(getDbDirectory());
Files.createDirectories(dbDir.toPath());
+ LOGGER.log(Level.INFO, "sqlite directory did not exist, created it at {0}.", getDbDirectory()); // NON-NLS
} catch (IOException ex) {
- LOGGER.log(Level.INFO, "Failed to create sqlite database directory.", ex); // NON-NLS
+ LOGGER.log(Level.SEVERE, "Failed to create sqlite database directory.", ex); // NON-NLS
return false;
}
- } else if (dbDir.exists() && !dbDir.isDirectory()) {
- LOGGER.log(Level.INFO, "Failed to create sqlite database directory. Path already exists and is not a directory."); // NON-NLS
- return false;
}
return true;
@@ -134,46 +157,258 @@ public final class SqliteEamDbSettings {
return url.toString();
}
- public boolean testSettings() {
- if (!createAndVerifyDirectory()) {
- return false;
+ /**
+ * Use the current settings to get an ephemeral client connection for testing.
+ *
+ * If the directory path does not exist, it will return null.
+ *
+ * @return Connection or null.
+ */
+ private Connection getEphemeralConnection() {
+ if (!dbDirectoryExists()) {
+ return null;
}
- // Open a new ephemeral client here to test that we can connect
- ResultSet resultSet = null;
- Connection conn = null;
+ Connection conn;
try {
String url = getConnectionURL();
Class.forName(getDriver());
conn = DriverManager.getConnection(url);
- Statement tester = conn.createStatement();
- resultSet = tester.executeQuery(getValidationQuery());
- if (resultSet.next()) {
- LOGGER.log(Level.INFO, "Testing connection to sqlite success."); // NON-NLS
- }
} catch (ClassNotFoundException | SQLException ex) {
- LOGGER.log(Level.INFO, "Testing connection to sqlite failed.", ex); // NON-NLS
+ LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to sqlite.", ex); // NON-NLS
+ conn = null;
+ }
+ return conn;
+ }
+
+ /**
+ * Use the current settings and the validation query
+ * to test the connection to the database.
+ *
+ * @return true if successfull connection, else false.
+ */
+ public boolean verifyConnection() {
+ Connection conn = getEphemeralConnection();
+ if (null == conn) {
+ return false;
+ }
+
+ boolean result = EamDbUtil.executeValidationQuery(conn, VALIDATION_QUERY);
+ EamDbUtil.closeConnection(conn);
+ return result;
+ }
+
+ /**
+ * Use the current settings and the schema version query
+ * to test the database schema.
+ *
+ * @return true if successfull connection, else false.
+ */
+ public boolean verifyDatabaseSchema() {
+ Connection conn = getEphemeralConnection();
+ if (null == conn) {
return false;
- } finally {
- if (null != resultSet) {
- try {
- resultSet.close();
- } catch (SQLException ex) {
- LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex); // NON-NLS
- }
- }
- if (null != conn) {
- try {
- conn.close();
- } catch (SQLException ex) {
- LOGGER.log(Level.SEVERE, "Error closing test connection.", ex); // NON-NLS
- }
- }
}
+ boolean result = EamDbUtil.schemaVersionIsSet(conn);
+ EamDbUtil.closeConnection(conn);
+ return result;
+ }
+
+ /**
+ * Initialize the database schema.
+ *
+ * Requires valid connectionPool.
+ *
+ * This method is called from within connect(), so we cannot call connect()
+ * to get a connection. This method is called after setupConnectionPool(),
+ * so it is safe to assume that a valid connectionPool exists. The
+ * implementation of connect() is synchronized, so we can safely use the
+ * connectionPool object directly.
+ */
+ public boolean initializeDatabaseSchema() {
+ // The "id" column is an alias for the built-in 64-bit int "rowid" column.
+ // It is autoincrementing by default and must be of type "integer primary key".
+ // We've omitted the autoincrement argument because we are not currently
+ // using the id value to search for specific rows, so we do not care
+ // if a rowid is re-used after an existing rows was previously deleted.
+ StringBuilder createOrganizationsTable = new StringBuilder();
+ createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
+ createOrganizationsTable.append("id integer primary key autoincrement NOT NULL,");
+ createOrganizationsTable.append("org_name text NOT NULL,");
+ createOrganizationsTable.append("poc_name text NOT NULL,");
+ createOrganizationsTable.append("poc_email text NOT NULL,");
+ createOrganizationsTable.append("poc_phone text NOT NULL");
+ createOrganizationsTable.append(")");
+
+ // NOTE: The organizations will only have a small number of rows, so
+ // an index is probably not worthwhile.
+
+ StringBuilder createCasesTable = new StringBuilder();
+ createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
+ createCasesTable.append("id integer primary key autoincrement NOT NULL,");
+ createCasesTable.append("case_uid text NOT NULL,");
+ createCasesTable.append("org_id integer,");
+ createCasesTable.append("case_name text NOT NULL,");
+ createCasesTable.append("creation_date text NOT NULL,");
+ createCasesTable.append("case_number text NOT NULL,");
+ createCasesTable.append("examiner_name text NOT NULL,");
+ createCasesTable.append("examiner_email text NOT NULL,");
+ createCasesTable.append("examiner_phone text NOT NULL,");
+ createCasesTable.append("notes text NOT NULL,");
+ createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null,");
+ createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE(case_uid)");
+ createCasesTable.append(")");
+
+ // NOTE: when there are few cases in the cases table, these indices may not be worthwhile
+ String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
+ String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
+
+ StringBuilder createDataSourcesTable = new StringBuilder();
+ createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
+ createDataSourcesTable.append("id integer primary key autoincrement NOT NULL,");
+ createDataSourcesTable.append("device_id text NOT NULL,");
+ createDataSourcesTable.append("name text NOT NULL,");
+ createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE(device_id)");
+ createDataSourcesTable.append(")");
+
+ String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
+
+ StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
+ createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
+ createGlobalReferenceSetsTable.append("id integer primary key autoincrement NOT NULL,");
+ createGlobalReferenceSetsTable.append("org_id integer,");
+ createGlobalReferenceSetsTable.append("set_name text NOT NULL,");
+ createGlobalReferenceSetsTable.append("version text NOT NULL,");
+ createGlobalReferenceSetsTable.append("import_date text NOT NULL,");
+ createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
+ createGlobalReferenceSetsTable.append(")");
+
+ String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
+
+ StringBuilder createGlobalFilesTable = new StringBuilder();
+ createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
+ createGlobalFilesTable.append("id integer primary key autoincrement NOT NULL,");
+ createGlobalFilesTable.append("global_reference_set_id integer,");
+ createGlobalFilesTable.append("value text NOT NULL,");
+ createGlobalFilesTable.append("known_status text NOT NULL,");
+ createGlobalFilesTable.append("comment text NOT NULL,");
+ createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE(global_reference_set_id, value)");
+ createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
+ createGlobalFilesTable.append(")");
+
+ String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
+ String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
+
+ StringBuilder createArtifactTypesTable = new StringBuilder();
+ createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
+ createArtifactTypesTable.append("id integer primary key autoincrement NOT NULL,");
+ createArtifactTypesTable.append("name text NOT NULL,");
+ createArtifactTypesTable.append("supported integer NOT NULL,");
+ createArtifactTypesTable.append("enabled integer NOT NULL,");
+ createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
+ createArtifactTypesTable.append(")");
+
+ // NOTE: there are API methods that query by one of: name, supported, or enabled.
+ // Only name is currently implemented, but, there will only be a small number
+ // of artifact_types, so there is no benefit to having any indices.
+ StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
+ createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
+ createArtifactInstancesTableTemplate.append("id integer primary key autoincrement NOT NULL,");
+ createArtifactInstancesTableTemplate.append("case_id integer,");
+ createArtifactInstancesTableTemplate.append("data_source_id integer,");
+ createArtifactInstancesTableTemplate.append("value text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("file_path text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("known_status text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("comment text NOT NULL,");
+ createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique UNIQUE(case_id, data_source_id, value, file_path),");
+ createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
+ createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
+ createArtifactInstancesTableTemplate.append(")");
+
+ // TODO: do we need any more indices?
+ String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
+ String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
+ String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
+ String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
+
+ StringBuilder createDbInfoTable = new StringBuilder();
+ createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
+ createDbInfoTable.append("id integer primary key NOT NULL,");
+ createDbInfoTable.append("name text NOT NULL,");
+ createDbInfoTable.append("value text NOT NULL");
+ createDbInfoTable.append(")");
+
+ // NOTE: the db_info table currenly only has 1 row, so having an index
+ // provides no benefit.
+
+ Connection conn = null;
+ try {
+ conn = getEphemeralConnection();
+ if (null == conn) {
+ return false;
+ }
+ Statement stmt = conn.createStatement();
+ stmt.execute(PRAGMA_JOURNAL_WAL);
+ stmt.execute(PRAGMA_SYNC_OFF);
+ stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE);
+ stmt.execute(PRAGMA_ENCODING_UTF8);
+ stmt.execute(PRAGMA_PAGE_SIZE_4096);
+ stmt.execute(PRAGMA_FOREIGN_KEYS_ON);
+
+ stmt.execute(createOrganizationsTable.toString());
+
+ stmt.execute(createCasesTable.toString());
+ stmt.execute(casesIdx1);
+ stmt.execute(casesIdx2);
+
+ stmt.execute(createDataSourcesTable.toString());
+ stmt.execute(dataSourceIdx1);
+
+ stmt.execute(createGlobalReferenceSetsTable.toString());
+ stmt.execute(globalReferenceSetsIdx1);
+
+ stmt.execute(createGlobalFilesTable.toString());
+ stmt.execute(globalFilesIdx1);
+ stmt.execute(globalFilesIdx2);
+
+ stmt.execute(createArtifactTypesTable.toString());
+
+ stmt.execute(createDbInfoTable.toString());
+
+ // Create a separate table for each artifact type
+ List DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
+
+ String type_name;
+ for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
+ type_name = type.getName();
+ stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
+ stmt.execute(String.format(instancesIdx1, type_name, type_name));
+ stmt.execute(String.format(instancesIdx2, type_name, type_name));
+ stmt.execute(String.format(instancesIdx3, type_name, type_name));
+ stmt.execute(String.format(instancesIdx4, type_name, type_name));
+ }
+ } catch (SQLException ex) {
+ LOGGER.log(Level.SEVERE, "Error initializing db schema.", ex); // NON-NLS
+ return false;
+ } finally {
+ EamDbUtil.closeConnection(conn);
+ }
return true;
}
+ public boolean insertDefaultDatabaseContent() {
+ Connection conn = getEphemeralConnection();
+ if (null == conn) {
+ return false;
+ }
+
+ boolean result = EamDbUtil.insertDefaultArtifactTypes(conn)
+ && EamDbUtil.insertSchemaVersion(conn);
+ EamDbUtil.closeConnection(conn);
+ return result;
+ }
+
public boolean isChanged() {
String dbNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS
String dbDirectoryString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory"); // NON-NLS
@@ -184,20 +419,6 @@ public final class SqliteEamDbSettings {
|| !Integer.toString(bulkThreshold).equals(bulkThresholdString);
}
- /**
- * @return the enabled
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * @param enabled the enabled to set
- */
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
/**
* @return the dbName
*/
@@ -211,11 +432,13 @@ public final class SqliteEamDbSettings {
* @param dbName the dbName to set
*/
public void setDbName(String dbName) throws EamDbException {
- if (dbName != null && !dbName.isEmpty()) {
- this.dbName = dbName;
- } else {
- throw new EamDbException("Error invalid file name for database. Cannot be null or empty."); // NON-NLS
+ if (dbName == null || dbName.isEmpty()) {
+ throw new EamDbException("Invalid database file name. Cannot be null or empty."); // NON-NLS
+ } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
+ throw new EamDbException("Invalid database file name. Name must start with a letter and can only contain letters, numbers, and '_'."); // NON-NLS
}
+
+ this.dbName = dbName;
}
/**
@@ -232,7 +455,7 @@ public final class SqliteEamDbSettings {
if (bulkThreshold > 0) {
this.bulkThreshold = bulkThreshold;
} else {
- throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS
+ throw new EamDbException("Invalid bulk threshold for database connection."); // NON-NLS
}
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java
index 3bbbb1aebf..1355bbef7e 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/BadFileTagRunner.java
@@ -42,7 +42,7 @@ public class BadFileTagRunner implements Runnable {
@Override
public void run() {
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS
return;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java
index 053eeebbc3..039e9a8867 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/CaseEventListener.java
@@ -61,7 +61,7 @@ public class CaseEventListener implements PropertyChangeListener {
EamDb dbManager = EamDb.getInstance();
switch (Case.Events.valueOf(evt.getPropertyName())) {
case CONTENT_TAG_ADDED: {
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
return;
}
@@ -125,7 +125,7 @@ public class CaseEventListener implements PropertyChangeListener {
break;
case BLACKBOARD_ARTIFACT_TAG_ADDED: {
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
return;
}
@@ -157,7 +157,7 @@ public class CaseEventListener implements PropertyChangeListener {
break;
case DATA_SOURCE_ADDED: {
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
break;
}
@@ -214,7 +214,7 @@ public class CaseEventListener implements PropertyChangeListener {
"",
"");
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
break;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java
index bcd1f3abeb..9066d960d5 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/IngestEventsListener.java
@@ -78,7 +78,7 @@ public class IngestEventsListener {
EamDb dbManager = EamDb.getInstance();
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
case DATA_ADDED: {
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
return;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java
index 79762b75a6..a8eaa8fd3d 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/eventlisteners/NewArtifactsRunner.java
@@ -45,7 +45,7 @@ public class NewArtifactsRunner implements Runnable {
@Override
public void run() {
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS
return;
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java
index 72fdf1762b..6937f5aca1 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/ingestmodule/IngestModule.java
@@ -29,7 +29,6 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.core.RuntimeProperties;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
-import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage;
@@ -69,8 +68,7 @@ class IngestModule implements FileIngestModule {
@Override
public ProcessResult process(AbstractFile af) {
- if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false
- || EamDb.getInstance().isEnabled() == false) {
+ if (EamDb.isEnabled() == false) {
/*
* Not signaling an error for now. This is a workaround for the way
* all newly didscovered ingest modules are automatically anabled.
@@ -152,8 +150,7 @@ class IngestModule implements FileIngestModule {
@Override
public void shutDown() {
- if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false
- || EamDb.getInstance().isEnabled() == false) {
+ if (EamDb.isEnabled() == false) {
/*
* Not signaling an error for now. This is a workaround for the way
* all newly didscovered ingest modules are automatically anabled.
@@ -187,8 +184,7 @@ class IngestModule implements FileIngestModule {
})
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
- if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false
- || EamDb.getInstance().isEnabled() == false) {
+ if (EamDb.isEnabled() == false) {
/*
* Not throwing the customary exception for now. This is a
* workaround for the way all newly didscovered ingest modules are
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties
index ccb83b2e46..8811aa8c49 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties
@@ -13,11 +13,9 @@ EamPostgresSettingsDialog.lbUserPassword.text=User Password :
EamPostgresSettingsDialog.lbUserName.text=User Name :
EamPostgresSettingsDialog.bnCancel.text=Cancel
EamPostgresSettingsDialog.lbPort.text=Port :
-EamPostgresSettingsDialog.bnSave.text=Save
EamPostgresSettingsDialog.lbHostName.text=Host Name / IP :
EamPostgresSettingsDialog.bnTestConnection.text=Test Connection
EamPostgresSettingsDialog.lbDatabaseName.text=Database name :
-EamSqliteSettingsDialog.bnSave.text=Save
EamSqliteSettingsDialog.bnCancel.text=Cancel
EamSqliteSettingsDialog.lbTestDatabase.text=
EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection
@@ -44,14 +42,11 @@ ImportHashDatabaseDialog.bnNewOrganization.text=Add New Organization
ImportHashDatabaseDialog.tfDatabaseName.tooltip=Name for this database
ImportHashDatabaseDialog.tfDatabaseVersion.tooltip.text=Database Version Number
GlobalSettingsPanel.bnImportDatabase.actionCommand=
-GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text=Enable Enterprise Artifacts Manager
GlobalSettingsPanel.bnManageTypes.text=Manage Artifact Types
GlobalSettingsPanel.bnManageTags.actionCommand=
GlobalSettingsPanel.bnManageTags.toolTipText=
GlobalSettingsPanel.bnManageTags.text=Manage Tags
GlobalSettingsPanel.tbOops.text=
-GlobalSettingsPanel.bnConfigureDatabaseSettings.text=Configure
-GlobalSettingsPanel.lbDatabasePlatform.text=Enable Database Platform :
GlobalSettingsPanel.lbDatabaseSettings.text=Database Settings
GlobalSettingsPanel.bnImportDatabase.label=Import Hash Database
AddNewOrganizationDialog.lbPocPhone.text=Phone:
@@ -68,3 +63,28 @@ ManageArtifactTypesDialog.cancelButton.text=Cancel
ManageArtifactTypesDialog.okButton.text=OK
ManageArtifactTypesDialog.lbWarningMsg.text=Warning Message
ManageArtifactTypesDialog.taInstructionsMsg.text=Select one or more artifact types to store in the database and use for correlation during Ingest.
+EamSqliteSettingsDialog.bnOk.text=OK
+EamPostgresSettingsDialog.bnSave.text=Save
+EamDbSettingsDialog.pnDatabaseConnectionSettings.border.title=Database Settings
+EamDbSettingsDialog.rdioBnPostgreSQL.text=PostgreSQL
+EamDbSettingsDialog.rdioBnSQLite.text=SQLite
+EamDbSettingsDialog.bnDatabasePathFileOpen.text=Open...
+EamDbSettingsDialog.tfDatabasePath.toolTipText=Filename and path to store SQLite db file
+EamDbSettingsDialog.tfDatabasePath.text=
+EamDbSettingsDialog.lbDatabasePath.text=Database Path :
+EamDbSettingsDialog.rdioBnDisabled.text=Disabled
+EamDbSettingsDialog.bnCancel.text=Cancel
+EamDbSettingsDialog.bnOk.text=OK
+EamDbSettingsDialog.bnTest.text=Test
+EamDbSettingsDialog.lbHostName.text=Host Name / IP :
+EamDbSettingsDialog.lbDatabaseName.text=Database name :
+EamDbSettingsDialog.lbUserPassword.text=User Password :
+EamDbSettingsDialog.lbUserName.text=User Name :
+EamDbSettingsDialog.lbPort.text=Port :
+EamDbSettingsDialog.bnCreateDb.text=Create
+EamDbSettingsDialog.pnSetupGuidance.border.title=Setup Guidance
+GlobalSettingsPanel.pnDatabaseConfiguration.title=Database Configuration
+GlobalSettingsPanel.lbDbPlatformTypeLabel.text=Type:
+GlobalSettingsPanel.lbDbNameLabel.text=Name:
+GlobalSettingsPanel.bnDbConfigure.text=Configure
+GlobalSettingsPanel.lbDbLocationLabel.text=Location:
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form
new file mode 100644
index 0000000000..3a43033eca
--- /dev/null
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.form
@@ -0,0 +1,489 @@
+
+
+
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java
new file mode 100644
index 0000000000..4f95216843
--- /dev/null
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamDbSettingsDialog.java
@@ -0,0 +1,932 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.optionspanel;
+
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.logging.Level;
+import javax.swing.ImageIcon;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle.Messages;
+import org.openide.windows.WindowManager;
+import org.sleuthkit.autopsy.corecomponents.TextPrompt;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.SqliteEamDbSettings;
+
+/**
+ *
+ * @author nick
+ */
+public class EamDbSettingsDialog extends JDialog {
+ private static final Logger LOGGER = Logger.getLogger(EamDbSettingsDialog.class.getName());
+ private final Collection textBoxes;
+ private final TextBoxChangedListener textBoxChangedListener;
+ private final ImageIcon goodIcon;
+ private final ImageIcon badIcon;
+
+ private final PostgresEamDbSettings dbSettingsPostgres;
+ private final SqliteEamDbSettings dbSettingsSqlite;
+ private DatabaseTestResult testingStatus;
+ private EamDbPlatformEnum selectedPlatform;
+
+ /**
+ * Creates new form EamDbSettingsDialog
+ */
+ @Messages({"EamDbSettingsDialog.title.text=Enterprise Artifacts Manager Settings"})
+ public EamDbSettingsDialog() {
+ super((JFrame) WindowManager.getDefault().getMainWindow(),
+ Bundle.EamDbSettingsDialog_title_text(),
+ true); // NON-NLS
+
+ textBoxes = new ArrayList<>();
+ textBoxChangedListener = new TextBoxChangedListener();
+ goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS
+ badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS
+
+ dbSettingsPostgres = new PostgresEamDbSettings();
+ dbSettingsSqlite = new SqliteEamDbSettings();
+ selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
+
+ initComponents();
+ customizeComponents();
+ valid();
+ display();
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ bnGrpDatabasePlatforms = new javax.swing.ButtonGroup();
+ fcDatabasePath = new javax.swing.JFileChooser();
+ pnDatabaseConnectionSettings = new javax.swing.JPanel();
+ pnSQLiteSettings = new javax.swing.JPanel();
+ lbDatabasePath = new javax.swing.JLabel();
+ tfDatabasePath = new javax.swing.JTextField();
+ bnDatabasePathFileOpen = new javax.swing.JButton();
+ pnPostgreSQLSettings = new javax.swing.JPanel();
+ lbHostName = new javax.swing.JLabel();
+ lbPort = new javax.swing.JLabel();
+ lbUserName = new javax.swing.JLabel();
+ lbUserPassword = new javax.swing.JLabel();
+ lbDatabaseName = new javax.swing.JLabel();
+ tbDbHostname = new javax.swing.JTextField();
+ tbDbPort = new javax.swing.JTextField();
+ tbDbName = new javax.swing.JTextField();
+ tbDbUsername = new javax.swing.JTextField();
+ jpDbPassword = new javax.swing.JPasswordField();
+ rdioBnSQLite = new javax.swing.JRadioButton();
+ rdioBnPostgreSQL = new javax.swing.JRadioButton();
+ rdioBnDisabled = new javax.swing.JRadioButton();
+ pnButtons = new javax.swing.JPanel();
+ bnCancel = new javax.swing.JButton();
+ bnOk = new javax.swing.JButton();
+ bnTest = new javax.swing.JButton();
+ bnCreateDb = new javax.swing.JButton();
+ lbTestIcon = new javax.swing.JLabel();
+ lbCreateIcon = new javax.swing.JLabel();
+ pnSetupGuidance = new javax.swing.JPanel();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ taSetupGuidance = new javax.swing.JTextArea();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+
+ pnDatabaseConnectionSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.pnDatabaseConnectionSettings.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+ pnDatabaseConnectionSettings.setName(""); // NOI18N
+
+ pnSQLiteSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabasePath.text")); // NOI18N
+
+ tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.text")); // NOI18N
+ tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N
+ tfDatabasePath.addFocusListener(new java.awt.event.FocusAdapter() {
+ public void focusLost(java.awt.event.FocusEvent evt) {
+ tfDatabasePathFocusLost(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N
+ bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnDatabasePathFileOpenActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnSQLiteSettingsLayout = new javax.swing.GroupLayout(pnSQLiteSettings);
+ pnSQLiteSettings.setLayout(pnSQLiteSettingsLayout);
+ pnSQLiteSettingsLayout.setHorizontalGroup(
+ pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnSQLiteSettingsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lbDatabasePath)
+ .addGap(18, 18, 18)
+ .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(bnDatabasePathFileOpen)
+ .addContainerGap())
+ );
+ pnSQLiteSettingsLayout.setVerticalGroup(
+ pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnSQLiteSettingsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnSQLiteSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(bnDatabasePathFileOpen))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ pnPostgreSQLSettings.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbHostName.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbPort.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserName.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbUserPassword.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseName, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.lbDatabaseName.text")); // NOI18N
+
+ javax.swing.GroupLayout pnPostgreSQLSettingsLayout = new javax.swing.GroupLayout(pnPostgreSQLSettings);
+ pnPostgreSQLSettings.setLayout(pnPostgreSQLSettingsLayout);
+ pnPostgreSQLSettingsLayout.setHorizontalGroup(
+ pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnPostgreSQLSettingsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbHostName)
+ .addComponent(lbPort)
+ .addComponent(lbDatabaseName)
+ .addComponent(lbUserName)
+ .addComponent(lbUserPassword))
+ .addGap(18, 18, 18)
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(tbDbUsername, javax.swing.GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE)
+ .addComponent(tbDbName)
+ .addComponent(tbDbPort)
+ .addComponent(tbDbHostname)
+ .addComponent(jpDbPassword))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ pnPostgreSQLSettingsLayout.setVerticalGroup(
+ pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnPostgreSQLSettingsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(tbDbPort)
+ .addComponent(lbPort, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(tbDbName)
+ .addComponent(lbDatabaseName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(tbDbUsername)
+ .addComponent(lbUserName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnPostgreSQLSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lbUserPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jpDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(19, Short.MAX_VALUE))
+ );
+
+ org.openide.awt.Mnemonics.setLocalizedText(rdioBnSQLite, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.rdioBnSQLite.text")); // NOI18N
+ rdioBnSQLite.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ rdioBnSQLiteActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(rdioBnPostgreSQL, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.rdioBnPostgreSQL.text")); // NOI18N
+ rdioBnPostgreSQL.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ rdioBnPostgreSQLActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(rdioBnDisabled, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.rdioBnDisabled.text")); // NOI18N
+ rdioBnDisabled.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ rdioBnDisabledActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnDatabaseConnectionSettingsLayout = new javax.swing.GroupLayout(pnDatabaseConnectionSettings);
+ pnDatabaseConnectionSettings.setLayout(pnDatabaseConnectionSettingsLayout);
+ pnDatabaseConnectionSettingsLayout.setHorizontalGroup(
+ pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup()
+ .addComponent(rdioBnPostgreSQL)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup()
+ .addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(rdioBnSQLite)
+ .addComponent(rdioBnDisabled))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnPostgreSQLSettings, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ );
+ pnDatabaseConnectionSettingsLayout.setVerticalGroup(
+ pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConnectionSettingsLayout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(rdioBnDisabled)
+ .addGap(13, 13, 13)
+ .addComponent(rdioBnSQLite)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pnSQLiteSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(12, 12, 12)
+ .addComponent(rdioBnPostgreSQL)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pnPostgreSQLSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(329, 329, 329))
+ );
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnCancel.text")); // NOI18N
+ bnCancel.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnCancelActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnOk, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnOk.text")); // NOI18N
+ bnOk.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnOkActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnTest, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnTest.text")); // NOI18N
+ bnTest.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnTestActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnCreateDb, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.bnCreateDb.text")); // NOI18N
+ bnCreateDb.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnCreateDbActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnButtonsLayout = new javax.swing.GroupLayout(pnButtons);
+ pnButtons.setLayout(pnButtonsLayout);
+ pnButtonsLayout.setHorizontalGroup(
+ pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnButtonsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(bnTest)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lbTestIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(18, 18, 18)
+ .addComponent(bnCreateDb)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lbCreateIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(bnOk)
+ .addGap(11, 11, 11)
+ .addComponent(bnCancel)
+ .addContainerGap())
+ );
+ pnButtonsLayout.setVerticalGroup(
+ pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnButtonsLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbCreateIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbTestIcon, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(pnButtonsLayout.createSequentialGroup()
+ .addGroup(pnButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(bnOk)
+ .addComponent(bnCancel)
+ .addComponent(bnTest)
+ .addComponent(bnCreateDb))
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+
+ pnSetupGuidance.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamDbSettingsDialog.class, "EamDbSettingsDialog.pnSetupGuidance.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+
+ jScrollPane1.setBorder(null);
+
+ taSetupGuidance.setEditable(false);
+ taSetupGuidance.setBackground(new java.awt.Color(240, 240, 240));
+ taSetupGuidance.setColumns(20);
+ taSetupGuidance.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
+ taSetupGuidance.setLineWrap(true);
+ taSetupGuidance.setRows(3);
+ taSetupGuidance.setTabSize(4);
+ taSetupGuidance.setWrapStyleWord(true);
+ taSetupGuidance.setAutoscrolls(false);
+ taSetupGuidance.setBorder(null);
+ taSetupGuidance.setRequestFocusEnabled(false);
+ taSetupGuidance.setVerifyInputWhenFocusTarget(false);
+ jScrollPane1.setViewportView(taSetupGuidance);
+
+ javax.swing.GroupLayout pnSetupGuidanceLayout = new javax.swing.GroupLayout(pnSetupGuidance);
+ pnSetupGuidance.setLayout(pnSetupGuidanceLayout);
+ pnSetupGuidanceLayout.setHorizontalGroup(
+ pnSetupGuidanceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnSetupGuidanceLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jScrollPane1)
+ .addContainerGap())
+ );
+ pnSetupGuidanceLayout.setVerticalGroup(
+ pnSetupGuidanceLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnSetupGuidanceLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jScrollPane1, 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 layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(pnSetupGuidance, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(pnSetupGuidance, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 348, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pnButtons, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void customizeComponents() {
+ bnGrpDatabasePlatforms.add(rdioBnDisabled);
+ bnGrpDatabasePlatforms.add(rdioBnPostgreSQL);
+ bnGrpDatabasePlatforms.add(rdioBnSQLite);
+
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ rdioBnPostgreSQL.setSelected(true);
+ testingStatus = DatabaseTestResult.UNTESTED;
+ updatePostgresFields(true);
+ updateSqliteFields(false);
+ break;
+ case SQLITE:
+ rdioBnSQLite.setSelected(true);
+ testingStatus = DatabaseTestResult.UNTESTED;
+ updatePostgresFields(false);
+ updateSqliteFields(true);
+ break;
+ default:
+ rdioBnDisabled.setSelected(true);
+ testingStatus = DatabaseTestResult.TESTEDOK;
+ updatePostgresFields(false);
+ updateSqliteFields(false);
+ break;
+ }
+
+ setTextPrompts();
+ setTextBoxListeners();
+ lbTestIcon.setIcon(null);
+ }
+
+ private void display() {
+ Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
+ setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
+ setVisible(true);
+ }
+ private void setGuidanceMessage(String message, boolean isError) {
+ taSetupGuidance.setText(message);
+ if (isError) {
+ taSetupGuidance.setForeground(new Color(255, 102, 102)); // light red color
+ } else {
+ taSetupGuidance.setForeground(new Color(0, 0, 0)); // black color
+ }
+ }
+
+ private void clearIcons() {
+ lbTestIcon.setIcon(null);
+ lbCreateIcon.setIcon(null);
+ }
+
+ @Messages({"EamDbSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."})
+ private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed
+ fcDatabasePath.setCurrentDirectory(new File(dbSettingsSqlite.getDbDirectory()));
+ fcDatabasePath.setSelectedFile(new File(dbSettingsSqlite.getFileNameWithPath()));
+ if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ File databaseFile = fcDatabasePath.getSelectedFile();
+ try {
+ String fullPath = databaseFile.getCanonicalPath();
+ if (!fullPath.endsWith(".db")) {
+ fullPath = fullPath + ".db"; // NON-NLS
+ }
+ tfDatabasePath.setText(fullPath);
+ valid();
+ } catch (IOException ex) {
+ LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_chooserPath_failedToGetDbPathMsg(), true);
+ }
+ }
+ }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed
+
+ private void bnTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestActionPerformed
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ if (dbSettingsPostgres.verifyConnection()) {
+ if (dbSettingsPostgres.verifyDatabaseExists()
+ && dbSettingsPostgres.verifyDatabaseSchema()) {
+ testingStatus = DatabaseTestResult.TESTEDOK;
+ } else {
+ testingStatus = DatabaseTestResult.SCHEMA_INVALID;
+ }
+ } else {
+ testingStatus = DatabaseTestResult.CONNECTION_FAILED;
+ }
+ break;
+ case SQLITE:
+ if (dbSettingsSqlite.dbDirectoryExists()
+ && dbSettingsSqlite.verifyConnection()) {
+ if (dbSettingsSqlite.verifyDatabaseSchema()) {
+ testingStatus = DatabaseTestResult.TESTEDOK;
+ } else {
+ testingStatus = DatabaseTestResult.SCHEMA_INVALID;
+ }
+ } else {
+ testingStatus = DatabaseTestResult.SCHEMA_INVALID;
+ }
+ break;
+ }
+
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ if (testingStatus == DatabaseTestResult.TESTEDOK) {
+ lbTestIcon.setIcon(goodIcon);
+ } else {
+ lbTestIcon.setIcon(badIcon);
+ }
+ valid();
+ }//GEN-LAST:event_bnTestActionPerformed
+
+ @Messages({"EamDbSettingsDialog.creation.failed=Database initialization failed."})
+ private void bnCreateDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCreateDbActionPerformed
+
+ setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ clearIcons();
+ boolean result = false;
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ if (!dbSettingsPostgres.verifyDatabaseExists()) {
+ dbSettingsPostgres.createDatabase();
+ }
+ result = dbSettingsPostgres.initializeDatabaseSchema()
+ && dbSettingsPostgres.insertDefaultDatabaseContent();
+
+ break;
+ case SQLITE:
+ if (!dbSettingsSqlite.dbDirectoryExists()) {
+ dbSettingsSqlite.createDbDirectory();
+ }
+ result = dbSettingsSqlite.initializeDatabaseSchema()
+ && dbSettingsSqlite.insertDefaultDatabaseContent();
+ break;
+ }
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ if (false == result) {
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_creation_failed(), true);
+ lbCreateIcon.setIcon(badIcon);
+ } else {
+ testingStatus = DatabaseTestResult.TESTEDOK;
+ lbCreateIcon.setIcon(goodIcon);
+ valid();
+ }
+ }//GEN-LAST:event_bnCreateDbActionPerformed
+
+ private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed
+ EamDbPlatformEnum.setSelectedPlatform(selectedPlatform.name());
+ EamDbPlatformEnum.saveSelectedPlatform();
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ dbSettingsPostgres.saveSettings();
+ EamDb.getInstance().updateSettings();
+ break;
+ case SQLITE:
+ dbSettingsSqlite.saveSettings();
+ EamDb.getInstance().updateSettings();
+ break;
+ case DISABLED:
+ break;
+ }
+
+ dispose();
+ }//GEN-LAST:event_bnOkActionPerformed
+
+ private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
+ dispose();
+ }//GEN-LAST:event_bnCancelActionPerformed
+
+ private void rdioBnDisabledActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnDisabledActionPerformed
+ selectedPlatform = EamDbPlatformEnum.DISABLED;
+ testingStatus = DatabaseTestResult.TESTEDOK;
+
+ updateSqliteFields(false);
+ updatePostgresFields(false);
+ }//GEN-LAST:event_rdioBnDisabledActionPerformed
+
+
+ private void rdioBnPostgreSQLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnPostgreSQLActionPerformed
+ selectedPlatform = EamDbPlatformEnum.POSTGRESQL;
+ testingStatus = DatabaseTestResult.UNTESTED;
+
+ updateSqliteFields(false);
+ updatePostgresFields(true);
+ }//GEN-LAST:event_rdioBnPostgreSQLActionPerformed
+
+ private void rdioBnSQLiteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rdioBnSQLiteActionPerformed
+ selectedPlatform = EamDbPlatformEnum.SQLITE;
+ testingStatus = DatabaseTestResult.UNTESTED;
+
+ updateSqliteFields(true);
+ updatePostgresFields(false);
+
+ }//GEN-LAST:event_rdioBnSQLiteActionPerformed
+
+ private void tfDatabasePathFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_tfDatabasePathFocusLost
+ String fullPath = tfDatabasePath.getText();
+ if (!fullPath.endsWith(".db")) {
+ fullPath = fullPath + ".db"; // NON-NLS
+ }
+ tfDatabasePath.setText(fullPath);
+ }//GEN-LAST:event_tfDatabasePathFocusLost
+
+ /**
+ * Update the fields for the Postgres platform depending on whether the
+ * Postgres radioButton is enabled.
+ *
+ * @param enabled
+ */
+ private void updatePostgresFields(boolean enabled) {
+ tbDbHostname.setText(enabled ? dbSettingsPostgres.getHost() : "");
+ tbDbHostname.setEnabled(enabled);
+ tbDbPort.setText(enabled ? Integer.toString(dbSettingsPostgres.getPort()) : "");
+ tbDbPort.setEnabled(enabled);
+ tbDbName.setText(enabled ? dbSettingsPostgres.getDbName() : "");
+ tbDbName.setEnabled(enabled);
+ tbDbUsername.setText(enabled ? dbSettingsPostgres.getUserName() : "");
+ tbDbUsername.setEnabled(enabled);
+ jpDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : "");
+ jpDbPassword.setEnabled(enabled);
+ }
+
+ /**
+ * Update the fields for the SQLite platform depending on whether the
+ * SQLite radioButton is enabled.
+ *
+ * @param enabled
+ */
+ private void updateSqliteFields(boolean enabled) {
+ tfDatabasePath.setText(enabled ? dbSettingsSqlite.getFileNameWithPath() : "");
+ tfDatabasePath.setEnabled(enabled);
+ bnDatabasePathFileOpen.setEnabled(enabled);
+ }
+
+ /**
+ * Add text prompts to all of the text fields.
+ */
+ @Messages({"EamDbSettingsDialog.textPrompt.hostnameOrIP=Hostname or IP Address",
+ "EamDbSettingsDialog.textPrompt.port=Port Number",
+ "EamDbSettingsDialog.textPrompt.dbName=Database Name",
+ "EamDbSettingsDialog.textPrompt.user=Database User",
+ "EamDbSettingsDialog.textPrompt.password=Database User's Password"})
+ private void setTextPrompts() {
+ Collection textPrompts = new ArrayList<>();
+ textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_hostnameOrIP(), tbDbHostname));
+ textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_port(), tbDbPort));
+ textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_dbName(), tbDbName));
+ textPrompts.add(new TextPrompt(Bundle.EamDbSettingsDialog_textPrompt_user(), tbDbUsername));
+ configureTextPrompts(textPrompts);
+ }
+
+ /**
+ * Register for notifications when the text boxes get updated.
+ */
+ private void setTextBoxListeners() {
+ textBoxes.add(tfDatabasePath);
+ textBoxes.add(tbDbHostname);
+ textBoxes.add(tbDbPort);
+ textBoxes.add(tbDbName);
+ textBoxes.add(tbDbUsername);
+ textBoxes.add(jpDbPassword);
+ addDocumentListeners(textBoxes, textBoxChangedListener);
+ }
+
+ /**
+ * Sets the foreground color and transparency of a collection of text
+ * prompts.
+ *
+ * @param textPrompts The text prompts to configure.
+ */
+ private static void configureTextPrompts(Collection textPrompts) {
+ float alpha = 0.9f; // Mostly opaque
+ for (TextPrompt textPrompt : textPrompts) {
+ textPrompt.setForeground(Color.LIGHT_GRAY);
+ textPrompt.changeAlpha(alpha);
+ }
+ }
+
+ /**
+ * Adds a change listener to a collection of text fields.
+ *
+ * @param textFields The text fields.
+ * @param listener The change listener.
+ */
+ private static void addDocumentListeners(Collection textFields, TextBoxChangedListener listener) {
+ textFields.forEach((textField) -> {
+ textField.getDocument().addDocumentListener(listener);
+ });
+ }
+
+ /**
+ * Tests whether or not values have been entered in all of the database
+ * settings text fields.
+ *
+ * @return True or false.
+ */
+ @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database."})
+ private boolean databaseFieldsArePopulated() {
+ boolean result = true;
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ result = !tbDbHostname.getText().trim().isEmpty()
+ && !tbDbPort.getText().trim().isEmpty()
+ && !tbDbName.getText().trim().isEmpty()
+ && !tbDbUsername.getText().trim().isEmpty()
+ && 0 < jpDbPassword.getPassword().length;
+
+ break;
+
+ case SQLITE:
+ result = !tfDatabasePath.getText().trim().isEmpty();
+ break;
+ }
+
+ if (!result) {
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_incompleteFields(), true);
+ }
+
+ return result;
+ }
+
+ /**
+ * Tests whether or not all of the settings components are populated.
+ *
+ * @return True or false.
+ */
+ private boolean checkFields() {
+ return databaseFieldsArePopulated()
+ && databaseSettingsAreValid();
+ }
+
+ /**
+ * Tests whether or not the database settings are valid.
+ *
+ * @return True or false.
+ */
+ private boolean databaseSettingsAreValid() {
+ boolean result = true;
+ StringBuilder guidanceText = new StringBuilder();
+
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ try {
+ dbSettingsPostgres.setHost(tbDbHostname.getText().trim());
+ } catch (EamDbException ex) {
+ guidanceText.append(ex.getMessage());
+ result = false;
+ }
+
+ try {
+ dbSettingsPostgres.setPort(Integer.valueOf(tbDbPort.getText().trim()));
+ } catch (NumberFormatException | EamDbException ex) {
+ guidanceText.append(ex.getMessage());
+ result = false;
+ }
+
+ try {
+ dbSettingsPostgres.setDbName(tbDbName.getText().trim());
+ } catch (EamDbException ex) {
+ guidanceText.append(ex.getMessage());
+ result = false;
+ }
+
+ try {
+ dbSettingsPostgres.setUserName(tbDbUsername.getText().trim());
+ } catch (EamDbException ex) {
+ guidanceText.append(ex.getMessage());
+ result = false;
+ }
+
+ try {
+ dbSettingsPostgres.setPassword(new String(jpDbPassword.getPassword()));
+ } catch (EamDbException ex) {
+ guidanceText.append(ex.getMessage());
+ result = false;
+ }
+ break;
+ case SQLITE:
+ try {
+ File databasePath = new File(tfDatabasePath.getText());
+ dbSettingsSqlite.setDbName(databasePath.getName());
+ dbSettingsSqlite.setDbDirectory(databasePath.getParent());
+ } catch (EamDbException ex) {
+ guidanceText.append(ex.getMessage());
+ result = false;
+ }
+ break;
+ }
+
+ setGuidanceMessage(guidanceText.toString(), true);
+ return result;
+ }
+
+ /**
+ * Validates that the form is filled out correctly for our usage.
+ *
+ * @return true if it's okay, false otherwise.
+ */
+ private boolean valid() {
+ taSetupGuidance.setText("");
+ return enableTestButton(checkFields())
+ && enableCreateButton()
+ && enableOkButton();
+ }
+
+ /**
+ * Enable the "Test" button once all fields are valid.
+ *
+ * @return true
+ */
+ @Messages({"EamDbSettingsDialog.validation.mustTest=Once you are statisfied with the database settings, click the Test button to test the database connection, settings, and schema.",
+ "EamDbSettingsDialog.validation.failedConnection=The connection to the database failed. Update the settings and try the Test again."})
+ private boolean enableTestButton(boolean isValidInput) {
+ if (selectedPlatform != EamDbPlatformEnum.DISABLED && isValidInput) {
+ bnTest.setEnabled(true);
+ if (testingStatus == DatabaseTestResult.UNTESTED) {
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_mustTest(), false);
+ } else if (testingStatus == DatabaseTestResult.CONNECTION_FAILED) {
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_failedConnection(), true);
+ }
+ } else {
+ bnTest.setEnabled(false);
+ }
+ return true;
+ }
+
+ /**
+ * Enable the "Create" button if the db is not created.
+ *
+ * @return true if db is created, else false
+ */
+ @Messages({"EamDbSettingsDialog.validation.dbNotCreated=The database does not exist. Click the Create button to create and initialize the database."})
+ private boolean enableCreateButton() {
+ if (testingStatus == DatabaseTestResult.SCHEMA_INVALID) {
+ bnCreateDb.setEnabled(true);
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_dbNotCreated(), false);
+ } else {
+ bnCreateDb.setEnabled(false);
+ }
+ return true;
+ }
+
+ /**
+ * Enable the "OK" button if the db test passed. Disabled defaults to db test passed.
+ *
+ * @return true
+ */
+ @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options. Or select a differnt database type."})
+ private boolean enableOkButton() {
+ if (testingStatus == DatabaseTestResult.TESTEDOK || selectedPlatform == EamDbPlatformEnum.DISABLED) {
+ bnOk.setEnabled(true);
+ setGuidanceMessage(Bundle.EamDbSettingsDialog_validation_finished(), false);
+ } else {
+ bnOk.setEnabled(false);
+ }
+ return true;
+ }
+
+ /**
+ * Used to listen for changes in text boxes. It lets the panel know things
+ * have been updated and that validation needs to happen.
+ */
+ private class TextBoxChangedListener implements DocumentListener {
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ clearIcons();
+ testingStatus = DatabaseTestResult.UNTESTED;
+ valid();
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ clearIcons();
+ testingStatus = DatabaseTestResult.UNTESTED;
+ valid();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ clearIcons();
+ testingStatus = DatabaseTestResult.UNTESTED;
+ valid();
+ }
+ }
+
+ private enum DatabaseTestResult {
+ UNTESTED,
+ CONNECTION_FAILED,
+ SCHEMA_INVALID,
+ TESTEDOK;
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton bnCancel;
+ private javax.swing.JButton bnCreateDb;
+ private javax.swing.JButton bnDatabasePathFileOpen;
+ private javax.swing.ButtonGroup bnGrpDatabasePlatforms;
+ private javax.swing.JButton bnOk;
+ private javax.swing.JButton bnTest;
+ private javax.swing.JFileChooser fcDatabasePath;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JPasswordField jpDbPassword;
+ private javax.swing.JLabel lbCreateIcon;
+ private javax.swing.JLabel lbDatabaseName;
+ private javax.swing.JLabel lbDatabasePath;
+ private javax.swing.JLabel lbHostName;
+ private javax.swing.JLabel lbPort;
+ private javax.swing.JLabel lbTestIcon;
+ private javax.swing.JLabel lbUserName;
+ private javax.swing.JLabel lbUserPassword;
+ private javax.swing.JPanel pnButtons;
+ private javax.swing.JPanel pnDatabaseConnectionSettings;
+ private javax.swing.JPanel pnPostgreSQLSettings;
+ private javax.swing.JPanel pnSQLiteSettings;
+ private javax.swing.JPanel pnSetupGuidance;
+ private javax.swing.JRadioButton rdioBnDisabled;
+ private javax.swing.JRadioButton rdioBnPostgreSQL;
+ private javax.swing.JRadioButton rdioBnSQLite;
+ private javax.swing.JTextArea taSetupGuidance;
+ private javax.swing.JTextField tbDbHostname;
+ private javax.swing.JTextField tbDbName;
+ private javax.swing.JTextField tbDbPort;
+ private javax.swing.JTextField tbDbUsername;
+ private javax.swing.JTextField tfDatabasePath;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form
deleted file mode 100644
index 31db936608..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.form
+++ /dev/null
@@ -1,246 +0,0 @@
-
-
-
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java
deleted file mode 100644
index 148551ffce..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamPostgresSettingsDialog.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Enterprise Artifacts Manager
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.experimental.enterpriseartifactsmanager.optionspanel;
-
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Toolkit;
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.swing.ImageIcon;
-import javax.swing.JFrame;
-import javax.swing.JTextField;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import org.netbeans.spi.options.OptionsPanelController;
-import org.openide.util.ImageUtilities;
-import org.openide.util.NbBundle;
-import org.openide.util.NbBundle.Messages;
-import org.openide.windows.WindowManager;
-import org.sleuthkit.autopsy.corecomponents.TextPrompt;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException;
-import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings;
-
-/**
- * Settings panel for the postgres-specific options
- */
-public class EamPostgresSettingsDialog extends javax.swing.JDialog {
-
- private static final Logger LOGGER = Logger.getLogger(EamSqliteSettingsDialog.class.getName());
- private final ImageIcon goodIcon;
- private final ImageIcon badIcon;
- private final Collection textBoxes;
- private final TextBoxChangedListener textBoxChangedListener;
-
- private final PostgresEamDbSettings dbSettings;
- private Boolean hasChanged;
-
- /**
- * Creates new form EnterpriseArtifactsManagerPostgresSettingsDialog
- */
- @NbBundle.Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.postgresSettingsMessage.text=PostgreSQL Database Settings"})
- public EamPostgresSettingsDialog() {
- super((JFrame) WindowManager.getDefault().getMainWindow(),
- Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_postgresSettingsMessage_text(),
- true); // NON-NLS
-
- textBoxes = new ArrayList<>();
- textBoxChangedListener = new TextBoxChangedListener();
- this.dbSettings = new PostgresEamDbSettings();
- goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS
- badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS
-
- initComponents();
- customizeComponents();
- display();
- }
-
- /**
- * Let calling object determine if this dialog made any changes.
- *
- * @return true or false
- */
- public Boolean isChanged() {
- return hasChanged;
- }
-
- private void customizeComponents() {
- hasChanged = false;
- lbTestDatabaseWarning.setText("");
- setTextPrompts();
- setTextBoxStatusIcons();
- setTextBoxListeners();
- tbDbHostname.setText(dbSettings.getHost());
- tbDbPort.setText(Integer.toString(dbSettings.getPort()));
- tbDbName.setText(dbSettings.getDbName());
- tbDbUsername.setText(dbSettings.getUserName());
- tbDbPassword.setText(dbSettings.getPassword());
-
- enableTestDatabaseButton(false);
- enableSaveButton(false);
- this.valid();
- }
-
- private void display() {
- Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
- setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
- setVisible(true);
- }
-
- /**
- * Add text prompts to all of the text fields.
- */
- @Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.hostnameOrIP=Hostname or IP Address",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.port=Port Number",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.dbName=Database Name",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.user=Database User",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.textPrompt.password=Database User's Password"})
- private void setTextPrompts() {
- Collection textPrompts = new ArrayList<>();
- textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_hostnameOrIP(), tbDbHostname));
- textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_port(), tbDbPort));
- textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_dbName(), tbDbName));
- textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_user(), tbDbUsername));
- textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_textPrompt_password(), tbDbPassword));
- configureTextPrompts(textPrompts);
- }
-
- /**
- * Set each textbox with a "statusIcon" property enabling the
- * DocumentListeners to know which icon to erase when changes are made
- */
- private void setTextBoxStatusIcons() {
- tbDbHostname.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
- tbDbPort.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
- tbDbName.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
- tbDbUsername.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
- tbDbPassword.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
- }
-
- /**
- * Register for notifications when the text boxes get updated.
- */
- private void setTextBoxListeners() {
- textBoxes.add(tbDbHostname);
- textBoxes.add(tbDbPort);
- textBoxes.add(tbDbName);
- textBoxes.add(tbDbUsername);
- textBoxes.add(tbDbPassword);
- addDocumentListeners(textBoxes, textBoxChangedListener);
- }
-
- /**
- * Sets the foreground color and transparency of a collection of text
- * prompts.
- *
- * @param textPrompts The text prompts to configure.
- */
- private static void configureTextPrompts(Collection textPrompts) {
- float alpha = 0.9f; // Mostly opaque
- for (TextPrompt textPrompt : textPrompts) {
- textPrompt.setForeground(Color.LIGHT_GRAY);
- textPrompt.changeAlpha(alpha);
- }
- }
-
- /**
- * Adds a change listener to a collection of text fields.
- *
- * @param textFields The text fields.
- * @param listener The change listener.
- */
- private static void addDocumentListeners(Collection textFields, TextBoxChangedListener listener) {
- textFields.forEach((textField) -> {
- textField.getDocument().addDocumentListener(listener);
- });
- }
-
- /**
- * Tests whether or not values have been entered in all of the database
- * settings text fields.
- *
- * @return True or false.
- */
- private boolean databaseFieldsArePopulated() {
- return !tbDbHostname.getText().trim().isEmpty()
- && !tbDbPort.getText().trim().isEmpty()
- && !tbDbName.getText().trim().isEmpty()
- && !tbDbUsername.getText().trim().isEmpty()
- && !tbDbPassword.getText().trim().isEmpty();
- }
-
- /**
- * Tests whether or not all of the settings components are populated.
- *
- * @return True or false.
- */
- @Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.validation.incompleteFields=Fill in all values"})
- private boolean checkFields() {
- boolean result = true;
-
- boolean dbPopulated = databaseFieldsArePopulated();
-
- if (!dbPopulated) {
- // We don't even have everything filled out
- result = false;
- lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_incompleteFields());
- }
- return result;
- }
-
- /**
- * Tests whether or not the database settings are valid.
- *
- * @return True or false.
- */
- @Messages({"EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidHost=Invalid database hostname.",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidPort=Invalid database port number.",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidDbName=Invalid database name.",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidDbUser=Invalid database username.",
- "EnterpriseArtifactsManagerPostgresSettingsDialog.validation.invalidDbPassword=Invalid database password.",})
- private boolean databaseSettingsAreValid() {
-
- try {
- dbSettings.setHost(tbDbHostname.getText().trim());
- } catch (EamDbException ex) {
- lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidHost());
- return false;
- }
-
- try {
- dbSettings.setPort(Integer.valueOf(tbDbPort.getText().trim()));
- } catch (NumberFormatException | EamDbException ex) {
- lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidPort());
- return false;
- }
-
- try {
- dbSettings.setDbName(tbDbName.getText().trim());
- } catch (EamDbException ex) {
- lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidDbName());
- return false;
- }
-
- try {
- dbSettings.setUserName(tbDbUsername.getText().trim());
- } catch (EamDbException ex) {
- lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidDbUser());
- return false;
- }
-
- try {
- dbSettings.setPassword(tbDbPassword.getText().trim());
- } catch (EamDbException ex) {
- lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactsManagerPostgresSettingsDialog_validation_invalidDbPassword());
- return false;
- }
-
- return true;
- }
-
- /**
- * Validates that the form is filled out correctly for our usage.
- *
- * @return true if it's okay, false otherwise.
- */
- public boolean valid() {
- lbTestDatabaseWarning.setText("");
-
- return checkFields()
- && enableTestDatabaseButton(databaseSettingsAreValid())
- && enableSaveButton(databaseSettingsAreValid());
- }
-
- /**
- * Enables the "Test Connection" button to test the database settings.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableTestDatabaseButton(Boolean enable) {
- bnTestConnection.setEnabled(enable);
- return enable;
- }
-
- /**
- * Enables the "Save" button to save the database settings.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableSaveButton(Boolean enable) {
- bnSave.setEnabled(enable);
- return enable;
- }
-
- /**
- * Used to listen for changes in text boxes. It lets the panel know things
- * have been updated and that validation needs to happen.
- */
- private class TextBoxChangedListener implements DocumentListener {
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS
- if (statusIcon != null) {
- ((javax.swing.JLabel) statusIcon).setIcon(null);
- }
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- valid();
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS
- if (statusIcon != null) {
- ((javax.swing.JLabel) statusIcon).setIcon(null);
- }
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- valid();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS
- if (statusIcon != null) {
- ((javax.swing.JLabel) statusIcon).setIcon(null);
- }
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- valid();
- }
- }
-
- /**
- * This method is called from within the constructor to initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is always
- * regenerated by the Form Editor.
- */
- @SuppressWarnings("unchecked")
- // //GEN-BEGIN:initComponents
- private void initComponents() {
-
- pnOuter = new javax.swing.JPanel();
- jScrollPane = new javax.swing.JScrollPane();
- pnContent = new javax.swing.JPanel();
- lbHostName = new javax.swing.JLabel();
- lbPort = new javax.swing.JLabel();
- lbUserName = new javax.swing.JLabel();
- lbUserPassword = new javax.swing.JLabel();
- lbDatabaseName = new javax.swing.JLabel();
- tbDbHostname = new javax.swing.JTextField();
- tbDbPort = new javax.swing.JTextField();
- tbDbName = new javax.swing.JTextField();
- tbDbUsername = new javax.swing.JTextField();
- tbDbPassword = new javax.swing.JTextField();
- bnTestConnection = new javax.swing.JButton();
- bnSave = new javax.swing.JButton();
- bnCancel = new javax.swing.JButton();
- lbTestDatabaseWarning = new javax.swing.JLabel();
- lbTestDatabase = new javax.swing.JLabel();
-
- setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
-
- org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbHostName.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbPort.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbUserName.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbUserPassword.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbDatabaseName.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(bnTestConnection, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnTestConnection.text")); // NOI18N
- bnTestConnection.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnTestConnectionActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(bnSave, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnSave.text")); // NOI18N
- bnSave.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnSaveActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnCancel.text")); // NOI18N
- bnCancel.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnCancelActionPerformed(evt);
- }
- });
-
- lbTestDatabaseWarning.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
- lbTestDatabaseWarning.setForeground(new java.awt.Color(255, 0, 0));
-
- javax.swing.GroupLayout pnContentLayout = new javax.swing.GroupLayout(pnContent);
- pnContent.setLayout(pnContentLayout);
- pnContentLayout.setHorizontalGroup(
- pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addComponent(bnTestConnection)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(153, 153, 153)
- .addComponent(bnSave)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(bnCancel))
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnContentLayout.createSequentialGroup()
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbHostName)
- .addComponent(lbPort)
- .addComponent(lbDatabaseName)
- .addComponent(lbUserName)
- .addComponent(lbUserPassword))
- .addGap(18, 18, 18)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(tbDbPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
- .addComponent(tbDbUsername)
- .addComponent(tbDbName)
- .addComponent(tbDbHostname)
- .addComponent(tbDbPort, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)))))
- .addGap(0, 11, Short.MAX_VALUE))
- );
- pnContentLayout.setVerticalGroup(
- pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(tbDbPort)
- .addComponent(lbPort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(tbDbName)
- .addComponent(lbDatabaseName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(tbDbUsername)
- .addComponent(lbUserName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbUserPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(tbDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(37, 37, 37)
- .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(bnTestConnection)
- .addComponent(bnSave)
- .addComponent(bnCancel)
- .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(0, 0, Short.MAX_VALUE))
- );
-
- jScrollPane.setViewportView(pnContent);
-
- javax.swing.GroupLayout pnOuterLayout = new javax.swing.GroupLayout(pnOuter);
- pnOuter.setLayout(pnOuterLayout);
- pnOuterLayout.setHorizontalGroup(
- pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 448, Short.MAX_VALUE)
- .addGroup(pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOuterLayout.createSequentialGroup()
- .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 448, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, Short.MAX_VALUE)))
- );
- pnOuterLayout.setVerticalGroup(
- pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 249, Short.MAX_VALUE)
- .addGroup(pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOuterLayout.createSequentialGroup()
- .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, Short.MAX_VALUE)))
- );
-
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnOuter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnOuter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- );
-
- pack();
- }// //GEN-END:initComponents
-
- private void bnTestConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestConnectionActionPerformed
- lbTestDatabase.setIcon(null);
- lbTestDatabase.setText("");
- setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
- if (dbSettings.testSettings()) {
- lbTestDatabase.setIcon(goodIcon);
- } else {
- lbTestDatabase.setIcon(badIcon);
- }
-
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
-
- }//GEN-LAST:event_bnTestConnectionActionPerformed
-
- private void bnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnSaveActionPerformed
- hasChanged = true;
- dbSettings.setEnabled(true);
- dbSettings.saveSettings();
- dispose();
- }//GEN-LAST:event_bnSaveActionPerformed
-
- private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
- dispose();
- }//GEN-LAST:event_bnCancelActionPerformed
-
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton bnCancel;
- private javax.swing.JButton bnSave;
- private javax.swing.JButton bnTestConnection;
- private javax.swing.JScrollPane jScrollPane;
- private javax.swing.JLabel lbDatabaseName;
- private javax.swing.JLabel lbHostName;
- private javax.swing.JLabel lbPort;
- private javax.swing.JLabel lbTestDatabase;
- private javax.swing.JLabel lbTestDatabaseWarning;
- private javax.swing.JLabel lbUserName;
- private javax.swing.JLabel lbUserPassword;
- private javax.swing.JPanel pnContent;
- private javax.swing.JPanel pnOuter;
- private javax.swing.JTextField tbDbHostname;
- private javax.swing.JTextField tbDbName;
- private javax.swing.JTextField tbDbPassword;
- private javax.swing.JTextField tbDbPort;
- private javax.swing.JTextField tbDbUsername;
- // End of variables declaration//GEN-END:variables
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form
deleted file mode 100644
index 9ab466696d..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.form
+++ /dev/null
@@ -1,218 +0,0 @@
-
-
-
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java
deleted file mode 100644
index e46288dd21..0000000000
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/EamSqliteSettingsDialog.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Enterprise Artifacts Manager
- *
- * Copyright 2015-2017 Basis Technology Corp.
- * Contact: carrier sleuthkit 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.experimental.enterpriseartifactsmanager.optionspanel;
-
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Toolkit;
-import java.io.File;
-import java.io.IOException;
-import java.util.logging.Level;
-import javax.swing.ImageIcon;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.filechooser.FileNameExtensionFilter;
-import org.netbeans.spi.options.OptionsPanelController;
-import org.openide.util.ImageUtilities;
-import org.openide.util.NbBundle.Messages;
-import org.openide.windows.WindowManager;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbException;
-import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.SqliteEamDbSettings;
-
-/**
- * Settings panel for the sqlite-specific options
- */
-public class EamSqliteSettingsDialog extends javax.swing.JDialog {
-
- private static final Logger LOGGER = Logger.getLogger(EamSqliteSettingsDialog.class.getName());
- private final ImageIcon goodIcon;
- private final ImageIcon badIcon;
- private final TextBoxChangedListener textBoxChangedListener;
-
- private final SqliteEamDbSettings dbSettings;
- private Boolean hasChanged;
-
- /**
- * Creates new form EnterpriseArtifactsManagerSQLiteSettingsDialog
- */
- @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.sqliteSettingsMessage.text=SQLite Database Settings"})
- public EamSqliteSettingsDialog() {
- super((JFrame) WindowManager.getDefault().getMainWindow(),
- Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_sqliteSettingsMessage_text(),
- true); // NON-NLS
-
- this.dbSettings = new SqliteEamDbSettings();
- goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS
- badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS
- textBoxChangedListener = new TextBoxChangedListener();
-
- initComponents();
- customizeComponents();
- valid();
- display();
- }
-
- /**
- * Let calling object determine if this dialog made any changes.
- *
- * @return true or false
- */
- public Boolean isChanged() {
- return hasChanged;
- }
-
- private void customizeComponents() {
- customizeFileChooser();
- tfDatabasePath.setText(dbSettings.getFileNameWithPath());
- lbTestDatabaseWarning.setText("");
- hasChanged = false;
- tfDatabasePath.getDocument().addDocumentListener(textBoxChangedListener);
- bnSave.setEnabled(false);
- bnTestDatabase.setEnabled(false);
- }
-
- @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.fileNameExtFilter.text=SQLite Database File"})
- private void customizeFileChooser() {
- fcDatabasePath.setDragEnabled(false);
- fcDatabasePath.setFileSelectionMode(JFileChooser.FILES_ONLY);
- String[] EXTENSION = new String[]{"db"}; //NON-NLS
- FileNameExtensionFilter filter = new FileNameExtensionFilter(Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_fileNameExtFilter_text(), EXTENSION); // NON-NLS
- fcDatabasePath.setFileFilter(filter);
- fcDatabasePath.setMultiSelectionEnabled(false);
- }
-
- private void display() {
- Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
- setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
- setVisible(true);
- }
-
- /**
- * Used to listen for changes in text boxes. It lets the panel know things
- * have been updated and that validation needs to happen.
- */
- private class TextBoxChangedListener implements DocumentListener {
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- valid();
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- valid();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- valid();
- }
- }
-
- private boolean valid() {
- boolean result = false;
- if (tfDatabasePath.getText().trim().isEmpty()) {
- bnSave.setEnabled(false);
- bnTestDatabase.setEnabled(false);
- } else {
- storeDbNameAndDirectory();
- bnSave.setEnabled(true);
- bnTestDatabase.setEnabled(true);
- result = true;
- }
- return result;
- }
-
- /**
- * Get the db file name and directory path from the file chooser and store
- * in dbSettings.
- */
- @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.storeDbNameAndDirectory.failedToSetDbNamePathMsg=Database filename or directory path is missing. Try again."})
- private void storeDbNameAndDirectory() {
- File databasePath = new File(tfDatabasePath.getText());
- try {
- dbSettings.setDbName(databasePath.getName());
- dbSettings.setDbDirectory(databasePath.getParent());
- } catch (EamDbException ex) {
- LOGGER.log(Level.SEVERE, "Failed to set database name or directory path.", ex); // NON-NLS
- JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_storeDbNameAndDirectory_failedToSetDbNamePathMsg());
- }
- }
-
- /**
- * This method is called from within the constructor to initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is always
- * regenerated by the Form Editor.
- */
- @SuppressWarnings("unchecked")
- // //GEN-BEGIN:initComponents
- private void initComponents() {
-
- fcDatabasePath = new javax.swing.JFileChooser();
- pnOuter = new javax.swing.JPanel();
- jScrollPane = new javax.swing.JScrollPane();
- pnContent = new javax.swing.JPanel();
- lbDatabasePath = new javax.swing.JLabel();
- tfDatabasePath = new javax.swing.JTextField();
- bnDatabasePathFileOpen = new javax.swing.JButton();
- lbTestDatabaseWarning = new javax.swing.JLabel();
- bnTestDatabase = new javax.swing.JButton();
- lbTestDatabase = new javax.swing.JLabel();
- bnCancel = new javax.swing.JButton();
- bnSave = new javax.swing.JButton();
-
- setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
-
- org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbDatabasePath.text")); // NOI18N
-
- tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.tfDatabasePath.text")); // NOI18N
- tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N
- bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnDatabasePathFileOpenActionPerformed(evt);
- }
- });
-
- lbTestDatabaseWarning.setForeground(new java.awt.Color(255, 51, 51));
- org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabaseWarning, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbTestDatabaseWarning.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(bnTestDatabase, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnTestDatabase.text")); // NOI18N
- bnTestDatabase.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnTestDatabaseActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabase, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbTestDatabase.text")); // NOI18N
- lbTestDatabase.setName(""); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnCancel.text")); // NOI18N
- bnCancel.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnCancelActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(bnSave, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnSave.text")); // NOI18N
- bnSave.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnSaveActionPerformed(evt);
- }
- });
-
- javax.swing.GroupLayout pnContentLayout = new javax.swing.GroupLayout(pnContent);
- pnContent.setLayout(pnContentLayout);
- pnContentLayout.setHorizontalGroup(
- pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addComponent(lbDatabasePath)
- .addGap(18, 18, 18)
- .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 57, Short.MAX_VALUE)
- .addComponent(bnDatabasePathFileOpen)
- .addGap(24, 24, 24))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnContentLayout.createSequentialGroup()
- .addComponent(bnTestDatabase)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(bnSave)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(bnCancel)
- .addContainerGap())))
- );
- pnContentLayout.setVerticalGroup(
- pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(bnDatabasePathFileOpen))
- .addGap(18, 18, 18)
- .addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnContentLayout.createSequentialGroup()
- .addGap(19, 19, 19)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(bnCancel)
- .addComponent(bnSave)))
- .addGroup(pnContentLayout.createSequentialGroup()
- .addGap(18, 18, 18)
- .addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(bnTestDatabase))))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
-
- jScrollPane.setViewportView(pnContent);
-
- javax.swing.GroupLayout pnOuterLayout = new javax.swing.GroupLayout(pnOuter);
- pnOuter.setLayout(pnOuterLayout);
- pnOuterLayout.setHorizontalGroup(
- pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane)
- );
- pnOuterLayout.setVerticalGroup(
- pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- );
-
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 603, Short.MAX_VALUE)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnOuter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 129, Short.MAX_VALUE)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(pnOuter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, Short.MAX_VALUE)))
- );
-
- pack();
- }// //GEN-END:initComponents
-
- @Messages({"EnterpriseArtifactsManagerSQLiteSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."})
- private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed
- if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
- File databaseFile = fcDatabasePath.getSelectedFile();
- try {
- tfDatabasePath.setText(databaseFile.getCanonicalPath());
- valid();
-
- } catch (IOException ex) {
- LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS
- JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactsManagerSQLiteSettingsDialog_chooserPath_failedToGetDbPathMsg());
- }
- }
- }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed
-
- private void bnTestDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestDatabaseActionPerformed
- lbTestDatabase.setIcon(null);
- lbTestDatabaseWarning.setText("");
- setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-
- if (dbSettings.testSettings()) {
- lbTestDatabase.setIcon(goodIcon);
- } else {
- lbTestDatabase.setIcon(badIcon);
- }
-
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- }//GEN-LAST:event_bnTestDatabaseActionPerformed
-
- private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
- dispose();
- }//GEN-LAST:event_bnCancelActionPerformed
-
- private void bnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnSaveActionPerformed
- hasChanged = true;
- dbSettings.setEnabled(true);
- dbSettings.saveSettings();
- dispose();
- }//GEN-LAST:event_bnSaveActionPerformed
-
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton bnCancel;
- private javax.swing.JButton bnDatabasePathFileOpen;
- private javax.swing.JButton bnSave;
- private javax.swing.JButton bnTestDatabase;
- private javax.swing.JFileChooser fcDatabasePath;
- private javax.swing.JScrollPane jScrollPane;
- private javax.swing.JLabel lbDatabasePath;
- private javax.swing.JLabel lbTestDatabase;
- private javax.swing.JLabel lbTestDatabaseWarning;
- private javax.swing.JPanel pnContent;
- private javax.swing.JPanel pnOuter;
- private javax.swing.JTextField tfDatabasePath;
- // End of variables declaration//GEN-END:variables
-}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form
index 29154fc5ea..02edd5748e 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.form
@@ -19,259 +19,226 @@
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java
index b0a2624224..ca37fc5f03 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/GlobalSettingsPanel.java
@@ -21,8 +21,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.optionspan
import org.sleuthkit.autopsy.coreutils.Logger;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import javax.swing.JComboBox;
-import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle.Messages;
@@ -32,7 +30,8 @@ import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum;
-import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDb;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.PostgresEamDbSettings;
+import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.SqliteEamDbSettings;
/**
* Main settings panel for the enterprise artifacts manager
@@ -44,10 +43,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private final IngestJobEventPropertyChangeListener ingestJobEventListener;
- private boolean dbConfigured;
- private boolean initiallyEnabled;
- private boolean comboboxSelectDatabaseTypeActionListenerActive;
-
/**
* Creates new form EnterpriseArtifactsManagerOptionsPanel
*/
@@ -62,12 +57,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
@Messages({"GlobalSettingsPanel.title=Global Enterprise Artifacts Manager Settings"})
private void customizeComponents() {
setName(Bundle.GlobalSettingsPanel_title());
- comboboxSelectDatabaseTypeActionListenerActive = false; // don't fire action listener while loading combobox content
- comboboxSelectDatabaseType.removeAllItems();
- for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
- comboboxSelectDatabaseType.addItem(p.toString());
- }
- comboboxSelectDatabaseTypeActionListenerActive = true;
}
private void addIngestJobEventsListener() {
@@ -84,22 +73,77 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
// //GEN-BEGIN:initComponents
private void initComponents() {
- jScrollPane = new javax.swing.JScrollPane();
- pnOverallPanel = new javax.swing.JPanel();
- pnSettings = new javax.swing.JPanel();
+ pnDatabaseConfiguration = new javax.swing.JPanel();
+ lbDbPlatformTypeLabel = new javax.swing.JLabel();
+ lbDbNameLabel = new javax.swing.JLabel();
+ lbDbLocationLabel = new javax.swing.JLabel();
+ bnDbConfigure = new javax.swing.JButton();
+ lbDbPlatformValue = new javax.swing.JLabel();
+ lbDbNameValue = new javax.swing.JLabel();
+ lbDbLocationValue = new javax.swing.JLabel();
+ pnDatabaseContentButtons = new javax.swing.JPanel();
bnImportDatabase = new javax.swing.JButton();
- pnDatabaseConnectionSettings = new javax.swing.JPanel();
- comboboxSelectDatabaseType = new javax.swing.JComboBox<>();
- lbDatabasePlatform = new javax.swing.JLabel();
- bnConfigureDatabaseSettings = new javax.swing.JButton();
- tbOops = new javax.swing.JTextField();
bnManageTags = new javax.swing.JButton();
bnManageTypes = new javax.swing.JButton();
- cbEnableEnterpriseArtifactsManager = new javax.swing.JCheckBox();
+ tbOops = new javax.swing.JTextField();
setName(""); // NOI18N
- jScrollPane.setBorder(null);
+ pnDatabaseConfiguration.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnDatabaseConfiguration.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbDbPlatformTypeLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDbPlatformTypeLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbDbNameLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDbNameLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lbDbLocationLabel, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDbLocationLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(bnDbConfigure, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnDbConfigure.text")); // NOI18N
+ bnDbConfigure.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ bnDbConfigureActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnDatabaseConfigurationLayout = new javax.swing.GroupLayout(pnDatabaseConfiguration);
+ pnDatabaseConfiguration.setLayout(pnDatabaseConfigurationLayout);
+ pnDatabaseConfigurationLayout.setHorizontalGroup(
+ pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbDbNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lbDbNameValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(lbDbLocationValue, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 711, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addComponent(bnDbConfigure))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ pnDatabaseConfigurationLayout.setVerticalGroup(
+ pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseConfigurationLayout.createSequentialGroup()
+ .addGap(7, 7, 7)
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbDbPlatformTypeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbDbPlatformValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbDbNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbDbNameValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnDatabaseConfigurationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lbDbLocationLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lbDbLocationValue, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
+ .addComponent(bnDbConfigure)
+ .addContainerGap())
+ );
bnImportDatabase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/images/import16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnImportDatabase, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnImportDatabase.label")); // NOI18N
@@ -110,54 +154,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
}
});
- pnDatabaseConnectionSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDatabaseSettings.text"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
- pnDatabaseConnectionSettings.setName(""); // NOI18N
-
- comboboxSelectDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "test 1", "test 2" }));
- comboboxSelectDatabaseType.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- comboboxSelectDatabaseTypeActionPerformed(evt);
- }
- });
-
- org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePlatform, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.lbDatabasePlatform.text")); // NOI18N
-
- org.openide.awt.Mnemonics.setLocalizedText(bnConfigureDatabaseSettings, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnConfigureDatabaseSettings.text")); // NOI18N
- bnConfigureDatabaseSettings.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- bnConfigureDatabaseSettingsActionPerformed(evt);
- }
- });
-
- javax.swing.GroupLayout pnDatabaseConnectionSettingsLayout = new javax.swing.GroupLayout(pnDatabaseConnectionSettings);
- pnDatabaseConnectionSettings.setLayout(pnDatabaseConnectionSettingsLayout);
- pnDatabaseConnectionSettingsLayout.setHorizontalGroup(
- pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConnectionSettingsLayout.createSequentialGroup()
- .addContainerGap()
- .addComponent(lbDatabasePlatform)
- .addGap(18, 18, 18)
- .addComponent(comboboxSelectDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(bnConfigureDatabaseSettings)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
- pnDatabaseConnectionSettingsLayout.setVerticalGroup(
- pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup()
- .addGap(3, 3, 3)
- .addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lbDatabasePlatform, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(comboboxSelectDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(bnConfigureDatabaseSettings)))
- );
-
- tbOops.setEditable(false);
- tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
- tbOops.setForeground(new java.awt.Color(255, 0, 0));
- tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
- tbOops.setBorder(null);
-
org.openide.awt.Mnemonics.setLocalizedText(bnManageTags, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.text")); // NOI18N
bnManageTags.setToolTipText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.toolTipText")); // NOI18N
bnManageTags.setActionCommand(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.bnManageTags.actionCommand")); // NOI18N
@@ -174,229 +170,130 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
}
});
- javax.swing.GroupLayout pnSettingsLayout = new javax.swing.GroupLayout(pnSettings);
- pnSettings.setLayout(pnSettingsLayout);
- pnSettingsLayout.setHorizontalGroup(
- pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnSettingsLayout.createSequentialGroup()
+ javax.swing.GroupLayout pnDatabaseContentButtonsLayout = new javax.swing.GroupLayout(pnDatabaseContentButtons);
+ pnDatabaseContentButtons.setLayout(pnDatabaseContentButtonsLayout);
+ pnDatabaseContentButtonsLayout.setHorizontalGroup(
+ pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup()
.addContainerGap()
- .addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(tbOops)
- .addGroup(pnSettingsLayout.createSequentialGroup()
- .addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGroup(pnSettingsLayout.createSequentialGroup()
- .addComponent(bnImportDatabase)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(bnManageTags)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(bnManageTypes)))
- .addGap(0, 188, Short.MAX_VALUE)))
- .addContainerGap())
- );
- pnSettingsLayout.setVerticalGroup(
- pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnSettingsLayout.createSequentialGroup()
- .addGap(8, 8, 8)
- .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(bnImportDatabase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 33, Short.MAX_VALUE)
- .addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(bnManageTags)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(bnManageTypes)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ pnDatabaseContentButtonsLayout.setVerticalGroup(
+ pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnImportDatabase)
.addComponent(bnManageTags, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnManageTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(34, 34, 34))
);
- cbEnableEnterpriseArtifactsManager.setFont(cbEnableEnterpriseArtifactsManager.getFont().deriveFont(cbEnableEnterpriseArtifactsManager.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
- org.openide.awt.Mnemonics.setLocalizedText(cbEnableEnterpriseArtifactsManager, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text")); // NOI18N
- cbEnableEnterpriseArtifactsManager.addItemListener(new java.awt.event.ItemListener() {
- public void itemStateChanged(java.awt.event.ItemEvent evt) {
- cbEnableEnterpriseArtifactsManagerItemStateChanged(evt);
- }
- });
-
- javax.swing.GroupLayout pnOverallPanelLayout = new javax.swing.GroupLayout(pnOverallPanel);
- pnOverallPanel.setLayout(pnOverallPanelLayout);
- pnOverallPanelLayout.setHorizontalGroup(
- pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOverallPanelLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(pnOverallPanelLayout.createSequentialGroup()
- .addComponent(cbEnableEnterpriseArtifactsManager, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, Short.MAX_VALUE))
- .addComponent(pnSettings, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
- );
- pnOverallPanelLayout.setVerticalGroup(
- pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnOverallPanelLayout.createSequentialGroup()
- .addComponent(cbEnableEnterpriseArtifactsManager)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(pnSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- );
-
- jScrollPane.setViewportView(pnOverallPanel);
+ tbOops.setEditable(false);
+ tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
+ tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
+ tbOops.setBorder(null);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(tbOops, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(jScrollPane)
- .addGap(2, 2, 2))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(pnDatabaseConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pnDatabaseContentButtons, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 18, Short.MAX_VALUE))
);
}// //GEN-END:initComponents
- private void cbEnableEnterpriseArtifactsManagerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbEnableEnterpriseArtifactsManagerItemStateChanged
- tbOops.setText("");
- if (!cbEnableEnterpriseArtifactsManager.isSelected()) {
- enableAllSubComponents(false);
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- } else {
- enableDatabaseSubComponents(true);
- validateDatabaseSettings();
- }
- }//GEN-LAST:event_cbEnableEnterpriseArtifactsManagerItemStateChanged
-
private void bnImportDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnImportDatabaseActionPerformed
ImportHashDatabaseDialog dialog = new ImportHashDatabaseDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnImportDatabaseActionPerformed
- /**
- * When the "Configure" button is clicked, open the proper dialog.
- *
- * @param evt Button event
- */
- @Messages({"GlobalSettingsPanel.configureButton.errorLabel=You must select a valid platform in the drop down box.",
- "GlobalSettingsPanel.configureButton.errorTitle=Invalid platform selection."})
- private void bnConfigureDatabaseSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnConfigureDatabaseSettingsActionPerformed
- EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
- Boolean dbConfigChanged = false;
-
- switch (selectedPlatform) {
- case SQLITE:
- EamSqliteSettingsDialog dialogS = new EamSqliteSettingsDialog();
- dbConfigChanged = dialogS.isChanged();
- break;
-
- case POSTGRESQL:
- EamPostgresSettingsDialog dialogP = new EamPostgresSettingsDialog();
- dbConfigChanged = dialogP.isChanged();
- break;
-
- default:
- JOptionPane.showMessageDialog(null, Bundle.GlobalSettingsPanel_configureButton_errorLabel(),
- Bundle.GlobalSettingsPanel_configureButton_errorTitle(),
- JOptionPane.ERROR_MESSAGE);
- break;
- }
-
- if (dbConfigChanged) {
- if (initiallyEnabled || dbConfigured) {
- enableButtonSubComponents(false);
- }
- dbConfigured = true;
- firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
- }
- }//GEN-LAST:event_bnConfigureDatabaseSettingsActionPerformed
-
- /**
- * When there is a change to the combobox, update the selectedPlatform.
- *
- * @param evt
- */
- @SuppressWarnings({"unchecked cast", "unchecked"})
- private void comboboxSelectDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboboxSelectDatabaseTypeActionPerformed
- if (comboboxSelectDatabaseTypeActionListenerActive) {
- JComboBox cb = (JComboBox) evt.getSource();
- String platformName = (String) cb.getSelectedItem();
- EamDbPlatformEnum.setSelectedPlatform(platformName);
- }
- }//GEN-LAST:event_comboboxSelectDatabaseTypeActionPerformed
-
private void bnManageTagsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTagsActionPerformed
ManageTagsDialog dialog = new ManageTagsDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnManageTagsActionPerformed
private void bnManageTypesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTypesActionPerformed
- ManageArtifactTypesDialog dialogT = new ManageArtifactTypesDialog();
+ ManageArtifactTypesDialog dialog = new ManageArtifactTypesDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnManageTypesActionPerformed
+ private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed
+ EamDbSettingsDialog dialog = new EamDbSettingsDialog();
+ load(); // reload db settings content and update buttons
+ }//GEN-LAST:event_bnDbConfigureActionPerformed
+
@Override
+ @Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."})
public void load() {
tbOops.setText("");
enableAllSubComponents(false);
-
- initiallyEnabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS
- cbEnableEnterpriseArtifactsManager.setSelected(initiallyEnabled); // NON-NLS
- String selectedPlatformString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.selectedPlatform"); // NON-NLS
- dbConfigured = selectedPlatformString != null;
-
- if (dbConfigured) {
- comboboxSelectDatabaseTypeActionListenerActive = false; // don't fire action listener while configuring combobox content
- comboboxSelectDatabaseType.setSelectedIndex(EamDbPlatformEnum.getSelectedPlatform().ordinal());
- comboboxSelectDatabaseTypeActionListenerActive = true; // don't fire action listener while loading combobox content
- }
- if (this.valid() && initiallyEnabled) {
- enableButtonSubComponents(true);
+ EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
+
+ switch (selectedPlatform) {
+ case POSTGRESQL:
+ PostgresEamDbSettings dbSettingsPg = new PostgresEamDbSettings();
+ lbDbPlatformValue.setText(EamDbPlatformEnum.POSTGRESQL.toString());
+ lbDbNameValue.setText(dbSettingsPg.getDbName());
+ lbDbLocationValue.setText(dbSettingsPg.getHost());
+ enableAllSubComponents(true);
+ break;
+ case SQLITE:
+ SqliteEamDbSettings dbSettingsSqlite = new SqliteEamDbSettings();
+ lbDbPlatformValue.setText(EamDbPlatformEnum.SQLITE.toString());
+ lbDbNameValue.setText(dbSettingsSqlite.getDbName());
+ lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory());
+ enableAllSubComponents(true);
+ break;
+ default:
+ lbDbPlatformValue.setText(EamDbPlatformEnum.DISABLED.toString());
+ lbDbNameValue.setText("");
+ lbDbLocationValue.setText("");
+ enableDatabaseConfigureButton(true);
+ tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure());
+ break;
}
+
this.ingestStateUpdated();
}
@Override
public void store() { // Click OK or Apply on Options Panel
- saveSettings();
}
/**
- * Validates that the form is filled out correctly for our usage.
+ * Validates that the dialog/panel is filled out correctly for our usage.
*
* @return true if it's okay, false otherwise.
*/
- boolean valid() {
- tbOops.setText("");
-
- if (cbEnableEnterpriseArtifactsManager.isSelected()) {
- return validateDatabaseSettings();
- } else {
- return true;
- }
- }
-
- /**
- * Validate the Database Settings panel
- *
- * @return true or false
- */
- @Messages({"GlobalSettingsPanel.validate.mustConfigureDb.text=You must configure the database."})
- private boolean validateDatabaseSettings() {
- if (!dbConfigured) {
- tbOops.setText(Bundle.GlobalSettingsPanel_validate_mustConfigureDb_text());
- return false;
- }
-
+ public boolean valid() {
return true;
}
@Override
public void saveSettings() { // Click OK on Global Settings Panel
- ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.enabled", Boolean.toString(cbEnableEnterpriseArtifactsManager.isSelected())); // NON-NLS
- if (cbEnableEnterpriseArtifactsManager.isSelected()) {
- EamDbPlatformEnum.saveSelectedPlatform();
- EamDb dbManager = EamDb.getInstance();
- dbManager.updateSettings();
- enableButtonSubComponents(true);
- }
}
@Override
@@ -426,7 +323,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
}
};
- @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=Cannot change settings while ingest is running."})
+ @Messages({"GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running."})
private void ingestStateUpdated() {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(() -> {
@@ -437,13 +334,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
}
if (IngestManager.getInstance().isIngestRunning()) {
- cbEnableEnterpriseArtifactsManager.setEnabled(false);
tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning());
enableAllSubComponents(false);
- } else {
- cbEnableEnterpriseArtifactsManager.setEnabled(true);
- tbOops.setText("");
- enableAllSubComponents(cbEnableEnterpriseArtifactsManager.isSelected());
}
}
@@ -456,22 +348,20 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
* @return True
*/
private boolean enableAllSubComponents(Boolean enable) {
- enableDatabaseSubComponents(enable);
+ enableDatabaseConfigureButton(enable);
enableButtonSubComponents(enable);
return true;
}
/**
- * Wrapper around each of the enableXYZ methods that configure the database
- * to enable/disable them all at the same time.
+ * Enable the Configure button
*
* @param enable
*
* @return True
*/
- private boolean enableDatabaseSubComponents(Boolean enable) {
- enableDatabasePlatformComboBox(enable);
- enableConfigureDatabasePlatformButton(enable);
+ private boolean enableDatabaseConfigureButton(Boolean enable) {
+ bnDbConfigure.setEnabled(enable);
return true;
}
@@ -484,84 +374,25 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
* @return True
*/
private boolean enableButtonSubComponents(Boolean enable) {
- enableManageCorrelationTypesButton(enable);
- enableImportGloballyKnownArtifactsButton(enable);
- enableManageTagsButton(enable);
+ bnManageTypes.setEnabled(enable);
+ bnImportDatabase.setEnabled(enable);
+ bnManageTags.setEnabled(enable);
return true;
}
- /**
- * Enables the ComboBox used to select the database platform.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableDatabasePlatformComboBox(Boolean enable) {
- comboboxSelectDatabaseType.setEnabled(enable);
- return enable;
- }
-
- /**
- * Enables the "Configure" button used to configure the database platform.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableConfigureDatabasePlatformButton(Boolean enable) {
- bnConfigureDatabaseSettings.setEnabled(enable);
- return enable;
- }
-
- /**
- * Enables the "Import Globally Known Artifacts" button.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableImportGloballyKnownArtifactsButton(Boolean enable) {
- bnImportDatabase.setEnabled(enable);
- return enable;
- }
-
- /**
- * Enables the "Manage Artifact Types" button.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableManageCorrelationTypesButton(Boolean enable) {
- bnManageTypes.setEnabled(enable);
- return enable;
- }
-
- /**
- * Enables the "Manage Tags" button.
- *
- * @param enable
- *
- * @return True or False
- */
- private boolean enableManageTagsButton(Boolean enable) {
- bnManageTags.setEnabled(enable);
- return enable;
- }
-
// Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton bnConfigureDatabaseSettings;
+ private javax.swing.JButton bnDbConfigure;
private javax.swing.JButton bnImportDatabase;
private javax.swing.JButton bnManageTags;
private javax.swing.JButton bnManageTypes;
- private javax.swing.JCheckBox cbEnableEnterpriseArtifactsManager;
- private javax.swing.JComboBox comboboxSelectDatabaseType;
- private javax.swing.JScrollPane jScrollPane;
- private javax.swing.JLabel lbDatabasePlatform;
- private javax.swing.JPanel pnDatabaseConnectionSettings;
- private javax.swing.JPanel pnOverallPanel;
- private javax.swing.JPanel pnSettings;
+ private javax.swing.JLabel lbDbLocationLabel;
+ private javax.swing.JLabel lbDbLocationValue;
+ private javax.swing.JLabel lbDbNameLabel;
+ private javax.swing.JLabel lbDbNameValue;
+ private javax.swing.JLabel lbDbPlatformTypeLabel;
+ private javax.swing.JLabel lbDbPlatformValue;
+ private javax.swing.JPanel pnDatabaseConfiguration;
+ private javax.swing.JPanel pnDatabaseContentButtons;
private javax.swing.JTextField tbOops;
// End of variables declaration//GEN-END:variables
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java
index e1927401cd..8e40524923 100644
--- a/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/ImportHashDatabaseDialog.java
@@ -119,8 +119,11 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
orgs = dbManager.getOrganizations();
orgs.forEach((org) -> {
comboboxSourceOrganization.addItem(org.getName());
- selectedOrg = orgs.get(0);
});
+ if (!orgs.isEmpty()) {
+ selectedOrg = orgs.get(0);
+ }
+ valid();
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failure populating combobox with organizations.", ex);
}
@@ -178,12 +181,12 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
public boolean valid() {
lbWarningMsg.setText("");
EamDb dbManager = EamDb.getInstance();
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
lbWarningMsg.setText(Bundle.ImportHashDatabaseDialog_validation_notEnabled());
return false;
}
- return enableOkButton(checkFields());
+ return enableOkButton(checkFields() && null != selectedOrg);
}
/**
@@ -545,6 +548,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
return;
}
}
+ valid();
}//GEN-LAST:event_comboboxSourceOrganizationActionPerformed
@NbBundle.Messages({"ImportHashDatabaseDialog.ImportHashDatabaseWorker.displayName=Importing Hash Database"})
@@ -561,7 +565,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
this.knownStatus = knownStatus;
this.globalSetID = globalSetID;
- if (!dbManager.isEnabled()) {
+ if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager database settings were not properly initialized"); // NON-NLS
}
}