Merge remote-tracking branch 'upstream/release-4.4.1' into develop

This commit is contained in:
Richard Cordovano 2017-06-22 12:25:31 -04:00
commit bcb3784c27
35 changed files with 3294 additions and 3161 deletions

View File

@ -20,8 +20,6 @@ ServicesMonitor.statusChange.notify.title=Service Status Update
ServicesMonitor.statusChange.notify.msg=Status for {0} is {1} ServicesMonitor.statusChange.notify.msg=Status for {0} is {1}
ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null
ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown 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.KeywordSearchNull=Cannot find Keyword Search service
ServicesMonitor.InvalidPortNumber=Invalid port number. ServicesMonitor.InvalidPortNumber=Invalid port number.
ServicesMonitor.remoteCaseDatabase.displayName.text=Multi-user case database service ServicesMonitor.remoteCaseDatabase.displayName.text=Multi-user case database service

View File

@ -18,20 +18,16 @@
*/ */
package org.sleuthkit.autopsy.core; package org.sleuthkit.autopsy.core;
import java.util.Base64; import org.sleuthkit.autopsy.coreutils.TextConverter;
import java.util.prefs.BackingStoreException; import java.util.prefs.BackingStoreException;
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo; import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
import java.util.prefs.PreferenceChangeListener; import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import javax.crypto.Cipher; import org.openide.util.Exceptions;
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.NbPreferences; import org.openide.util.NbPreferences;
import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.TextConverterException;
import org.sleuthkit.autopsy.coreutils.Version; import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.datamodel.CaseDbConnectionInfo; import org.sleuthkit.datamodel.CaseDbConnectionInfo;
import org.sleuthkit.datamodel.TskData.DbType; import org.sleuthkit.datamodel.TskData.DbType;
@ -205,12 +201,16 @@ public final class UserPreferences {
} catch (Exception ex) { } catch (Exception ex) {
dbType = DbType.SQLITE; dbType = DbType.SQLITE;
} }
try {
return new CaseDbConnectionInfo( return new CaseDbConnectionInfo(
preferences.get(EXTERNAL_DATABASE_HOSTNAME_OR_IP, ""), preferences.get(EXTERNAL_DATABASE_HOSTNAME_OR_IP, ""),
preferences.get(EXTERNAL_DATABASE_PORTNUMBER, "5432"), preferences.get(EXTERNAL_DATABASE_PORTNUMBER, "5432"),
preferences.get(EXTERNAL_DATABASE_USER, ""), preferences.get(EXTERNAL_DATABASE_USER, ""),
TextConverter.convertHexTextToText(preferences.get(EXTERNAL_DATABASE_PASSWORD, "")), TextConverter.convertHexTextToText(preferences.get(EXTERNAL_DATABASE_PASSWORD, "")),
dbType); 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_HOSTNAME_OR_IP, connectionInfo.getHost());
preferences.put(EXTERNAL_DATABASE_PORTNUMBER, connectionInfo.getPort()); preferences.put(EXTERNAL_DATABASE_PORTNUMBER, connectionInfo.getPort());
preferences.put(EXTERNAL_DATABASE_USER, connectionInfo.getUserName()); preferences.put(EXTERNAL_DATABASE_USER, connectionInfo.getUserName());
try {
preferences.put(EXTERNAL_DATABASE_PASSWORD, TextConverter.convertTextToHexText(connectionInfo.getPassword())); 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()); 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_HOST, info.getHost());
preferences.put(MESSAGE_SERVICE_PORT, Integer.toString(info.getPort())); preferences.put(MESSAGE_SERVICE_PORT, Integer.toString(info.getPort()));
preferences.put(MESSAGE_SERVICE_USER, info.getUserName()); preferences.put(MESSAGE_SERVICE_USER, info.getUserName());
try {
preferences.put(MESSAGE_SERVICE_PASSWORD, TextConverter.convertTextToHexText(info.getPassword())); 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; port = DEFAULT_PORT_INT;
} }
try {
return new MessageServiceConnectionInfo( return new MessageServiceConnectionInfo(
preferences.get(MESSAGE_SERVICE_HOST, ""), preferences.get(MESSAGE_SERVICE_HOST, ""),
port, port,
preferences.get(MESSAGE_SERVICE_USER, ""), preferences.get(MESSAGE_SERVICE_USER, ""),
TextConverter.convertHexTextToText(preferences.get(MESSAGE_SERVICE_PASSWORD, ""))); 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); 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);
}
}
} }

View File

@ -45,25 +45,15 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="1" max="32767" attributes="0"/> <Component id="jPanel1" pref="622" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="1" max="32767" attributes="0"/> <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[622, 58]"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1"> <Container class="javax.swing.JPanel" name="jPanel1">
<Properties> <Properties>
@ -90,14 +80,14 @@
<Component id="prevPageButton" min="-2" pref="23" max="-2" attributes="0"/> <Component id="prevPageButton" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/> <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="nextPageButton" min="-2" pref="23" max="-2" attributes="0"/> <Component id="nextPageButton" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/> <EmptySpace pref="366" max="32767" attributes="0"/>
</Group> </Group>
<Component id="resultsTableScrollPane" alignment="1" max="32767" attributes="0"/> <Component id="resultsTableScrollPane" alignment="1" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> <Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace pref="277" max="32767" attributes="0"/> <EmptySpace pref="280" max="32767" attributes="0"/>
<Component id="artifactLabel" min="-2" pref="258" max="-2" attributes="0"/> <Component id="artifactLabel" min="-2" pref="258" max="-2" attributes="0"/>
<EmptySpace pref="85" max="32767" attributes="0"/> <EmptySpace pref="84" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -116,13 +106,14 @@
<Component id="prevPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/> <Component id="prevPageButton" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="pageLabel2" min="-2" max="-2" attributes="0"/> <Component id="pageLabel2" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="resultsTableScrollPane" pref="34" max="32767" attributes="0"/> <Component id="resultsTableScrollPane" pref="29" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group> </Group>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> <Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="artifactLabel" min="-2" pref="23" max="-2" attributes="0"/> <Component id="artifactLabel" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace min="0" pref="40" max="32767" attributes="0"/> <EmptySpace min="0" pref="401" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -247,8 +238,9 @@
</Component> </Component>
<Container class="javax.swing.JScrollPane" name="resultsTableScrollPane"> <Container class="javax.swing.JScrollPane" name="resultsTableScrollPane">
<Properties> <Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[620, 271]"/> <Dimension value="[620, 34]"/>
</Property> </Property>
</Properties> </Properties>
<AuxValues> <AuxValues>
@ -262,6 +254,4 @@
</SubComponents> </SubComponents>
</Container> </Container>
</SubComponents> </SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2011-2013 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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.awt.datatransfer.StringSelection;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.Lookup; 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 * 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. * representation of its BlackboardAttributes.
*/ */
@ServiceProvider(service = DataContentViewer.class, position = 3) @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_type(),
Bundle.DataContentViewerArtifact_attrsTableHeader_value(), Bundle.DataContentViewerArtifact_attrsTableHeader_value(),
Bundle.DataContentViewerArtifact_attrsTableHeader_sources()}; Bundle.DataContentViewerArtifact_attrsTableHeader_sources()};
private static final int[] COLUMN_WIDTHS = {100, 800, 100};
public DataContentViewerArtifact() { public DataContentViewerArtifact() {
initResultsTable(); initResultsTable();
@ -86,30 +89,32 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private void initResultsTable() { private void initResultsTable() {
resultsTable = new ETable(); resultsTable = new ETable();
resultsTable.setModel(new javax.swing.table.DefaultTableModel() { resultsTable.setModel(new javax.swing.table.DefaultTableModel() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) { public boolean isCellEditable(int rowIndex, int columnIndex) {
return false; return false;
} }
}); });
resultsTable.setCellSelectionEnabled(true); resultsTable.setCellSelectionEnabled(true);
resultsTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
resultsTable.setColumnHidingAllowed(false);
resultsTable.getTableHeader().setReorderingAllowed(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(); updateColumnSizes();
} }
private void updateColumnSizes() { private void updateColumnSizes() {
resultsTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN); resultsTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN);
if (resultsTable.getColumnModel().getColumnCount() > 0) { Enumeration<TableColumn> columns = resultsTable.getColumnModel().getColumns();
resultsTable.getColumnModel().getColumn(0).setPreferredWidth(100); while (columns.hasMoreElements()) {
resultsTable.getColumnModel().getColumn(1).setPreferredWidth(800); TableColumn col = columns.nextElement();
resultsTable.getColumnModel().getColumn(2).setPreferredWidth(100); 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. * regenerated by the Form Editor.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code"> // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
rightClickMenu = new javax.swing.JPopupMenu(); rightClickMenu = new javax.swing.JPopupMenu();
copyMenuItem = new javax.swing.JMenuItem(); copyMenuItem = new javax.swing.JMenuItem();
selectAllMenuItem = new javax.swing.JMenuItem(); selectAllMenuItem = new javax.swing.JMenuItem();
jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel(); jPanel1 = new javax.swing.JPanel();
totalPageLabel = new javax.swing.JLabel(); totalPageLabel = new javax.swing.JLabel();
ofLabel = 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)); 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)); jPanel1.setPreferredSize(new java.awt.Dimension(620, 58));
totalPageLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.totalPageLabel.text")); // NOI18N 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); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout); 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) .addComponent(prevPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0) .addGap(0, 0, 0)
.addComponent(nextPageButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .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) .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(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .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) .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.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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(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)) .addComponent(pageLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .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.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(artifactLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .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); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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)
); );
}// </editor-fold> }// </editor-fold>//GEN-END:initComponents
private void prevPageButtonActionPerformed(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));
}
private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {
currentPage = currentPage + 1; currentPage = currentPage + 1;
currentPageLabel.setText(Integer.toString(currentPage)); currentPageLabel.setText(Integer.toString(currentPage));
artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName()); artifactLabel.setText(artifactTableContents.get(currentPage - 1).getArtifactDisplayName());
startNewTask(new SelectedArtifactChangedTask(currentPage)); 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.JLabel artifactLabel;
private javax.swing.JMenuItem copyMenuItem; private javax.swing.JMenuItem copyMenuItem;
private javax.swing.JLabel currentPageLabel; private javax.swing.JLabel currentPageLabel;
private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton nextPageButton; private javax.swing.JButton nextPageButton;
private javax.swing.JLabel ofLabel; private javax.swing.JLabel ofLabel;
private javax.swing.JLabel pageLabel; 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.JPopupMenu rightClickMenu;
private javax.swing.JMenuItem selectAllMenuItem; private javax.swing.JMenuItem selectAllMenuItem;
private javax.swing.JLabel totalPageLabel; private javax.swing.JLabel totalPageLabel;
// End of variables declaration // End of variables declaration//GEN-END:variables
private ETable resultsTable; private ETable resultsTable;
private void customizeComponents() { private void customizeComponents() {
@ -548,10 +548,6 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages)); totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
currentPageLabel.setText(Integer.toString(currentPage)); currentPageLabel.setText(Integer.toString(currentPage));
artifactLabel.setText(viewUpdate.tableContents.getArtifactDisplayName()); 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()); DefaultTableModel tModel = ((DefaultTableModel) resultsTable.getModel());
tModel.setDataVector(viewUpdate.tableContents.getRows(), COLUMN_HEADERS); tModel.setDataVector(viewUpdate.tableContents.getRows(), COLUMN_HEADERS);
updateColumnSizes(); updateColumnSizes();
@ -740,8 +736,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
List<ResultsTableArtifact> artifactContents = getArtifactContents(); List<ResultsTableArtifact> artifactContents = getArtifactContents();
ResultsTableArtifact artifactContent = artifactContents.get(pageIndex - 1); 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 // It may take a considerable amount of time to fetch the attributes of the selected artifact so check for cancellation.
// as HTML, so check for cancellation.
if (isCancelled()) { if (isCancelled()) {
return null; return null;
} }

View File

@ -21,3 +21,5 @@ PlatformUtil.getAllMemUsageInfo.usageText={0}\n\
{1}\n\ {1}\n\
Process Virtual Memory\: {2} Process Virtual Memory\: {2}
StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract 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

View File

@ -0,0 +1,88 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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);
}
}

View File

@ -0,0 +1,30 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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);
}
}

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2016 Basis Technology Corp. * Copyright 2011-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -33,6 +33,8 @@ import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; 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.ChildFactory;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
@ -74,12 +76,12 @@ public class KeywordHits implements AutopsyVisitableItem {
keywordResults = new KeywordResults(); 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 * All of these maps and code assume the following: Regexps will have an
* Exact match and substring will not have the instance layer and instead will have the specific hits * 'instance' layer that shows the specific words that matched the regexp
* below their term. * 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 { 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 // Map from listName/Type to Map of keywords/regexp to Map of instance terms to Set of artifact Ids
@ -104,10 +106,11 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
/** /**
* Get keywords used in a given list. Will be regexp patterns for regexps * Get keywords used in a given list. Will be regexp patterns for
* and search term for non-regexps. * regexps and search term for non-regexps.
* *
* @param listName Keyword list name * @param listName Keyword list name
*
* @return * @return
*/ */
List<String> getKeywords(String listName) { List<String> getKeywords(String listName) {
@ -120,12 +123,13 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
/** /**
* Get specific keyword terms that were found for a given list * Get specific keyword terms that were found for a given list and
* and keyword combination. For example, a specific phone number for a * keyword combination. For example, a specific phone number for a phone
* phone number regexp. Will be the default instance for non-regexp searches. * number regexp. Will be the default instance for non-regexp searches.
* *
* @param listName Keyword list name * @param listName Keyword list name
* @param keyword search term (regexp pattern or exact match term) * @param keyword search term (regexp pattern or exact match term)
*
* @return * @return
*/ */
List<String> getKeywordInstances(String listName, String keyword) { List<String> getKeywordInstances(String listName, String keyword) {
@ -139,9 +143,13 @@ public class KeywordHits implements AutopsyVisitableItem {
/** /**
* Get artifact ids for a given list, keyword, and instance triple * Get artifact ids for a given list, keyword, and instance triple
*
* @param listName Keyword list name * @param listName Keyword list name
* @param keyword search term (regexp pattern or exact match term) * @param keyword search term (regexp pattern or exact match
* @param keywordInstance specific term that matched (or default instance name) * term)
* @param keywordInstance specific term that matched (or default
* instance name)
*
* @return * @return
*/ */
Set<Long> getArtifactIds(String listName, String keyword, String keywordInstance) { Set<Long> getArtifactIds(String listName, String keyword, String keywordInstance) {
@ -152,7 +160,9 @@ public class KeywordHits implements AutopsyVisitableItem {
/** /**
* Add a hit for a regexp to the internal data structure. * Add a hit for a regexp to the internal data structure.
* @param listMap Maps keywords/regexp to instances to artifact IDs *
* @param listMap Maps keywords/regexp to instances to artifact
* IDs
* @param regExp Regular expression that was used in search * @param regExp Regular expression that was used in search
* @param keywordInstance Specific term that matched regexp * @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
@ -172,9 +182,10 @@ public class KeywordHits implements AutopsyVisitableItem {
instanceMap.get(keywordInstance).add(artifactId); instanceMap.get(keywordInstance).add(artifactId);
} }
/** /**
* Add a hit for a exactmatch (or substring) to the internal data structure. * Add a hit for a exactmatch (or substring) to the internal data
* structure.
*
* @param listMap Maps keywords/regexp to instances to artifact IDs * @param listMap Maps keywords/regexp to instances to artifact IDs
* @param keyWord Term that was hit * @param keyWord Term that was hit
* @param artifactId Artifact id of file that had hit * @param artifactId Artifact id of file that had hit
@ -193,8 +204,11 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
/** /**
* Populate data structure for the tree based on the keyword hit artifacts * Populate data structure for the tree based on the keyword hit
* @param artifactIds Maps Artifact ID to map of attribute types to attribute values * artifacts
*
* @param artifactIds Maps Artifact ID to map of attribute types to
* attribute values
*/ */
void populateTreeMaps(Map<Long, Map<Long, String>> artifactIds) { void populateTreeMaps(Map<Long, Map<Long, String>> artifactIds) {
synchronized (topLevelMap) { synchronized (topLevelMap) {
@ -241,8 +255,7 @@ public class KeywordHits implements AutopsyVisitableItem {
} else { } else {
addNonRegExpMatchToList(listMap, word, id); addNonRegExpMatchToList(listMap, word, id);
} }
} } else if (reg != null) {
else if (reg != null) {
addRegExpToList(listMap, reg, word, id); addRegExpToList(listMap, reg, word, id);
} else { } else {
addNonRegExpMatchToList(listMap, word, id); addNonRegExpMatchToList(listMap, word, id);
@ -299,9 +312,9 @@ public class KeywordHits implements AutopsyVisitableItem {
long artifactId = resultSet.getLong("artifact_id"); //NON-NLS long artifactId = resultSet.getLong("artifact_id"); //NON-NLS
long typeId = resultSet.getLong("attribute_type_id"); //NON-NLS long typeId = resultSet.getLong("attribute_type_id"); //NON-NLS
if (!artifactIds.containsKey(artifactId)) { if (!artifactIds.containsKey(artifactId)) {
artifactIds.put(artifactId, new LinkedHashMap<Long, String>()); artifactIds.put(artifactId, new LinkedHashMap<>());
} }
if (valueStr != null && !valueStr.equals("")) { if (StringUtils.isNotEmpty(valueStr)) {
artifactIds.get(artifactId).put(typeId, valueStr); artifactIds.get(artifactId).put(typeId, valueStr);
} else { } else {
// Keyword Search Type is an int // Keyword Search Type is an int
@ -459,7 +472,8 @@ 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 { 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 this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/keyword_hits.png"); //NON-NLS
updateDisplayName(); updateDisplayName();
keywordResults.addObserver(this); keywordResults.addObserver(this);
} }
private void updateDisplayName() { private void updateDisplayName() {
int totalDescendants = 0; super.setDisplayName(keyword + " (" + countTotalDescendants() + ")");
for (String instance : keywordResults.getKeywordInstances(setName, keyword)) {
Set<Long> ids = keywordResults.getArtifactIds(setName, keyword, instance);
totalDescendants += ids.size();
} }
super.setDisplayName(keyword + " (" + totalDescendants + ")"); private int countTotalDescendants() {
return keywordResults.getKeywordInstances(setName, keyword).stream()
.mapToInt(instance -> keywordResults.getArtifactIds(setName, keyword, instance).size())
.sum();
} }
@Override @Override
@ -605,12 +619,7 @@ public class KeywordHits implements AutopsyVisitableItem {
public boolean isLeafTypeNode() { public boolean isLeafTypeNode() {
List<String> instances = keywordResults.getKeywordInstances(setName, keyword); List<String> instances = keywordResults.getKeywordInstances(setName, keyword);
// is this an exact/substring match (i.e. did we use the DEFAULT name)? // 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 instances.size() == 1 && instances.get(0).equals(DEFAULT_INSTANCE_NAME);
return true;
}
else {
return false;
}
} }
@Override @Override
@ -635,7 +644,7 @@ public class KeywordHits implements AutopsyVisitableItem {
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.name"), 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.displayName"),
NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"), NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"),
keywordResults.getKeywordInstances(setName, keyword).size())); countTotalDescendants()));
return s; return s;
} }
@ -650,37 +659,45 @@ public class KeywordHits implements AutopsyVisitableItem {
// as they keys for different types of nodes at the // as they keys for different types of nodes at the
// same level. Probably a better way to do this, but // same level. Probably a better way to do this, but
// it works. // it works.
class RegExpInstanceKey { private class RegExpInstanceKey {
private final boolean isRegExp; private final boolean isRegExp;
private String strKey; private String strKey;
private Long longKey; private Long longKey;
public RegExpInstanceKey(String key) {
RegExpInstanceKey(String key) {
isRegExp = true; isRegExp = true;
strKey = key; strKey = key;
} }
public RegExpInstanceKey(Long key) {
RegExpInstanceKey(Long key) {
isRegExp = false; isRegExp = false;
longKey = key; longKey = key;
} }
boolean isRegExp() { boolean isRegExp() {
return isRegExp; return isRegExp;
} }
Long getIdKey() { Long getIdKey() {
return longKey; return longKey;
} }
String getRegExpKey() { String getRegExpKey() {
return strKey; 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<RegExpInstanceKey> implements Observer { public class RegExpInstancesFactory extends ChildFactory.Detachable<RegExpInstanceKey> implements Observer {
private final String keyword; private final String keyword;
private final String setName; private final String setName;
private Map<RegExpInstanceKey, DisplayableItemNode > nodesMap = new HashMap<>(); private final Map<RegExpInstanceKey, DisplayableItemNode> nodesMap = new HashMap<>();
public RegExpInstancesFactory(String setName, String keyword) { public RegExpInstancesFactory(String setName, String keyword) {
super(); super();
@ -739,6 +756,7 @@ public class KeywordHits implements AutopsyVisitableItem {
} }
} }
@Override @Override
public void update(Observable o, Object arg) { public void update(Observable o, Object arg) {
refresh(true); refresh(true);
@ -756,7 +774,7 @@ public class KeywordHits implements AutopsyVisitableItem {
private final String instance; private final String instance;
public RegExpInstanceNode(String setName, String keyword, 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 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.setName = setName;
this.keyword = keyword; this.keyword = keyword;
@ -803,7 +821,7 @@ public class KeywordHits implements AutopsyVisitableItem {
ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.name"), 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.displayName"),
NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"), NbBundle.getMessage(this.getClass(), "KeywordHits.createSheet.filesWithHits.desc"),
keywordResults.getKeywordInstances(setName, keyword).size())); keywordResults.getArtifactIds(setName, keyword, instance).size()));
return s; return s;
} }
@ -816,7 +834,9 @@ public class KeywordHits implements AutopsyVisitableItem {
/** /**
* Create a blackboard node for the given Keyword Hit artifact * Create a blackboard node for the given Keyword Hit artifact
*
* @param artifactId * @param artifactId
*
* @return Node or null on error * @return Node or null on error
*/ */
private BlackboardArtifactNode createBlackboardArtifactNode(Long artifactId) { private BlackboardArtifactNode createBlackboardArtifactNode(Long artifactId) {
@ -879,7 +899,7 @@ public class KeywordHits implements AutopsyVisitableItem {
private final String setName; private final String setName;
private final String instance; private final String instance;
private Map<Long, BlackboardArtifactNode > nodesMap = new HashMap<>(); private final Map<Long, BlackboardArtifactNode> nodesMap = new HashMap<>();
public HitsFactory(String setName, String keyword, String instance) { public HitsFactory(String setName, String keyword, String instance) {
super(); super();

View File

@ -524,7 +524,7 @@ public class EamCaseEditDetailsDialog extends JDialog {
private void updateDb() { private void updateDb() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.SEVERE, "Enteprise artifacts manager database not enabled"); // NON-NLS LOGGER.log(Level.SEVERE, "Enteprise artifacts manager database not enabled"); // NON-NLS
return; return;
} }

View File

@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.actions;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action; import javax.swing.Action;
import org.openide.awt.ActionID; import org.openide.awt.ActionID;
import org.openide.awt.ActionReference; import org.openide.awt.ActionReference;
@ -29,7 +28,7 @@ import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case; 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 * Action to update case details in enterprise artifacts manager database
@ -53,8 +52,7 @@ public final class EamEditCaseInfoAction extends CallableSystemAction implements
@Override @Override
public boolean isEnabled() { public boolean isEnabled() {
boolean enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS return EamDb.isEnabled() && Case.isCaseOpen();
return enabled && Case.isCaseOpen();
} }
@Override @Override

View File

@ -504,8 +504,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
@Override @Override
public boolean isSupported(Node node) { public boolean isSupported(Node node) {
EamDb dbManager = EamDb.getInstance(); if (!EamDb.isEnabled()) {
if (!dbManager.isEnabled()) {
return false; return false;
} }
@ -516,8 +515,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
@Override @Override
@Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifacts manager database."}) @Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifacts manager database."})
public void setNode(Node node) { public void setNode(Node node) {
EamDb dbManager = EamDb.getInstance(); if (!EamDb.isEnabled()) {
if (!dbManager.isEnabled()) {
return; return;
} }

View File

@ -45,8 +45,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
private final static Logger LOGGER = Logger.getLogger(AbstractSqlEamDb.class.getName()); private final static Logger LOGGER = Logger.getLogger(AbstractSqlEamDb.class.getName());
protected static final int SCHEMA_VERSION = 1; protected final List<EamArtifact.Type> DEFAULT_ARTIFACT_TYPES;
protected final List<EamArtifact.Type> DEFAULT_ARTIFACT_TYPES = new ArrayList<>();
private int bulkArtifactsCount; private int bulkArtifactsCount;
private int bulkGlobalArtifactsCount; private int bulkGlobalArtifactsCount;
@ -67,7 +66,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
bulkArtifacts = new HashMap<>(); bulkArtifacts = new HashMap<>();
bulkGlobalArtifacts = new HashMap<>(); bulkGlobalArtifacts = new HashMap<>();
loadDefaultArtifactTypes(); DEFAULT_ARTIFACT_TYPES = EamArtifact.getDefaultArtifactTypes();
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) { for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
bulkArtifacts.put(type.getName(), new ArrayList<>()); 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. - * 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 * 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. * Note: this should be call after the connectionPool is initialized.
*/ */
protected void confirmDatabaseSchema() throws EamDbException { // protected void confirmDatabaseSchema() throws EamDbException {
int schema_version; // int schema_version;
try { // try {
schema_version = Integer.parseInt(getDbInfo("SCHEMA_VERSION")); // schema_version = Integer.parseInt(getDbInfo("SCHEMA_VERSION"));
} catch (EamDbException | NumberFormatException ex) { // } catch (EamDbException | NumberFormatException ex) {
// error likely means we have not initialized the schema // // error likely means we have not initialized the schema
schema_version = 0; // schema_version = 0;
LOGGER.log(Level.WARNING, "Could not find SCHEMA_VERSION in db_info table, assuming database is not initialized.", ex); // NON-NLS // 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) { // if (0 == schema_version) {
initializeDatabaseSchema(); //// initializeDatabaseSchema();
insertDefaultContent(); // insertDefaultContent();
} else if (SCHEMA_VERSION > schema_version) { // } else if (SCHEMA_VERSION > schema_version) {
// FUTURE: upgrade schema // // FUTURE: upgrade schema
} // }
// else, schema is current // // else, schema is current
} // }
/**
* Create the schema for the selected database implementation
*/
protected abstract void initializeDatabaseSchema() throws EamDbException;
/** /**
* Setup and create a connection to the selected database implementation * Setup and create a connection to the selected database implementation
*/ */
protected abstract Connection connect() throws EamDbException; 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" * Get the list of tags recognized as "Bad"
* *
@ -260,8 +153,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error adding new name/value pair to db_info.", ex); throw new EamDbException("Error adding new name/value pair to db_info.", ex);
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -293,9 +186,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting value for name.", ex); throw new EamDbException("Error getting value for name.", ex);
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return value; return value;
@ -323,8 +216,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error updating value for name.", ex); throw new EamDbException("Error updating value for name.", ex);
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -366,8 +259,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new case.", ex); // NON-NLS throw new EamDbException("Error inserting new case.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -406,8 +299,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error updating case.", ex); // NON-NLS throw new EamDbException("Error updating case.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -442,9 +335,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting case details.", ex); // NON-NLS throw new EamDbException("Error getting case details.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return eamCaseResult; return eamCaseResult;
@ -479,9 +372,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting all cases.", ex); // NON-NLS throw new EamDbException("Error getting all cases.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return cases; return cases;
@ -510,8 +403,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new data source.", ex); // NON-NLS throw new EamDbException("Error inserting new data source.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -537,8 +430,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error updating case.", ex); // NON-NLS throw new EamDbException("Error updating case.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -557,7 +450,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
ResultSet resultSet = 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 { try {
preparedStatement = conn.prepareStatement(sql); preparedStatement = conn.prepareStatement(sql);
@ -569,9 +462,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting case details.", ex); // NON-NLS throw new EamDbException("Error getting case details.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return eamDataSourceResult; return eamDataSourceResult;
@ -603,9 +496,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting all data sources.", ex); // NON-NLS throw new EamDbException("Error getting all data sources.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return dataSources; return dataSources;
@ -651,8 +544,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new artifact into artifacts table.", ex); // NON-NLS throw new EamDbException("Error inserting new artifact into artifacts table.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -697,9 +590,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return artifactInstances; return artifactInstances;
@ -749,9 +642,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS throw new EamDbException("Error getting artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return artifactInstances; return artifactInstances;
@ -790,9 +683,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting count of artifact instances by artifactType and artifactValue.", ex); // NON-NLS throw new EamDbException("Error getting count of artifact instances by artifactType and artifactValue.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return instanceCount; return instanceCount;
@ -852,9 +745,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); // NON-NLS throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return instanceCount; return instanceCount;
@ -897,9 +790,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples.", ex); // NON-NLS throw new EamDbException("Error counting unique caseDisplayName/dataSource tuples.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return instanceCount; return instanceCount;
@ -953,9 +846,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error counting artifact instances by caseName/dataSource.", ex); // NON-NLS throw new EamDbException("Error counting artifact instances by caseName/dataSource.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return instanceCount; return instanceCount;
@ -1035,8 +928,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(bulkPs); EamDbUtil.closePreparedStatement(bulkPs);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1088,8 +981,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting bulk cases.", ex); // NON-NLS throw new EamDbException("Error inserting bulk cases.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(bulkPs); EamDbUtil.closePreparedStatement(bulkPs);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1154,10 +1047,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting/setting artifact instance knownStatus=Bad.", ex); // NON-NLS throw new EamDbException("Error getting/setting artifact instance knownStatus=Bad.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedUpdate); EamDbUtil.closePreparedStatement(preparedUpdate);
closePreparedStatement(preparedQuery); EamDbUtil.closePreparedStatement(preparedQuery);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1202,9 +1095,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return artifactInstances; return artifactInstances;
@ -1241,9 +1134,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting count of known bad artifact instances.", ex); // NON-NLS throw new EamDbException("Error getting count of known bad artifact instances.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return badInstances; return badInstances;
@ -1292,9 +1185,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS throw new EamDbException("Error getting known bad artifact instances.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return caseNames.stream().collect(Collectors.toList()); return caseNames.stream().collect(Collectors.toList());
@ -1332,9 +1225,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error determining if artifact is globally known bad.", ex); // NON-NLS throw new EamDbException("Error determining if artifact is globally known bad.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
return 0 < badInstances; return 0 < badInstances;
@ -1365,8 +1258,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new organization.", ex); // NON-NLS throw new EamDbException("Error inserting new organization.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1397,9 +1290,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting all organizations.", ex); // NON-NLS throw new EamDbException("Error getting all organizations.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1430,9 +1323,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting organization by id.", ex); // NON-NLS throw new EamDbException("Error getting organization by id.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1477,10 +1370,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new global set.", ex); // NON-NLS throw new EamDbException("Error inserting new global set.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement1); EamDbUtil.closePreparedStatement(preparedStatement1);
closePreparedStatement(preparedStatement2); EamDbUtil.closePreparedStatement(preparedStatement2);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1511,9 +1404,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting global set by id.", ex); // NON-NLS throw new EamDbException("Error getting global set by id.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement1); EamDbUtil.closePreparedStatement(preparedStatement1);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1542,8 +1435,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new global file instance into global_files table.", ex); // NON-NLS throw new EamDbException("Error inserting new global file instance into global_files table.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1606,8 +1499,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS throw new EamDbException("Error inserting bulk artifacts.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(bulkPs); EamDbUtil.closePreparedStatement(bulkPs);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
} }
@ -1640,9 +1533,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting global set by id.", ex); // NON-NLS throw new EamDbException("Error getting global set by id.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement1); EamDbUtil.closePreparedStatement(preparedStatement1);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1671,8 +1564,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error inserting new correlation artifact type.", ex); // NON-NLS throw new EamDbException("Error inserting new correlation artifact type.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1704,9 +1597,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting all correlation artifact types.", ex); // NON-NLS throw new EamDbException("Error getting all correlation artifact types.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1738,9 +1631,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting enabled correlation artifact types.", ex); // NON-NLS throw new EamDbException("Error getting enabled correlation artifact types.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1772,9 +1665,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting supported correlation artifact types.", ex); // NON-NLS throw new EamDbException("Error getting supported correlation artifact types.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1802,8 +1695,8 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -1836,9 +1729,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS throw new EamDbException("Error getting correlation artifact type by name.", ex); // NON-NLS
} finally { } finally {
closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }

View File

@ -36,6 +36,19 @@ public class EamArtifact implements Serializable {
private Type artifactType; private Type artifactType;
private final List<EamArtifactInstance> artifactInstances; private final List<EamArtifactInstance> artifactInstances;
/**
* Load the default correlation artifact types
*/
public static List<EamArtifact.Type> getDefaultArtifactTypes() {
List<EamArtifact.Type> 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) { public EamArtifact(Type artifactType, String artifactValue) {
this.ID = ""; this.ID = "";
this.artifactType = artifactType; this.artifactType = artifactType;

View File

@ -24,11 +24,12 @@ import java.util.List;
* Main interface for interacting with the database * Main interface for interacting with the database
*/ */
public interface EamDb { 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 * @throws EamDbException
*/ */
@ -40,8 +41,9 @@ public interface EamDb {
return PostgresEamDb.getInstance(); return PostgresEamDb.getInstance();
case SQLITE: case SQLITE:
default:
return SqliteEamDb.getInstance(); return SqliteEamDb.getInstance();
default:
return null;
} }
} }
@ -65,7 +67,9 @@ public interface EamDb {
* *
* @return Is the database enabled * @return Is the database enabled
*/ */
boolean isEnabled(); static boolean isEnabled() {
return EamDbPlatformEnum.getSelectedPlatform() != EamDbPlatformEnum.DISABLED;
}
/** /**
* Get the list of tags recognized as "Bad" * Get the list of tags recognized as "Bad"

View File

@ -24,7 +24,8 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
* *
*/ */
public enum EamDbPlatformEnum { public enum EamDbPlatformEnum {
SQLITE("SQLite", true), DISABLED("Disabled", true),
SQLITE("SQLite", false),
POSTGRESQL("PostgreSQL", false); POSTGRESQL("PostgreSQL", false);
private final String platformName; private final String platformName;
@ -44,6 +45,8 @@ public enum EamDbPlatformEnum {
if (null != selectedPlatformString) { if (null != selectedPlatformString) {
selected = this.toString().equalsIgnoreCase(selectedPlatformString); selected = this.toString().equalsIgnoreCase(selectedPlatformString);
} else if (this == DISABLED) {
selected = true;
} }
} }
@ -56,13 +59,13 @@ public enum EamDbPlatformEnum {
this.selected = selected; this.selected = selected;
} }
private Boolean isSelected() { public Boolean isSelected() {
return selected; return selected;
} }
public static EamDbPlatformEnum fromString(String pName) { public static EamDbPlatformEnum fromString(String pName) {
if (null == pName) { if (null == pName) {
return SQLITE; return DISABLED;
} }
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
@ -70,14 +73,14 @@ public enum EamDbPlatformEnum {
return p; return p;
} }
} }
return SQLITE; return DISABLED;
} }
/** /**
* Save the selected platform to the config file. * Save the selected platform to the config file.
*/ */
public static void saveSelectedPlatform() { public static void saveSelectedPlatform() {
EamDbPlatformEnum selectedPlatform = SQLITE; EamDbPlatformEnum selectedPlatform = DISABLED;
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
if (p.isSelected()) { if (p.isSelected()) {
selectedPlatform = p; selectedPlatform = p;
@ -103,7 +106,7 @@ public enum EamDbPlatformEnum {
* Get the selected platform. * Get the selected platform.
* *
* @return The selected platform, or if not platform is selected, default to * @return The selected platform, or if not platform is selected, default to
* SQLITE. * DISABLED.
*/ */
public static EamDbPlatformEnum getSelectedPlatform() { public static EamDbPlatformEnum getSelectedPlatform() {
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) { for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
@ -111,6 +114,6 @@ public enum EamDbPlatformEnum {
return p; return p;
} }
} }
return SQLITE; return DISABLED;
} }
} }

View File

@ -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<EamArtifact.Type> 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;
}
}

View File

@ -90,10 +90,10 @@ public class PostgresEamDb extends AbstractSqlEamDb {
} catch (SQLException ex) { } catch (SQLException ex) {
//LOGGER.log(Level.WARNING, "Failed to reset database.", ex); //LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
} finally { } finally {
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
insertDefaultContent(); dbSettings.insertDefaultDatabaseContent();
} }
/** /**
@ -113,12 +113,10 @@ public class PostgresEamDb extends AbstractSqlEamDb {
connectionURL.append(dbSettings.getPort()); connectionURL.append(dbSettings.getPort());
connectionURL.append("/"); connectionURL.append("/");
connectionURL.append(dbSettings.getDbName()); connectionURL.append(dbSettings.getDbName());
connectionURL.append("?user=");
connectionURL.append(dbSettings.getUserName());
connectionURL.append("&password=");
connectionURL.append(dbSettings.getPassword());
connectionPool.setUrl(connectionURL.toString()); connectionPool.setUrl(connectionURL.toString());
connectionPool.setUsername(dbSettings.getUserName());
connectionPool.setPassword(dbSettings.getPassword());
// tweak pool configuration // tweak pool configuration
connectionPool.setInitialSize(5); // start with 5 connections connectionPool.setInitialSize(5); // start with 5 connections
@ -126,175 +124,6 @@ public class PostgresEamDb extends AbstractSqlEamDb {
connectionPool.setValidationQuery(dbSettings.getValidationQuery()); 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. * Lazily setup Singleton connection on first request.
* *
@ -305,13 +134,12 @@ public class PostgresEamDb extends AbstractSqlEamDb {
@Override @Override
protected Connection connect() throws EamDbException { protected Connection connect() throws EamDbException {
synchronized (this) { synchronized (this) {
if (!dbSettings.isEnabled()) { if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS
} }
if (connectionPool == null) { if (connectionPool == null) {
setupConnectionPool(); setupConnectionPool();
confirmDatabaseSchema();
} }
} }
@ -322,11 +150,6 @@ public class PostgresEamDb extends AbstractSqlEamDb {
} }
} }
@Override
public boolean isEnabled() {
return dbSettings.isEnabled();
}
@Override @Override
public List<String> getBadTags() { public List<String> getBadTags() {
return dbSettings.getBadTags(); return dbSettings.getBadTags();

View File

@ -20,15 +20,20 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.regex.Pattern;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings; 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 * 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 static Logger LOGGER = Logger.getLogger(PostgresEamDbSettings.class.getName());
private final String DEFAULT_HOST = "localhost"; // NON-NLS private final String DEFAULT_HOST = "localhost"; // NON-NLS
private final int DEFAULT_PORT = 5432; 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 int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_USERNAME = ""; private final String DEFAULT_USERNAME = "";
private final String DEFAULT_PASSWORD = ""; 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 VALIDATION_QUERY = "SELECT version()"; // NON-NLS
private final String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS private final String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS
private final String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS private final String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS
private final String DB_NAMES_REGEX = "[a-z][a-z0-9_]*"; // only lower case
private boolean enabled; private final String DB_USER_NAMES_REGEX = "[a-zA-Z]\\w*";
private String host; private String host;
private int port; private int port;
private String dbName; private String dbName;
@ -62,8 +67,6 @@ public final class PostgresEamDbSettings {
} }
public void loadSettings() { public void loadSettings() {
enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS
host = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS host = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS
if (host == null || host.isEmpty()) { if (host == null || host.isEmpty()) {
host = DEFAULT_HOST; host = DEFAULT_HOST;
@ -110,6 +113,13 @@ public final class PostgresEamDbSettings {
password = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.password"); // NON-NLS password = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.password"); // NON-NLS
if (password == null || password.isEmpty()) { if (password == null || password.isEmpty()) {
password = DEFAULT_PASSWORD; 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 String badTagsStr = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.badTags"); // NON-NLS
@ -120,70 +130,339 @@ public final class PostgresEamDbSettings {
} }
public void saveSettings() { 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.host", getHost()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.port", Integer.toString(port)); // 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.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.postgresql.bulkThreshold", Integer.toString(getBulkThreshold())); // 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.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 ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.badTags", String.join(",", badTags)); // NON-NLS
} }
/** /**
* Get the full connection URL as a String * Get the full connection URL as a String
* *
* @param usePostgresDb Connect to the 'postgres' database when testing
* connectivity and creating the main database.
*
* @return * @return
*/ */
public String getConnectionURL() { public String getConnectionURL(boolean usePostgresDb) {
StringBuilder url = new StringBuilder(); StringBuilder url = new StringBuilder();
url.append(getJDBCBaseURI()); url.append(getJDBCBaseURI());
url.append(getHost()); url.append(getHost());
url.append("/"); // NON-NLS url.append("/"); // NON-NLS
if (usePostgresDb) {
url.append("postgres"); // NON-NLS
} else {
url.append(getDbName()); url.append(getDbName());
url.append("?user="); // NON-NLS }
url.append(getUserName());
url.append("&password="); // NON-NLS
url.append(getPassword());
return url.toString(); return url.toString();
} }
public boolean testSettings() { /**
// Open a new ephemeral client here to test that we can connect * Use the current settings to get an ephemeral client connection for testing.
ResultSet resultSet = null; *
Connection conn = null; * @return Connection or null.
*/
private Connection getEphemeralConnection(boolean usePostgresDb) {
Connection conn;
try { try {
String url = getConnectionURL(); String url = getConnectionURL(usePostgresDb);
Properties props = new Properties();
props.setProperty("user", getUserName());
props.setProperty("password", getPassword());
Class.forName(getDriver()); Class.forName(getDriver());
conn = DriverManager.getConnection(url); conn = DriverManager.getConnection(url, props);
Statement tester = conn.createStatement();
resultSet = tester.executeQuery(getValidationQuery());
if (resultSet.next()) {
LOGGER.log(Level.INFO, "Testing connection to postgresql success."); // NON-NLS
}
} catch (ClassNotFoundException | SQLException ex) { } 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
return false; // the SQLException and does not print this log message?
} finally { LOGGER.log(Level.SEVERE, "Failed to acquire ephemeral connection to postgresql."); // NON-NLS
if (null != resultSet) { conn = null;
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
}
} }
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;
}
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; 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<EamArtifact.Type> 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() { public boolean isChanged() {
String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.postgresql.host"); // NON-NLS
@ -198,20 +477,6 @@ public final class PostgresEamDbSettings {
|| !userName.equals(userNameString) || !password.equals(userPasswordString); || !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 * @return the host
*/ */
@ -226,7 +491,7 @@ public final class PostgresEamDbSettings {
if (null != host && !host.isEmpty()) { if (null != host && !host.isEmpty()) {
this.host = host; this.host = host;
} else { } 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) { if (port > 0 && port < 65535) {
this.port = port; this.port = port;
} else { } 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 * @return the dbName
*/ */
public String getDbName() { public String getDbName() {
return dbName; return dbName.toLowerCase();
} }
/** /**
* @param dbName the dbName to set * @param dbName the dbName to set
*/ */
public void setDbName(String dbName) throws EamDbException { public void setDbName(String dbName) throws EamDbException {
if (dbName != null && !dbName.isEmpty()) { if (dbName == null || dbName.isEmpty()) {
this.dbName = dbName; throw new EamDbException("Invalid database name. Cannot be empty."); // NON-NLS
} else { } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
throw new EamDbException("Error invalid name for database connection. Cannot be null or empty."); // NON-NLS 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) { if (bulkThreshold > 0) {
this.bulkThreshold = bulkThreshold; this.bulkThreshold = bulkThreshold;
} else { } 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 * @param userName the userName to set
*/ */
public void setUserName(String userName) throws EamDbException { public void setUserName(String userName) throws EamDbException {
if (userName != null && !userName.isEmpty()) { if (userName == null || userName.isEmpty()) {
this.userName = userName; throw new EamDbException("Invalid user name. Cannot be empty."); // NON-NLS
} else { } else if (!Pattern.matches(DB_USER_NAMES_REGEX, userName)) {
throw new EamDbException("Error invalid user name for database connection. Cannot be null or empty."); // NON-NLS 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 * @param password the password to set
*/ */
public void setPassword(String password) throws EamDbException { public void setPassword(String password) throws EamDbException {
if (password != null && !password.isEmpty()) { if (password == null || password.isEmpty()) {
this.password = password; throw new EamDbException("Invalid user password. Cannot be empty."); // NON-NLS
} else {
throw new EamDbException("Error invalid user password for database connection. Cannot be null or empty."); // NON-NLS
} }
this.password = password;
} }
/** /**

View File

@ -19,8 +19,6 @@
package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel; package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
@ -38,13 +36,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
private static SqliteEamDb instance; 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 BasicDataSource connectionPool = null;
private final SqliteEamDbSettings dbSettings; private final SqliteEamDbSettings dbSettings;
@ -97,12 +88,12 @@ public class SqliteEamDb extends AbstractSqlEamDb {
} }
dropContent.executeUpdate("VACUUM"); dropContent.executeUpdate("VACUUM");
insertDefaultContent(); dbSettings.insertDefaultDatabaseContent();
} catch (SQLException ex) { } catch (SQLException ex) {
LOGGER.log(Level.WARNING, "Failed to reset database.", ex); LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
} finally { } finally {
closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
} }
@ -130,202 +121,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
connectionPool.setValidationQuery(dbSettings.getValidationQuery()); 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. * Lazily setup Singleton connection on first request.
* *
@ -336,14 +131,12 @@ public class SqliteEamDb extends AbstractSqlEamDb {
@Override @Override
protected Connection connect() throws EamDbException { protected Connection connect() throws EamDbException {
synchronized (this) { synchronized (this) {
if (!dbSettings.isEnabled()) { if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS throw new EamDbException("Enterprise artifacts manager is not enabled"); // NON-NLS
} }
if (connectionPool == null) { if (connectionPool == null) {
verifyDBDirectory();
setupConnectionPool(); setupConnectionPool();
confirmDatabaseSchema();
} }
try { try {
@ -354,11 +147,6 @@ public class SqliteEamDb extends AbstractSqlEamDb {
} }
} }
@Override
public boolean isEnabled() {
return dbSettings.isEnabled();
}
@Override @Override
public List<String> getBadTags() { public List<String> getBadTags() {
return dbSettings.getBadTags(); return dbSettings.getBadTags();

View File

@ -23,13 +23,13 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.regex.Pattern;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings; import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; 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 static Logger LOGGER = Logger.getLogger(SqliteEamDbSettings.class.getName());
private final String DEFAULT_DBNAME = "EnterpriseArtifacts.db"; // NON-NLS 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 int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_BAD_TAGS = "Evidence"; // NON-NLS private final String DEFAULT_BAD_TAGS = "Evidence"; // NON-NLS
private final String JDBC_DRIVER = "org.sqlite.JDBC"; // 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 JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS
private final String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS private final String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS
private static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF";
private boolean enabled; 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 dbName;
private String dbDirectory; private String dbDirectory;
private int bulkThreshold; private int bulkThreshold;
@ -59,8 +65,6 @@ public final class SqliteEamDbSettings {
} }
public void loadSettings() { public void loadSettings() {
enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS
dbName = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS dbName = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS
if (dbName == null || dbName.isEmpty()) { if (dbName == null || dbName.isEmpty()) {
dbName = DEFAULT_DBNAME; dbName = DEFAULT_DBNAME;
@ -93,30 +97,49 @@ public final class SqliteEamDbSettings {
} }
public void saveSettings() { 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.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory", getDbDirectory()); // 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.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactsManager", "db.badTags", String.join(",", badTags)); // 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 // Ensure dbDirectory is a valid directory
File dbDir = new File(getDbDirectory()); File dbDir = new File(getDbDirectory());
if (!dbDir.exists()) { if (!dbDir.exists()) {
LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", getDbDirectory()); // NON-NLS return false;
try { } else if (!dbDir.isDirectory()) {
Files.createDirectories(dbDir.toPath());
} catch (IOException ex) {
LOGGER.log(Level.INFO, "Failed to create sqlite database directory.", ex); // NON-NLS
return false; 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 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.SEVERE, "Failed to create sqlite database directory.", ex); // NON-NLS
return false; return false;
} }
}
return true; return true;
} }
@ -134,46 +157,258 @@ public final class SqliteEamDbSettings {
return url.toString(); return url.toString();
} }
public boolean testSettings() { /**
if (!createAndVerifyDirectory()) { * Use the current settings to get an ephemeral client connection for testing.
return false; *
* 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 Connection conn;
ResultSet resultSet = null;
Connection conn = null;
try { try {
String url = getConnectionURL(); String url = getConnectionURL();
Class.forName(getDriver()); Class.forName(getDriver());
conn = DriverManager.getConnection(url); 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) { } 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
return false; conn = null;
} 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
}
} }
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;
}
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<EamArtifact.Type> 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; 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() { public boolean isChanged() {
String dbNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS String dbNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbName"); // NON-NLS
String dbDirectoryString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.sqlite.dbDirectory"); // 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); || !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 * @return the dbName
*/ */
@ -211,11 +432,13 @@ public final class SqliteEamDbSettings {
* @param dbName the dbName to set * @param dbName the dbName to set
*/ */
public void setDbName(String dbName) throws EamDbException { public void setDbName(String dbName) throws EamDbException {
if (dbName != null && !dbName.isEmpty()) { if (dbName == null || dbName.isEmpty()) {
this.dbName = dbName; throw new EamDbException("Invalid database file name. Cannot be null or empty."); // NON-NLS
} else { } else if (!Pattern.matches(DB_NAMES_REGEX, dbName)) {
throw new EamDbException("Error invalid file name for database. Cannot be null or empty."); // NON-NLS 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) { if (bulkThreshold > 0) {
this.bulkThreshold = bulkThreshold; this.bulkThreshold = bulkThreshold;
} else { } else {
throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS throw new EamDbException("Invalid bulk threshold for database connection."); // NON-NLS
} }
} }

View File

@ -42,7 +42,7 @@ public class BadFileTagRunner implements Runnable {
@Override @Override
public void run() { public void run() {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS
return; return;
} }

View File

@ -61,7 +61,7 @@ public class CaseEventListener implements PropertyChangeListener {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
switch (Case.Events.valueOf(evt.getPropertyName())) { switch (Case.Events.valueOf(evt.getPropertyName())) {
case CONTENT_TAG_ADDED: { case CONTENT_TAG_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }
@ -125,7 +125,7 @@ public class CaseEventListener implements PropertyChangeListener {
break; break;
case BLACKBOARD_ARTIFACT_TAG_ADDED: { case BLACKBOARD_ARTIFACT_TAG_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }
@ -157,7 +157,7 @@ public class CaseEventListener implements PropertyChangeListener {
break; break;
case DATA_SOURCE_ADDED: { case DATA_SOURCE_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
break; break;
} }
@ -214,7 +214,7 @@ public class CaseEventListener implements PropertyChangeListener {
"", "",
""); "");
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
break; break;
} }

View File

@ -78,7 +78,7 @@ public class IngestEventsListener {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) { switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
case DATA_ADDED: { case DATA_ADDED: {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }

View File

@ -45,7 +45,7 @@ public class NewArtifactsRunner implements Runnable {
@Override @Override
public void run() { public void run() {
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS LOGGER.log(Level.WARNING, "Enterprise artifacts manager database not configured"); // NON-NLS
return; return;
} }

View File

@ -29,7 +29,6 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard; import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.core.RuntimeProperties;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.ingest.FileIngestModule; import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage;
@ -69,8 +68,7 @@ class IngestModule implements FileIngestModule {
@Override @Override
public ProcessResult process(AbstractFile af) { public ProcessResult process(AbstractFile af) {
if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false if (EamDb.isEnabled() == false) {
|| EamDb.getInstance().isEnabled() == false) {
/* /*
* Not signaling an error for now. This is a workaround for the way * Not signaling an error for now. This is a workaround for the way
* all newly didscovered ingest modules are automatically anabled. * all newly didscovered ingest modules are automatically anabled.
@ -152,8 +150,7 @@ class IngestModule implements FileIngestModule {
@Override @Override
public void shutDown() { public void shutDown() {
if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false if (EamDb.isEnabled() == false) {
|| EamDb.getInstance().isEnabled() == false) {
/* /*
* Not signaling an error for now. This is a workaround for the way * Not signaling an error for now. This is a workaround for the way
* all newly didscovered ingest modules are automatically anabled. * all newly didscovered ingest modules are automatically anabled.
@ -187,8 +184,7 @@ class IngestModule implements FileIngestModule {
}) })
@Override @Override
public void startUp(IngestJobContext context) throws IngestModuleException { public void startUp(IngestJobContext context) throws IngestModuleException {
if (Boolean.parseBoolean(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")) == false if (EamDb.isEnabled() == false) {
|| EamDb.getInstance().isEnabled() == false) {
/* /*
* Not throwing the customary exception for now. This is a * Not throwing the customary exception for now. This is a
* workaround for the way all newly didscovered ingest modules are * workaround for the way all newly didscovered ingest modules are

View File

@ -13,11 +13,9 @@ EamPostgresSettingsDialog.lbUserPassword.text=User Password :
EamPostgresSettingsDialog.lbUserName.text=User Name : EamPostgresSettingsDialog.lbUserName.text=User Name :
EamPostgresSettingsDialog.bnCancel.text=Cancel EamPostgresSettingsDialog.bnCancel.text=Cancel
EamPostgresSettingsDialog.lbPort.text=Port : EamPostgresSettingsDialog.lbPort.text=Port :
EamPostgresSettingsDialog.bnSave.text=Save
EamPostgresSettingsDialog.lbHostName.text=Host Name / IP : EamPostgresSettingsDialog.lbHostName.text=Host Name / IP :
EamPostgresSettingsDialog.bnTestConnection.text=Test Connection EamPostgresSettingsDialog.bnTestConnection.text=Test Connection
EamPostgresSettingsDialog.lbDatabaseName.text=Database name : EamPostgresSettingsDialog.lbDatabaseName.text=Database name :
EamSqliteSettingsDialog.bnSave.text=Save
EamSqliteSettingsDialog.bnCancel.text=Cancel EamSqliteSettingsDialog.bnCancel.text=Cancel
EamSqliteSettingsDialog.lbTestDatabase.text= EamSqliteSettingsDialog.lbTestDatabase.text=
EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection
@ -44,14 +42,11 @@ ImportHashDatabaseDialog.bnNewOrganization.text=Add New Organization
ImportHashDatabaseDialog.tfDatabaseName.tooltip=Name for this database ImportHashDatabaseDialog.tfDatabaseName.tooltip=Name for this database
ImportHashDatabaseDialog.tfDatabaseVersion.tooltip.text=Database Version Number ImportHashDatabaseDialog.tfDatabaseVersion.tooltip.text=Database Version Number
GlobalSettingsPanel.bnImportDatabase.actionCommand= GlobalSettingsPanel.bnImportDatabase.actionCommand=
GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text=Enable Enterprise Artifacts Manager
GlobalSettingsPanel.bnManageTypes.text=Manage Artifact Types GlobalSettingsPanel.bnManageTypes.text=Manage Artifact Types
GlobalSettingsPanel.bnManageTags.actionCommand= GlobalSettingsPanel.bnManageTags.actionCommand=
GlobalSettingsPanel.bnManageTags.toolTipText= GlobalSettingsPanel.bnManageTags.toolTipText=
GlobalSettingsPanel.bnManageTags.text=Manage Tags GlobalSettingsPanel.bnManageTags.text=Manage Tags
GlobalSettingsPanel.tbOops.text= GlobalSettingsPanel.tbOops.text=
GlobalSettingsPanel.bnConfigureDatabaseSettings.text=Configure
GlobalSettingsPanel.lbDatabasePlatform.text=Enable Database Platform :
GlobalSettingsPanel.lbDatabaseSettings.text=Database Settings GlobalSettingsPanel.lbDatabaseSettings.text=Database Settings
GlobalSettingsPanel.bnImportDatabase.label=Import Hash Database GlobalSettingsPanel.bnImportDatabase.label=Import Hash Database
AddNewOrganizationDialog.lbPocPhone.text=Phone: AddNewOrganizationDialog.lbPocPhone.text=Phone:
@ -68,3 +63,28 @@ ManageArtifactTypesDialog.cancelButton.text=Cancel
ManageArtifactTypesDialog.okButton.text=OK ManageArtifactTypesDialog.okButton.text=OK
ManageArtifactTypesDialog.lbWarningMsg.text=Warning Message 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. 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:

View File

@ -0,0 +1,489 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="bnGrpDatabasePlatforms">
</Component>
<Component class="javax.swing.JFileChooser" name="fcDatabasePath">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="pnSetupGuidance" max="32767" attributes="0"/>
<Component id="pnDatabaseConnectionSettings" alignment="0" max="32767" attributes="0"/>
<Component id="pnButtons" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="pnSetupGuidance" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="pnDatabaseConnectionSettings" min="-2" pref="348" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnButtons" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnDatabaseConnectionSettings">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Database Settings">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.pnDatabaseConnectionSettings.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="rdioBnPostgreSQL" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="rdioBnSQLite" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="rdioBnDisabled" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnSQLiteSettings" alignment="0" max="32767" attributes="0"/>
<Component id="pnPostgreSQLSettings" alignment="1" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="32767" attributes="0"/>
<Component id="rdioBnDisabled" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
<Component id="rdioBnSQLite" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnSQLiteSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
<Component id="rdioBnPostgreSQL" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnPostgreSQLSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="329" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnSQLiteSettings">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lbDatabasePath" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="tfDatabasePath" min="-2" pref="343" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="bnDatabasePathFileOpen" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDatabasePath" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="tfDatabasePath" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="bnDatabasePathFileOpen" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.lbDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.tfDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.tfDatabasePath.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="tfDatabasePathFocusLost"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnDatabasePathFileOpen">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.bnDatabasePathFileOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnDatabasePathFileOpenActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnPostgreSQLSettings">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbHostName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbPort" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbDatabaseName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbUserName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbUserPassword" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbUsername" alignment="0" pref="439" max="32767" attributes="0"/>
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbPort" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbHostname" max="32767" attributes="0"/>
<Component id="jpDbPassword" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="tbDbHostname" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="lbHostName" alignment="1" min="-2" pref="22" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbPort" alignment="0" max="32767" attributes="0"/>
<Component id="lbPort" alignment="0" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="lbDatabaseName" alignment="0" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbUsername" alignment="0" max="32767" attributes="0"/>
<Component id="lbUserName" alignment="0" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbUserPassword" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="jpDbPassword" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="19" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbHostName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.lbHostName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPort">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.lbPort.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbUserName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.lbUserName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbUserPassword">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.lbUserPassword.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabaseName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.lbDatabaseName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tbDbHostname">
</Component>
<Component class="javax.swing.JTextField" name="tbDbPort">
</Component>
<Component class="javax.swing.JTextField" name="tbDbName">
</Component>
<Component class="javax.swing.JTextField" name="tbDbUsername">
</Component>
<Component class="javax.swing.JPasswordField" name="jpDbPassword">
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JRadioButton" name="rdioBnSQLite">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.rdioBnSQLite.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rdioBnSQLiteActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="rdioBnPostgreSQL">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.rdioBnPostgreSQL.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rdioBnPostgreSQLActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="rdioBnDisabled">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.rdioBnDisabled.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rdioBnDisabledActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnButtons">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="bnTest" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="lbTestIcon" min="-2" pref="20" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="bnCreateDb" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="lbCreateIcon" min="-2" pref="21" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="bnOk" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbCreateIcon" max="32767" attributes="0"/>
<Component id="lbTestIcon" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnOk" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnTest" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnCreateDb" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnOk">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.bnOk.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOkActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnTest">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.bnTest.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnTestActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnCreateDb">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.bnCreateDb.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCreateDbActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestIcon">
</Component>
<Component class="javax.swing.JLabel" name="lbCreateIcon">
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnSetupGuidance">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Setup Guidance">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamDbSettingsDialog.pnSetupGuidance.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="taSetupGuidance">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Monospaced" size="12" style="0"/>
</Property>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="3"/>
<Property name="tabSize" type="int" value="4"/>
<Property name="wrapStyleWord" type="boolean" value="true"/>
<Property name="autoscrolls" type="boolean" value="false"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
<Property name="verifyInputWhenFocusTarget" type="boolean" value="false"/>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -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<JTextField> 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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();
}// </editor-fold>//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<TextPrompt> 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<TextPrompt> 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<JTextField> 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
}

View File

@ -1,246 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnOuter" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnOuter" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnOuter">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="448" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane" min="-2" pref="448" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="249" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane" min="-2" pref="249" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnContent">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="bnTestConnection" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbTestDatabase" min="-2" pref="19" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="153" max="-2" attributes="0"/>
<Component id="bnSave" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Component id="lbTestDatabaseWarning" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbHostName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbPort" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbDatabaseName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbUserName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbUserPassword" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbPassword" alignment="0" pref="322" max="32767" attributes="0"/>
<Component id="tbDbUsername" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbHostname" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbPort" alignment="0" min="-2" pref="67" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<EmptySpace min="0" pref="11" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="tbDbHostname" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="lbHostName" alignment="1" min="-2" pref="22" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbPort" alignment="0" max="32767" attributes="0"/>
<Component id="lbPort" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="lbDatabaseName" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbUsername" alignment="0" max="32767" attributes="0"/>
<Component id="lbUserName" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbUserPassword" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="tbDbPassword" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
<Component id="lbTestDatabaseWarning" min="-2" pref="21" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnTestConnection" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnSave" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbTestDatabase" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbHostName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbHostName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPort">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbPort.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbUserName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbUserName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbUserPassword">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbUserPassword.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabaseName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbDatabaseName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tbDbHostname">
</Component>
<Component class="javax.swing.JTextField" name="tbDbPort">
</Component>
<Component class="javax.swing.JTextField" name="tbDbName">
</Component>
<Component class="javax.swing.JTextField" name="tbDbUsername">
</Component>
<Component class="javax.swing.JTextField" name="tbDbPassword">
</Component>
<Component class="javax.swing.JButton" name="bnTestConnection">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.bnTestConnection.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnTestConnectionActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnSave">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.bnSave.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnSaveActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabaseWarning">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="1"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabase">
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -1,545 +0,0 @@
/*
* Enterprise Artifacts Manager
*
* Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<JTextField> 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<TextPrompt> 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<TextPrompt> 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<JTextField> 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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();
}// </editor-fold>//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
}

View File

@ -1,218 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<NonVisualComponents>
<Component class="javax.swing.JFileChooser" name="fcDatabasePath">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="603" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Component id="pnOuter" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="129" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="pnOuter" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnOuter">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnContent">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="lbTestDatabaseWarning" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="lbDatabasePath" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="tfDatabasePath" min="-2" pref="343" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="57" max="32767" attributes="0"/>
<Component id="bnDatabasePathFileOpen" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="bnTestDatabase" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbTestDatabase" min="-2" pref="30" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="bnSave" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDatabasePath" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="tfDatabasePath" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="bnDatabasePathFileOpen" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="lbTestDatabaseWarning" min="-2" pref="22" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnSave" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbTestDatabase" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="bnTestDatabase" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.lbDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.tfDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.tfDatabasePath.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnDatabasePathFileOpen">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnDatabasePathFileOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnDatabasePathFileOpenActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabaseWarning">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="33" green="33" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.lbTestDatabaseWarning.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnTestDatabase">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnTestDatabase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnTestDatabaseActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabase">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.lbTestDatabase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnSave">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnSave.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnSaveActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -1,366 +0,0 @@
/*
* Enterprise Artifacts Manager
*
* Copyright 2015-2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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();
}// </editor-fold>//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
}

View File

@ -18,58 +18,44 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnOverallPanel">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Component id="pnDatabaseContentButtons" max="32767" attributes="0"/>
<Component id="cbEnableEnterpriseArtifactsManager" min="-2" pref="215" max="-2" attributes="0"/> <Component id="tbOops" alignment="1" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <Component id="pnDatabaseConfiguration" max="32767" attributes="0"/>
</Group>
<Component id="pnSettings" alignment="1" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="cbEnableEnterpriseArtifactsManager" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="pnSettings" max="32767" attributes="0"/> <Component id="pnDatabaseConfiguration" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="tbOops" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnDatabaseContentButtons" min="-2" pref="50" max="-2" attributes="0"/>
<EmptySpace min="0" pref="18" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="pnSettings"> <Container class="javax.swing.JPanel" name="pnDatabaseConfiguration">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Database Configuration">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.pnDatabaseConfiguration.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
@ -77,33 +63,112 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="tbOops" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnDatabaseConnectionSettings" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbDbPlatformTypeLabel" max="32767" attributes="0"/>
<Component id="lbDbNameLabel" alignment="0" max="32767" attributes="0"/>
<Component id="lbDbLocationLabel" alignment="0" min="-2" pref="57" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbDbPlatformValue" alignment="0" min="-2" pref="711" max="-2" attributes="0"/>
<Component id="lbDbNameValue" alignment="1" min="-2" pref="711" max="-2" attributes="0"/>
</Group>
<Component id="lbDbLocationValue" alignment="1" min="-2" pref="711" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="bnDbConfigure" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbDbPlatformTypeLabel" max="32767" attributes="0"/>
<Component id="lbDbPlatformValue" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbDbNameLabel" max="32767" attributes="0"/>
<Component id="lbDbNameValue" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbDbLocationLabel" max="32767" attributes="0"/>
<Component id="lbDbLocationValue" min="-2" pref="14" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="11" max="32767" attributes="0"/>
<Component id="bnDbConfigure" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbDbPlatformTypeLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.lbDbPlatformTypeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDbNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.lbDbNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDbLocationLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.lbDbLocationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnDbConfigure">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnDbConfigure.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnDbConfigureActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbDbPlatformValue">
</Component>
<Component class="javax.swing.JLabel" name="lbDbNameValue">
</Component>
<Component class="javax.swing.JLabel" name="lbDbLocationValue">
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnDatabaseContentButtons">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/> <Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="bnManageTags" min="-2" max="-2" attributes="0"/> <Component id="bnManageTags" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/> <Component id="bnManageTypes" min="-2" max="-2" attributes="0"/>
</Group> <EmptySpace max="32767" attributes="0"/>
</Group>
<EmptySpace min="0" pref="188" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
<Component id="tbOops" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnDatabaseConnectionSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="33" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="bnImportDatabase" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="bnImportDatabase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnManageTags" alignment="3" min="-2" pref="25" max="-2" attributes="0"/> <Component id="bnManageTags" alignment="3" min="-2" pref="25" max="-2" attributes="0"/>
@ -131,101 +196,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnImportDatabaseActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnImportDatabaseActionPerformed"/>
</Events> </Events>
</Component> </Component>
<Container class="javax.swing.JPanel" name="pnDatabaseConnectionSettings">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Database Settings">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.lbDatabaseSettings.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lbDatabasePlatform" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="comboboxSelectDatabaseType" min="-2" pref="79" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnConfigureDatabaseSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="3" pref="3" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDatabasePlatform" alignment="3" max="32767" attributes="0"/>
<Component id="comboboxSelectDatabaseType" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnConfigureDatabaseSettings" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JComboBox" name="comboboxSelectDatabaseType">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="2">
<StringItem index="0" value="test 1"/>
<StringItem index="1" value="test 2"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="comboboxSelectDatabaseTypeActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabasePlatform">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.lbDatabasePlatform.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnConfigureDatabaseSettings">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.bnConfigureDatabaseSettings.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnConfigureDatabaseSettingsActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JTextField" name="tbOops">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="tbOops" property="font" relativeSize="false" size="12"/>
</FontInfo>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.tbOops.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnManageTags"> <Component class="javax.swing.JButton" name="bnManageTags">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -254,24 +224,21 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="javax.swing.JCheckBox" name="cbEnableEnterpriseArtifactsManager"> <Component class="javax.swing.JTextField" name="tbOops">
<Properties> <Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor"> <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true"> <FontInfo relative="true">
<Font bold="false" component="cbEnableEnterpriseArtifactsManager" property="font" relativeSize="false" size="11"/> <Font bold="true" component="tbOops" property="font" relativeSize="false" size="12"/>
</FontInfo> </FontInfo>
</Property> </Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactsmanager/optionspanel/Bundle.properties" key="GlobalSettingsPanel.tbOops.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property> </Property>
</Properties> </Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cbEnableEnterpriseArtifactsManagerItemStateChanged"/>
</Events>
</Component> </Component>
</SubComponents> </SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form> </Form>

View File

@ -21,8 +21,6 @@ package org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.optionspan
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.netbeans.spi.options.OptionsPanelController; import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle.Messages; 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.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel; import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.experimental.enterpriseartifactsmanager.datamodel.EamDbPlatformEnum; 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 * Main settings panel for the enterprise artifacts manager
@ -44,10 +43,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private final IngestJobEventPropertyChangeListener ingestJobEventListener; private final IngestJobEventPropertyChangeListener ingestJobEventListener;
private boolean dbConfigured;
private boolean initiallyEnabled;
private boolean comboboxSelectDatabaseTypeActionListenerActive;
/** /**
* Creates new form EnterpriseArtifactsManagerOptionsPanel * Creates new form EnterpriseArtifactsManagerOptionsPanel
*/ */
@ -62,12 +57,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
@Messages({"GlobalSettingsPanel.title=Global Enterprise Artifacts Manager Settings"}) @Messages({"GlobalSettingsPanel.title=Global Enterprise Artifacts Manager Settings"})
private void customizeComponents() { private void customizeComponents() {
setName(Bundle.GlobalSettingsPanel_title()); 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() { private void addIngestJobEventsListener() {
@ -84,22 +73,77 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() { private void initComponents() {
jScrollPane = new javax.swing.JScrollPane(); pnDatabaseConfiguration = new javax.swing.JPanel();
pnOverallPanel = new javax.swing.JPanel(); lbDbPlatformTypeLabel = new javax.swing.JLabel();
pnSettings = new javax.swing.JPanel(); 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(); 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(); bnManageTags = new javax.swing.JButton();
bnManageTypes = new javax.swing.JButton(); bnManageTypes = new javax.swing.JButton();
cbEnableEnterpriseArtifactsManager = new javax.swing.JCheckBox(); tbOops = new javax.swing.JTextField();
setName(""); // NOI18N 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 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 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 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.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 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); javax.swing.GroupLayout pnDatabaseContentButtonsLayout = new javax.swing.GroupLayout(pnDatabaseContentButtons);
pnSettings.setLayout(pnSettingsLayout); pnDatabaseContentButtons.setLayout(pnDatabaseContentButtonsLayout);
pnSettingsLayout.setHorizontalGroup( pnDatabaseContentButtonsLayout.setHorizontalGroup(
pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSettingsLayout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup()
.addContainerGap() .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) .addComponent(bnImportDatabase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnManageTags) .addComponent(bnManageTags)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnManageTypes))) .addComponent(bnManageTypes)
.addGap(0, 188, Short.MAX_VALUE))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
); );
pnSettingsLayout.setVerticalGroup( pnDatabaseContentButtonsLayout.setVerticalGroup(
pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnSettingsLayout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseContentButtonsLayout.createSequentialGroup()
.addGap(8, 8, 8) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(pnDatabaseContentButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.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(bnImportDatabase) .addComponent(bnImportDatabase)
.addComponent(bnManageTags, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) .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)) .addComponent(bnManageTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(34, 34, 34)) .addGap(34, 34, 34))
); );
cbEnableEnterpriseArtifactsManager.setFont(cbEnableEnterpriseArtifactsManager.getFont().deriveFont(cbEnableEnterpriseArtifactsManager.getFont().getStyle() & ~java.awt.Font.BOLD, 11)); tbOops.setEditable(false);
org.openide.awt.Mnemonics.setLocalizedText(cbEnableEnterpriseArtifactsManager, org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.cbEnableEnterpriseArtifactsManager.text")); // NOI18N tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
cbEnableEnterpriseArtifactsManager.addItemListener(new java.awt.event.ItemListener() { tbOops.setText(org.openide.util.NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.tbOops.text")); // NOI18N
public void itemStateChanged(java.awt.event.ItemEvent evt) { tbOops.setBorder(null);
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);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane) .addContainerGap()
.addGap(2, 2, 2)) .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))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//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 private void bnImportDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnImportDatabaseActionPerformed
ImportHashDatabaseDialog dialog = new ImportHashDatabaseDialog(); ImportHashDatabaseDialog dialog = new ImportHashDatabaseDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null); firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnImportDatabaseActionPerformed }//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<String> cb = (JComboBox<String>) 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 private void bnManageTagsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTagsActionPerformed
ManageTagsDialog dialog = new ManageTagsDialog(); ManageTagsDialog dialog = new ManageTagsDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null); firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnManageTagsActionPerformed }//GEN-LAST:event_bnManageTagsActionPerformed
private void bnManageTypesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTypesActionPerformed 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); firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnManageTypesActionPerformed }//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 @Override
@Messages({"GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module."})
public void load() { public void load() {
tbOops.setText(""); tbOops.setText("");
enableAllSubComponents(false); enableAllSubComponents(false);
EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
initiallyEnabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.enabled")); // NON-NLS switch (selectedPlatform) {
cbEnableEnterpriseArtifactsManager.setSelected(initiallyEnabled); // NON-NLS case POSTGRESQL:
String selectedPlatformString = ModuleSettings.getConfigSetting("EnterpriseArtifactsManager", "db.selectedPlatform"); // NON-NLS PostgresEamDbSettings dbSettingsPg = new PostgresEamDbSettings();
dbConfigured = selectedPlatformString != null; 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;
}
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);
}
this.ingestStateUpdated(); this.ingestStateUpdated();
} }
@Override @Override
public void store() { // Click OK or Apply on Options Panel 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. * @return true if it's okay, false otherwise.
*/ */
boolean valid() { public 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;
}
return true; return true;
} }
@Override @Override
public void saveSettings() { // Click OK on Global Settings Panel 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 @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() { private void ingestStateUpdated() {
if (!SwingUtilities.isEventDispatchThread()) { if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
@ -437,13 +334,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
} }
if (IngestManager.getInstance().isIngestRunning()) { if (IngestManager.getInstance().isIngestRunning()) {
cbEnableEnterpriseArtifactsManager.setEnabled(false);
tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning()); tbOops.setText(Bundle.GlobalSettingsPanel_validationErrMsg_ingestRunning());
enableAllSubComponents(false); enableAllSubComponents(false);
} else {
cbEnableEnterpriseArtifactsManager.setEnabled(true);
tbOops.setText("");
enableAllSubComponents(cbEnableEnterpriseArtifactsManager.isSelected());
} }
} }
@ -456,22 +348,20 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
* @return True * @return True
*/ */
private boolean enableAllSubComponents(Boolean enable) { private boolean enableAllSubComponents(Boolean enable) {
enableDatabaseSubComponents(enable); enableDatabaseConfigureButton(enable);
enableButtonSubComponents(enable); enableButtonSubComponents(enable);
return true; return true;
} }
/** /**
* Wrapper around each of the enableXYZ methods that configure the database * Enable the Configure button
* to enable/disable them all at the same time.
* *
* @param enable * @param enable
* *
* @return True * @return True
*/ */
private boolean enableDatabaseSubComponents(Boolean enable) { private boolean enableDatabaseConfigureButton(Boolean enable) {
enableDatabasePlatformComboBox(enable); bnDbConfigure.setEnabled(enable);
enableConfigureDatabasePlatformButton(enable);
return true; return true;
} }
@ -484,84 +374,25 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
* @return True * @return True
*/ */
private boolean enableButtonSubComponents(Boolean enable) { private boolean enableButtonSubComponents(Boolean enable) {
enableManageCorrelationTypesButton(enable); bnManageTypes.setEnabled(enable);
enableImportGloballyKnownArtifactsButton(enable); bnImportDatabase.setEnabled(enable);
enableManageTagsButton(enable); bnManageTags.setEnabled(enable);
return true; 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 // 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 bnImportDatabase;
private javax.swing.JButton bnManageTags; private javax.swing.JButton bnManageTags;
private javax.swing.JButton bnManageTypes; private javax.swing.JButton bnManageTypes;
private javax.swing.JCheckBox cbEnableEnterpriseArtifactsManager; private javax.swing.JLabel lbDbLocationLabel;
private javax.swing.JComboBox<String> comboboxSelectDatabaseType; private javax.swing.JLabel lbDbLocationValue;
private javax.swing.JScrollPane jScrollPane; private javax.swing.JLabel lbDbNameLabel;
private javax.swing.JLabel lbDatabasePlatform; private javax.swing.JLabel lbDbNameValue;
private javax.swing.JPanel pnDatabaseConnectionSettings; private javax.swing.JLabel lbDbPlatformTypeLabel;
private javax.swing.JPanel pnOverallPanel; private javax.swing.JLabel lbDbPlatformValue;
private javax.swing.JPanel pnSettings; private javax.swing.JPanel pnDatabaseConfiguration;
private javax.swing.JPanel pnDatabaseContentButtons;
private javax.swing.JTextField tbOops; private javax.swing.JTextField tbOops;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -119,8 +119,11 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
orgs = dbManager.getOrganizations(); orgs = dbManager.getOrganizations();
orgs.forEach((org) -> { orgs.forEach((org) -> {
comboboxSourceOrganization.addItem(org.getName()); comboboxSourceOrganization.addItem(org.getName());
selectedOrg = orgs.get(0);
}); });
if (!orgs.isEmpty()) {
selectedOrg = orgs.get(0);
}
valid();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failure populating combobox with organizations.", 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() { public boolean valid() {
lbWarningMsg.setText(""); lbWarningMsg.setText("");
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
lbWarningMsg.setText(Bundle.ImportHashDatabaseDialog_validation_notEnabled()); lbWarningMsg.setText(Bundle.ImportHashDatabaseDialog_validation_notEnabled());
return false; return false;
} }
return enableOkButton(checkFields()); return enableOkButton(checkFields() && null != selectedOrg);
} }
/** /**
@ -545,6 +548,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
return; return;
} }
} }
valid();
}//GEN-LAST:event_comboboxSourceOrganizationActionPerformed }//GEN-LAST:event_comboboxSourceOrganizationActionPerformed
@NbBundle.Messages({"ImportHashDatabaseDialog.ImportHashDatabaseWorker.displayName=Importing Hash Database"}) @NbBundle.Messages({"ImportHashDatabaseDialog.ImportHashDatabaseWorker.displayName=Importing Hash Database"})
@ -561,7 +565,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
this.knownStatus = knownStatus; this.knownStatus = knownStatus;
this.globalSetID = globalSetID; this.globalSetID = globalSetID;
if (!dbManager.isEnabled()) { if (!EamDb.isEnabled()) {
throw new EamDbException("Enterprise artifacts manager database settings were not properly initialized"); // NON-NLS throw new EamDbException("Enterprise artifacts manager database settings were not properly initialized"); // NON-NLS
} }
} }