mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
Merge remote-tracking branch 'upstream/develop' into iwUpdatePath
This commit is contained in:
commit
1340320bcf
@ -1,132 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
|
|
||||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
|
||||||
<NonVisualComponents>
|
|
||||||
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
|
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
|
||||||
<Properties>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardChooseDataSourceVisual.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
</NonVisualComponents>
|
|
||||||
<Properties>
|
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
|
||||||
<Dimension value="[588, 328]"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<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" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Component id="inputPanel" 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 min="-2" pref="6" max="-2" attributes="0"/>
|
|
||||||
<Component id="inputPanel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace pref="44" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
<SubComponents>
|
|
||||||
<Container class="javax.swing.JPanel" name="inputPanel">
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
|
||||||
<Component id="typeTabel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="typeComboBox" min="-2" pref="292" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="0" pref="119" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Component id="typePanel" alignment="1" pref="548" 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" attributes="0">
|
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
|
||||||
<Component id="typeTabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="typeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
|
||||||
<Component id="typePanel" min="-2" pref="225" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
<SubComponents>
|
|
||||||
<Component class="javax.swing.JLabel" name="typeTabel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardChooseDataSourceVisual.typeTabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
<Container class="javax.swing.JPanel" name="typePanel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
|
||||||
<Dimension value="[0, 65]"/>
|
|
||||||
</Property>
|
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
|
||||||
<Dimension value="[521, 65]"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="548" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="225" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
</Container>
|
|
||||||
<Component class="javax.swing.JComboBox" name="typeComboBox">
|
|
||||||
<Properties>
|
|
||||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
|
||||||
<StringArray count="0"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
|
||||||
</AuxValues>
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
|
||||||
</Form>
|
|
@ -1,330 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2011-2014 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.casemodule;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.beans.PropertyChangeEvent;
|
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import javax.swing.JList;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JSeparator;
|
|
||||||
import javax.swing.ListCellRenderer;
|
|
||||||
import javax.swing.event.DocumentEvent;
|
|
||||||
import org.openide.util.Lookup;
|
|
||||||
import org.openide.util.NbBundle;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.autopsy.datasourceprocessors.RawDSProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* visual component for the first panel of add image wizard. Allows the user to
|
|
||||||
* choose the data source type and then select the data source
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
final class AddImageWizardChooseDataSourceVisual extends JPanel {
|
|
||||||
|
|
||||||
static final Logger logger = Logger.getLogger(AddImageWizardChooseDataSourceVisual.class.getName());
|
|
||||||
|
|
||||||
private AddImageWizardChooseDataSourcePanel wizPanel;
|
|
||||||
|
|
||||||
private JPanel currentPanel;
|
|
||||||
|
|
||||||
private Map<String, DataSourceProcessor> datasourceProcessorsMap = new HashMap<>();
|
|
||||||
|
|
||||||
List<String> coreDSPTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new form AddImageVisualPanel1
|
|
||||||
*
|
|
||||||
* @param wizPanel corresponding WizardPanel to handle logic of wizard step
|
|
||||||
*/
|
|
||||||
AddImageWizardChooseDataSourceVisual(AddImageWizardChooseDataSourcePanel wizPanel) {
|
|
||||||
initComponents();
|
|
||||||
this.wizPanel = wizPanel;
|
|
||||||
|
|
||||||
customInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
private void customInit() {
|
|
||||||
|
|
||||||
typePanel.setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
discoverDataSourceProcessors();
|
|
||||||
|
|
||||||
// set up the DSP type combobox
|
|
||||||
typeComboBox.removeAllItems();
|
|
||||||
|
|
||||||
Set<String> dspTypes = datasourceProcessorsMap.keySet();
|
|
||||||
|
|
||||||
// make a list of core DSPs
|
|
||||||
// ensure that the core DSPs are at the top and in a fixed order
|
|
||||||
coreDSPTypes.add(ImageDSProcessor.getType());
|
|
||||||
// Local disk processing is not allowed for multi-user cases
|
|
||||||
if (Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
|
|
||||||
coreDSPTypes.add(LocalDiskDSProcessor.getType());
|
|
||||||
} else {
|
|
||||||
// remove LocalDiskDSProcessor from list of DSPs
|
|
||||||
datasourceProcessorsMap.remove(LocalDiskDSProcessor.getType());
|
|
||||||
}
|
|
||||||
coreDSPTypes.add(LocalFilesDSProcessor.getType());
|
|
||||||
coreDSPTypes.add(RawDSProcessor.getType());
|
|
||||||
|
|
||||||
for (String dspType : coreDSPTypes) {
|
|
||||||
typeComboBox.addItem(dspType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now add any addtional DSPs that haven't already been added
|
|
||||||
for (String dspType : dspTypes) {
|
|
||||||
if (!coreDSPTypes.contains(dspType)) {
|
|
||||||
typeComboBox.addItem(dspType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typeComboBox.setRenderer(new ComboboxSeparatorRenderer(typeComboBox.getRenderer()) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean addSeparatorAfter(JList list, Object value, int index) {
|
|
||||||
return (index == coreDSPTypes.size() - 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//add actionlistner to listen for change
|
|
||||||
ActionListener cbActionListener = new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
dspSelectionChanged();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
typeComboBox.addActionListener(cbActionListener);
|
|
||||||
typeComboBox.setSelectedIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void discoverDataSourceProcessors() {
|
|
||||||
|
|
||||||
for (DataSourceProcessor dsProcessor : Lookup.getDefault().lookupAll(DataSourceProcessor.class)) {
|
|
||||||
|
|
||||||
if (!datasourceProcessorsMap.containsKey(dsProcessor.getDataSourceType())) {
|
|
||||||
datasourceProcessorsMap.put(dsProcessor.getDataSourceType(), dsProcessor);
|
|
||||||
} else {
|
|
||||||
logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dspSelectionChanged() {
|
|
||||||
// update the current panel to selection
|
|
||||||
currentPanel = getCurrentDSProcessor().getPanel();
|
|
||||||
updateCurrentPanel(currentPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the current panel to the given panel.
|
|
||||||
*
|
|
||||||
* @param panel instance of ImageTypePanel to change to
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private void updateCurrentPanel(JPanel panel) {
|
|
||||||
currentPanel = panel;
|
|
||||||
typePanel.removeAll();
|
|
||||||
typePanel.add(currentPanel, BorderLayout.CENTER);
|
|
||||||
typePanel.validate();
|
|
||||||
typePanel.repaint();
|
|
||||||
currentPanel.addPropertyChangeListener(new PropertyChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
|
||||||
if (evt.getPropertyName().equals(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString())) {
|
|
||||||
updateUI(null);
|
|
||||||
}
|
|
||||||
if (evt.getPropertyName().equals(DataSourceProcessor.DSP_PANEL_EVENT.FOCUS_NEXT.toString())) {
|
|
||||||
wizPanel.moveFocusToNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
updateUI(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the currently selected DS Processor
|
|
||||||
*
|
|
||||||
* @return DataSourceProcessor the DataSourceProcessor corresponding to the
|
|
||||||
* data source type selected in the combobox
|
|
||||||
*/
|
|
||||||
protected DataSourceProcessor getCurrentDSProcessor() {
|
|
||||||
// get the type of the currently selected panel and then look up
|
|
||||||
// the correspodning DS Handler in the map
|
|
||||||
String dsType = (String) typeComboBox.getSelectedItem();
|
|
||||||
DataSourceProcessor dsProcessor = datasourceProcessorsMap.get(dsType);
|
|
||||||
|
|
||||||
return dsProcessor;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the this panel. This name will be shown on the left
|
|
||||||
* panel of the "Add Image" wizard panel.
|
|
||||||
*
|
|
||||||
* @return name the name of this panel
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return NbBundle.getMessage(this.getClass(), "AddImageWizardChooseDataSourceVisual.getName.text");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
|
||||||
private void initComponents() {
|
|
||||||
|
|
||||||
buttonGroup1 = new javax.swing.ButtonGroup();
|
|
||||||
jLabel2 = new javax.swing.JLabel();
|
|
||||||
inputPanel = new javax.swing.JPanel();
|
|
||||||
typeTabel = new javax.swing.JLabel();
|
|
||||||
typePanel = new javax.swing.JPanel();
|
|
||||||
typeComboBox = new javax.swing.JComboBox<String>();
|
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(AddImageWizardChooseDataSourceVisual.class, "AddImageWizardChooseDataSourceVisual.jLabel2.text")); // NOI18N
|
|
||||||
|
|
||||||
setPreferredSize(new java.awt.Dimension(588, 328));
|
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(typeTabel, org.openide.util.NbBundle.getMessage(AddImageWizardChooseDataSourceVisual.class, "AddImageWizardChooseDataSourceVisual.typeTabel.text")); // NOI18N
|
|
||||||
|
|
||||||
typePanel.setMinimumSize(new java.awt.Dimension(0, 65));
|
|
||||||
typePanel.setPreferredSize(new java.awt.Dimension(521, 65));
|
|
||||||
|
|
||||||
javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel);
|
|
||||||
typePanel.setLayout(typePanelLayout);
|
|
||||||
typePanelLayout.setHorizontalGroup(
|
|
||||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 548, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
typePanelLayout.setVerticalGroup(
|
|
||||||
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 225, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout inputPanelLayout = new javax.swing.GroupLayout(inputPanel);
|
|
||||||
inputPanel.setLayout(inputPanelLayout);
|
|
||||||
inputPanelLayout.setHorizontalGroup(
|
|
||||||
inputPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(inputPanelLayout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addGroup(inputPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(inputPanelLayout.createSequentialGroup()
|
|
||||||
.addComponent(typeTabel)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 292, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(0, 119, Short.MAX_VALUE))
|
|
||||||
.addComponent(typePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 548, Short.MAX_VALUE))
|
|
||||||
.addContainerGap())
|
|
||||||
);
|
|
||||||
inputPanelLayout.setVerticalGroup(
|
|
||||||
inputPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(inputPanelLayout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addGroup(inputPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
||||||
.addComponent(typeTabel)
|
|
||||||
.addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
||||||
.addComponent(typePanel, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
|
||||||
this.setLayout(layout);
|
|
||||||
layout.setHorizontalGroup(
|
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addComponent(inputPanel, 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()
|
|
||||||
.addGap(6, 6, 6)
|
|
||||||
.addComponent(inputPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addContainerGap(44, Short.MAX_VALUE))
|
|
||||||
);
|
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
|
||||||
private javax.swing.ButtonGroup buttonGroup1;
|
|
||||||
private javax.swing.JPanel inputPanel;
|
|
||||||
private javax.swing.JLabel jLabel2;
|
|
||||||
private javax.swing.JComboBox<String> typeComboBox;
|
|
||||||
private javax.swing.JPanel typePanel;
|
|
||||||
private javax.swing.JLabel typeTabel;
|
|
||||||
// End of variables declaration//GEN-END:variables
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The "listener" that updates the UI of this panel based on the changes of
|
|
||||||
* fields on this panel. This is also the method to check whether all the
|
|
||||||
* fields on this panel are correctly filled and decides whether to enable
|
|
||||||
* the "Next" button or not.
|
|
||||||
*
|
|
||||||
* @param e the document event
|
|
||||||
*/
|
|
||||||
public void updateUI(DocumentEvent e) {
|
|
||||||
// Enable the Next button if the current DSP panel is valid
|
|
||||||
this.wizPanel.enableNextButton(getCurrentDSProcessor().isPanelValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
public abstract class ComboboxSeparatorRenderer implements ListCellRenderer {
|
|
||||||
|
|
||||||
private ListCellRenderer delegate;
|
|
||||||
|
|
||||||
private JPanel separatorPanel = new JPanel(new BorderLayout());
|
|
||||||
|
|
||||||
private JSeparator separator = new JSeparator();
|
|
||||||
|
|
||||||
public ComboboxSeparatorRenderer(ListCellRenderer delegate) {
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
|
||||||
Component comp = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
|
||||||
if (index != -1 && addSeparatorAfter(list, value, index)) {
|
|
||||||
separatorPanel.removeAll();
|
|
||||||
separatorPanel.add(comp, BorderLayout.CENTER);
|
|
||||||
separatorPanel.add(separator, BorderLayout.SOUTH);
|
|
||||||
return separatorPanel;
|
|
||||||
} else {
|
|
||||||
return comp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean addSeparatorAfter(JList list, Object value, int index);
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,23 +39,17 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript
|
|||||||
* The "Add Image" wizard panel1 handling the logic of selecting image file(s)
|
* The "Add Image" wizard panel1 handling the logic of selecting image file(s)
|
||||||
* to add to Case, and pick the time zone.
|
* to add to Case, and pick the time zone.
|
||||||
*/
|
*/
|
||||||
class AddImageWizardChooseDataSourcePanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener {
|
class AddImageWizardDataSourceSettingsPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The visual component that displays this panel. If you need to access the
|
* The visual component that displays this panel. If you need to access the
|
||||||
* component from this class, just use getComponent().
|
* component from this class, just use getComponent().
|
||||||
*/
|
*/
|
||||||
private final AddImageWizardAddingProgressPanel progressPanel;
|
private AddImageWizardDataSourceSettingsVisual component;
|
||||||
private AddImageWizardChooseDataSourceVisual component;
|
|
||||||
private boolean isNextEnable = false;
|
private boolean isNextEnable = false;
|
||||||
private static final String PROP_LASTDATASOURCE_PATH = "LBL_LastDataSource_PATH"; //NON-NLS
|
|
||||||
private static final String PROP_LASTDATASOURCE_TYPE = "LBL_LastDataSource_TYPE"; //NON-NLS
|
|
||||||
// paths to any set hash lookup databases (can be null)
|
// paths to any set hash lookup databases (can be null)
|
||||||
private String NSRLPath, knownBadPath;
|
|
||||||
|
|
||||||
AddImageWizardChooseDataSourcePanel(AddImageWizardAddingProgressPanel proPanel) {
|
AddImageWizardDataSourceSettingsPanel() {
|
||||||
|
|
||||||
this.progressPanel = proPanel;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,10 +62,10 @@ class AddImageWizardChooseDataSourcePanel extends ShortcutWizardDescriptorPanel
|
|||||||
* @return component the UI component of this wizard panel
|
* @return component the UI component of this wizard panel
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AddImageWizardChooseDataSourceVisual getComponent() {
|
public AddImageWizardDataSourceSettingsVisual getComponent() {
|
||||||
if (component == null) {
|
if (component == null) {
|
||||||
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
component = new AddImageWizardChooseDataSourceVisual(this);
|
component = new AddImageWizardDataSourceSettingsVisual(this);
|
||||||
}
|
}
|
||||||
component.addPropertyChangeListener(this);
|
component.addPropertyChangeListener(this);
|
||||||
return component;
|
return component;
|
||||||
@ -87,8 +81,7 @@ class AddImageWizardChooseDataSourcePanel extends ShortcutWizardDescriptorPanel
|
|||||||
public HelpCtx getHelp() {
|
public HelpCtx getHelp() {
|
||||||
// Show no Help button for this panel:
|
// Show no Help button for this panel:
|
||||||
return HelpCtx.DEFAULT_HELP;
|
return HelpCtx.DEFAULT_HELP;
|
||||||
// If you have context help:
|
|
||||||
// return new HelpCtx(SampleWizardPanel1.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,10 +157,6 @@ class AddImageWizardChooseDataSourcePanel extends ShortcutWizardDescriptorPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can use a settings object to keep track of state. Normally the
|
|
||||||
// settings object will be the WizardDescriptor, so you can use
|
|
||||||
// WizardDescriptor.getProperty & putProperty to store information entered
|
|
||||||
// by the user.
|
|
||||||
/**
|
/**
|
||||||
* Provides the wizard panel with the current data--either the default data
|
* Provides the wizard panel with the current data--either the default data
|
||||||
* or already-modified settings, if the user used the previous and/or next
|
* or already-modified settings, if the user used the previous and/or next
|
||||||
@ -178,26 +167,16 @@ class AddImageWizardChooseDataSourcePanel extends ShortcutWizardDescriptorPanel
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void readSettings(WizardDescriptor settings) {
|
public void readSettings(WizardDescriptor settings) {
|
||||||
|
|
||||||
//reset settings if supports it
|
|
||||||
//getComponent().reset();
|
|
||||||
// Prepopulate the image directory from the properties file
|
// Prepopulate the image directory from the properties file
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Load hash database settings, enable or disable the checkbox
|
|
||||||
this.NSRLPath = null;
|
|
||||||
this.knownBadPath = null;
|
|
||||||
//JCheckBox lookupFilesCheckbox = component.getLookupFilesCheckbox();
|
|
||||||
//lookupFilesCheckbox.setSelected(false);
|
|
||||||
//lookupFilesCheckbox.setEnabled(this.NSRLPath != null || this.knownBadPath != null);
|
|
||||||
|
|
||||||
// If there is a process object in the settings, revert it and remove it from the settings
|
// If there is a process object in the settings, revert it and remove it from the settings
|
||||||
AddImageAction.CleanupTask cleanupTask = (AddImageAction.CleanupTask) settings.getProperty(AddImageAction.IMAGECLEANUPTASK_PROP);
|
AddImageAction.CleanupTask cleanupTask = (AddImageAction.CleanupTask) settings.getProperty(AddImageAction.IMAGECLEANUPTASK_PROP);
|
||||||
if (cleanupTask != null) {
|
if (cleanupTask != null) {
|
||||||
try {
|
try {
|
||||||
cleanupTask.cleanup();
|
cleanupTask.cleanup();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger logger = Logger.getLogger(AddImageWizardChooseDataSourcePanel.class.getName());
|
Logger logger = Logger.getLogger(AddImageWizardDataSourceSettingsPanel.class.getName());
|
||||||
logger.log(Level.WARNING, "Error cleaning up image task", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error cleaning up image task", ex); //NON-NLS
|
||||||
} finally {
|
} finally {
|
||||||
cleanupTask.disable();
|
cleanupTask.disable();
|
||||||
@ -205,7 +184,7 @@ class AddImageWizardChooseDataSourcePanel extends ShortcutWizardDescriptorPanel
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
component.setDspSelection((String)settings.getProperty("SelectedDsp")); //NON-NLS magic string used SelectDataSourceProcessorPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<Properties>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[588, 328]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<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="typePanel" alignment="0" pref="588" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="typePanel" alignment="0" pref="328" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="typePanel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[0, 65]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[521, 65]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="588" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="328" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* 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.casemodule;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSeparator;
|
||||||
|
import javax.swing.ListCellRenderer;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* visual component for the first panel of add image wizard. Allows the user to
|
||||||
|
* choose the data source type and then select the data source
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
final class AddImageWizardDataSourceSettingsVisual extends JPanel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(AddImageWizardDataSourceSettingsVisual.class.getName());
|
||||||
|
|
||||||
|
private final AddImageWizardDataSourceSettingsPanel wizPanel;
|
||||||
|
|
||||||
|
private JPanel currentPanel;
|
||||||
|
|
||||||
|
private final Map<String, DataSourceProcessor> datasourceProcessorsMap = new HashMap<>();
|
||||||
|
|
||||||
|
private String currentDsp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form AddImageVisualPanel1
|
||||||
|
*
|
||||||
|
* @param wizPanel corresponding WizardPanel to handle logic of wizard step
|
||||||
|
*/
|
||||||
|
AddImageWizardDataSourceSettingsVisual(AddImageWizardDataSourceSettingsPanel wizPanel) {
|
||||||
|
initComponents();
|
||||||
|
this.wizPanel = wizPanel;
|
||||||
|
typePanel.setLayout(new BorderLayout());
|
||||||
|
discoverDataSourceProcessors();
|
||||||
|
currentDsp = ImageDSProcessor.getType(); //default value to the ImageDSProcessor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the map of DataSourceProcessors which so they can be retrieved
|
||||||
|
* by name.
|
||||||
|
*/
|
||||||
|
private void discoverDataSourceProcessors() {
|
||||||
|
for (DataSourceProcessor dsProcessor : Lookup.getDefault().lookupAll(DataSourceProcessor.class)) {
|
||||||
|
if (!datasourceProcessorsMap.containsKey(dsProcessor.getDataSourceType())) {
|
||||||
|
datasourceProcessorsMap.put(dsProcessor.getDataSourceType(), dsProcessor);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current DataSourceProcessor and update the panel to reflect that
|
||||||
|
* selection.
|
||||||
|
*
|
||||||
|
* @param dsType - the name of the DataSourceProcessor you wish to have this
|
||||||
|
* panel display settings for.
|
||||||
|
*/
|
||||||
|
void setDspSelection(String dsType) {
|
||||||
|
currentDsp = dsType;
|
||||||
|
currentPanel = datasourceProcessorsMap.get(dsType).getPanel();
|
||||||
|
updateCurrentPanel(currentPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the current panel to the given panel.
|
||||||
|
*
|
||||||
|
* @param panel instance of ImageTypePanel to change to
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void updateCurrentPanel(JPanel panel) {
|
||||||
|
currentPanel = panel;
|
||||||
|
typePanel.removeAll();
|
||||||
|
typePanel.add(currentPanel, BorderLayout.CENTER);
|
||||||
|
typePanel.validate();
|
||||||
|
typePanel.repaint();
|
||||||
|
currentPanel.addPropertyChangeListener(new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if (evt.getPropertyName().equals(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString())) {
|
||||||
|
wizPanel.enableNextButton(getCurrentDSProcessor().isPanelValid());
|
||||||
|
}
|
||||||
|
if (evt.getPropertyName().equals(DataSourceProcessor.DSP_PANEL_EVENT.FOCUS_NEXT.toString())) {
|
||||||
|
wizPanel.moveFocusToNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.wizPanel.enableNextButton(getCurrentDSProcessor().isPanelValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently selected DS Processor
|
||||||
|
*
|
||||||
|
* @return DataSourceProcessor the DataSourceProcessor corresponding to the
|
||||||
|
* data source type selected in the combobox
|
||||||
|
*/
|
||||||
|
protected DataSourceProcessor getCurrentDSProcessor() {
|
||||||
|
// get the type of the currently selected panel and then look up
|
||||||
|
// the correspodning DS Handler in the map
|
||||||
|
DataSourceProcessor dsProcessor = datasourceProcessorsMap.get(currentDsp);
|
||||||
|
return dsProcessor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the this panel. This name will be shown on the left
|
||||||
|
* panel of the "Add Image" wizard panel.
|
||||||
|
*
|
||||||
|
* @return name the name of this panel
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NbBundle.getMessage(this.getClass(), "AddImageWizardChooseDataSourceVisual.getName.text");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
typePanel = new javax.swing.JPanel();
|
||||||
|
|
||||||
|
setPreferredSize(new java.awt.Dimension(588, 328));
|
||||||
|
|
||||||
|
typePanel.setMinimumSize(new java.awt.Dimension(0, 65));
|
||||||
|
typePanel.setPreferredSize(new java.awt.Dimension(521, 65));
|
||||||
|
|
||||||
|
javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel);
|
||||||
|
typePanel.setLayout(typePanelLayout);
|
||||||
|
typePanelLayout.setHorizontalGroup(
|
||||||
|
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 588, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
typePanelLayout.setVerticalGroup(
|
||||||
|
typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 328, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(typePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 588, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(typePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 328, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JPanel typePanel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public abstract class ComboboxSeparatorRenderer implements ListCellRenderer {
|
||||||
|
|
||||||
|
private final ListCellRenderer delegate;
|
||||||
|
|
||||||
|
private final JPanel separatorPanel = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
|
private final JSeparator separator = new JSeparator();
|
||||||
|
|
||||||
|
public ComboboxSeparatorRenderer(ListCellRenderer delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
|
Component comp = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||||
|
if (index != -1 && addSeparatorAfter(list, value, index)) {
|
||||||
|
separatorPanel.removeAll();
|
||||||
|
separatorPanel.add(comp, BorderLayout.CENTER);
|
||||||
|
separatorPanel.add(separator, BorderLayout.SOUTH);
|
||||||
|
return separatorPanel;
|
||||||
|
} else {
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean addSeparatorAfter(JList list, Object value, int index);
|
||||||
|
}
|
||||||
|
}
|
@ -69,12 +69,12 @@ class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel {
|
|||||||
private final AddImageAction addImageAction;
|
private final AddImageAction addImageAction;
|
||||||
|
|
||||||
private final AddImageWizardAddingProgressPanel progressPanel;
|
private final AddImageWizardAddingProgressPanel progressPanel;
|
||||||
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
|
private final AddImageWizardDataSourceSettingsPanel dataSourcePanel;
|
||||||
|
|
||||||
private DataSourceProcessor dsProcessor;
|
private DataSourceProcessor dsProcessor;
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
|
|
||||||
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
|
AddImageWizardIngestConfigPanel(AddImageWizardDataSourceSettingsPanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
|
||||||
this.addImageAction = action;
|
this.addImageAction = action;
|
||||||
this.progressPanel = proPanel;
|
this.progressPanel = proPanel;
|
||||||
this.dataSourcePanel = dsPanel;
|
this.dataSourcePanel = dsPanel;
|
||||||
|
@ -40,6 +40,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
|||||||
private List<ShortcutWizardDescriptorPanel> panels;
|
private List<ShortcutWizardDescriptorPanel> panels;
|
||||||
private final AddImageAction action;
|
private final AddImageAction action;
|
||||||
private int progressPanelIndex;
|
private int progressPanelIndex;
|
||||||
|
private int dsPanelIndex;
|
||||||
private final static String PROP_LASTPROFILE_NAME = "AIW_LASTPROFILE_NAME"; //NON-NLS
|
private final static String PROP_LASTPROFILE_NAME = "AIW_LASTPROFILE_NAME"; //NON-NLS
|
||||||
|
|
||||||
AddImageWizardIterator(AddImageAction action) {
|
AddImageWizardIterator(AddImageAction action) {
|
||||||
@ -53,10 +54,11 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
|||||||
private List<ShortcutWizardDescriptorPanel> getPanels() {
|
private List<ShortcutWizardDescriptorPanel> getPanels() {
|
||||||
if (panels == null) {
|
if (panels == null) {
|
||||||
panels = new ArrayList<>();
|
panels = new ArrayList<>();
|
||||||
|
AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel();
|
||||||
|
panels.add(dspSelection);
|
||||||
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel();
|
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel();
|
||||||
|
|
||||||
AddImageWizardChooseDataSourcePanel dsPanel = new AddImageWizardChooseDataSourcePanel(progressPanel);
|
AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel();
|
||||||
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel);
|
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel);
|
||||||
panels.add(dsPanel);
|
panels.add(dsPanel);
|
||||||
List<IngestProfiles.IngestProfile> profiles = IngestProfiles.getIngestProfiles();
|
List<IngestProfiles.IngestProfile> profiles = IngestProfiles.getIngestProfiles();
|
||||||
@ -66,6 +68,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
|||||||
panels.add(ingestConfigPanel);
|
panels.add(ingestConfigPanel);
|
||||||
panels.add(progressPanel);
|
panels.add(progressPanel);
|
||||||
progressPanelIndex = panels.indexOf(progressPanel); //Doing programatically because number of panels is variable
|
progressPanelIndex = panels.indexOf(progressPanel); //Doing programatically because number of panels is variable
|
||||||
|
dsPanelIndex = panels.indexOf(dsPanel);
|
||||||
String[] steps = new String[panels.size()];
|
String[] steps = new String[panels.size()];
|
||||||
for (int i = 0; i < panels.size(); i++) {
|
for (int i = 0; i < panels.size(); i++) {
|
||||||
Component c = panels.get(i).getComponent();
|
Component c = panels.get(i).getComponent();
|
||||||
@ -157,9 +160,9 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
|
|||||||
* @return boolean true if it has previous panel, false if not
|
* @return boolean true if it has previous panel, false if not
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
// disable the previous button on all panels
|
// disable the previous button on all panels except the data source panel
|
||||||
public boolean hasPrevious() {
|
public boolean hasPrevious() {
|
||||||
return false;
|
return (index == dsPanelIndex); //Users should be able to back up to select a different DSP
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.casemodule;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Cursor;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
import org.openide.WizardDescriptor;
|
||||||
|
import org.openide.util.HelpCtx;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.windows.WindowManager;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a wizard panel which contains a panel allowing the selection of the
|
||||||
|
* DataSourceProcessor
|
||||||
|
*/
|
||||||
|
final class AddImageWizardSelectDspPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener {
|
||||||
|
|
||||||
|
@NbBundle.Messages("SelectDataSourceProcessorPanel.name.text=Select Type of Data")
|
||||||
|
private AddImageWizardSelectDspVisual component;
|
||||||
|
private static final String LAST_DSP_PROPERTIES_FILE = "LastDspUsed"; //NON-NLS
|
||||||
|
private static final String LAST_DSP_USED_KEY = "Last_Dsp_Used"; //NON-NLS
|
||||||
|
private static final Logger logger = Logger.getLogger(AddImageWizardSelectDspVisual.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent() {
|
||||||
|
if (component == null) {
|
||||||
|
String lastDspUsed;
|
||||||
|
if (!(ModuleSettings.getConfigSetting(LAST_DSP_PROPERTIES_FILE, LAST_DSP_USED_KEY) == null)
|
||||||
|
&& !ModuleSettings.getConfigSetting(LAST_DSP_PROPERTIES_FILE, LAST_DSP_USED_KEY).isEmpty()) {
|
||||||
|
lastDspUsed = ModuleSettings.getConfigSetting(LAST_DSP_PROPERTIES_FILE, LAST_DSP_USED_KEY);
|
||||||
|
} else {
|
||||||
|
lastDspUsed = ImageDSProcessor.getType();
|
||||||
|
logger.log(Level.WARNING, "There was no properties file containing the last DataSourceProcessor used, Disk Image or VM will be selected as default selection"); //NON-NLS
|
||||||
|
}
|
||||||
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
component = new AddImageWizardSelectDspVisual(lastDspUsed);
|
||||||
|
component.setName(Bundle.SelectDataSourceProcessorPanel_name_text());
|
||||||
|
}
|
||||||
|
component.addPropertyChangeListener(this);
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HelpCtx getHelp() {
|
||||||
|
return HelpCtx.DEFAULT_HELP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSettings(WizardDescriptor data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeSettings(WizardDescriptor data) {
|
||||||
|
String lastDspUsed = component.getSelectedDsp();
|
||||||
|
ModuleSettings.setConfigSetting(LAST_DSP_PROPERTIES_FILE, LAST_DSP_USED_KEY, lastDspUsed);
|
||||||
|
data.putProperty("SelectedDsp", lastDspUsed); //NON-NLS magic string necesary to AddImageWizardChooseDataSourcePanel
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addChangeListener(ChangeListener cl) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeChangeListener(ChangeListener cl) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<NonVisualComponents>
|
||||||
|
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
|
||||||
|
</Component>
|
||||||
|
</NonVisualComponents>
|
||||||
|
<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="588" max="32767" attributes="0"/>
|
||||||
|
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jScrollPane1" alignment="0" pref="588" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="328" max="32767" attributes="0"/>
|
||||||
|
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jScrollPane1" alignment="0" pref="328" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.Box$Filler" name="filler1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[6, 8]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[6, 8]"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||||
|
<Dimension value="[6, 8]"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.RigidArea"/>
|
||||||
|
</AuxValues>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* 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.casemodule;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.Box.Filler;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.JToggleButton;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.datasourceprocessors.RawDSProcessor;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel which displays the available DataSourceProcessors and allows selection of one
|
||||||
|
*/
|
||||||
|
final class AddImageWizardSelectDspVisual extends JPanel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(AddImageWizardSelectDspVisual.class.getName());
|
||||||
|
private String selectedDsp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form SelectDataSourceProcessorPanel
|
||||||
|
*/
|
||||||
|
AddImageWizardSelectDspVisual(String lastDspUsed) {
|
||||||
|
initComponents();
|
||||||
|
selectedDsp = lastDspUsed;
|
||||||
|
createDataSourceProcessorButtons();
|
||||||
|
|
||||||
|
//add actionlistner to listen for change
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the DSP which is currently selected and save it as the selected
|
||||||
|
* DataSourceProcessor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void updateSelectedDsp() {
|
||||||
|
Enumeration<AbstractButton> buttonGroup = buttonGroup1.getElements();
|
||||||
|
while (buttonGroup.hasMoreElements()) {
|
||||||
|
AbstractButton dspButton = buttonGroup.nextElement();
|
||||||
|
if (dspButton.isSelected()) {
|
||||||
|
selectedDsp = dspButton.getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the DataSourceProcessor which is currently selected in this panel
|
||||||
|
*
|
||||||
|
* @return selectedDsp the DataSourceProcessor which is selected in this panel
|
||||||
|
*/
|
||||||
|
String getSelectedDsp() {
|
||||||
|
return selectedDsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the a button for each DataSourceProcessor that should exist as an option.
|
||||||
|
*/
|
||||||
|
private void createDataSourceProcessorButtons() {
|
||||||
|
//Listener for button selection
|
||||||
|
ActionListener cbActionListener = new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
updateSelectedDsp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
List<String> dspList = getListOfDsps();
|
||||||
|
//Set up the constraints for the panel layout
|
||||||
|
GridBagLayout gridBagLayout = new GridBagLayout();
|
||||||
|
GridBagConstraints constraints = new GridBagConstraints();
|
||||||
|
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
constraints.gridx = 0;
|
||||||
|
constraints.gridy = 0;
|
||||||
|
constraints.weighty = 0;
|
||||||
|
constraints.anchor = GridBagConstraints.LINE_START;
|
||||||
|
Dimension spacerBlockDimension = new Dimension(6, 4); // Space between left edge and button, Space between rows
|
||||||
|
for (String dspType : dspList) {
|
||||||
|
constraints.weightx = 1;
|
||||||
|
//Add a spacer
|
||||||
|
Filler spacer = new Filler(spacerBlockDimension, spacerBlockDimension, spacerBlockDimension);
|
||||||
|
gridBagLayout.setConstraints(spacer, constraints);
|
||||||
|
jPanel1.add(spacer);
|
||||||
|
constraints.gridx++;
|
||||||
|
constraints.gridy++;
|
||||||
|
//Add the button
|
||||||
|
JToggleButton dspButton = createDspButton(dspType);
|
||||||
|
dspButton.addActionListener(cbActionListener);
|
||||||
|
jPanel1.add(dspButton);
|
||||||
|
buttonGroup1.add(dspButton);
|
||||||
|
gridBagLayout.setConstraints(dspButton, constraints);
|
||||||
|
constraints.gridx++;
|
||||||
|
//Add the text area serving as a label to the right of the button
|
||||||
|
JTextArea myLabel = new JTextArea(dspType);
|
||||||
|
myLabel.setBackground(new Color(240, 240, 240));//matches background of panel
|
||||||
|
myLabel.setEditable(false);
|
||||||
|
myLabel.setWrapStyleWord(true);
|
||||||
|
myLabel.setLineWrap(true);
|
||||||
|
jPanel1.add(myLabel);
|
||||||
|
gridBagLayout.setConstraints(myLabel, constraints);
|
||||||
|
constraints.weightx = 0;
|
||||||
|
constraints.gridy++;
|
||||||
|
constraints.gridx = 0;
|
||||||
|
}
|
||||||
|
Component vertGlue = javax.swing.Box.createVerticalGlue();
|
||||||
|
jPanel1.add(vertGlue);
|
||||||
|
constraints.gridy++;
|
||||||
|
constraints.gridx = 0;
|
||||||
|
constraints.weighty = 1;
|
||||||
|
gridBagLayout.setConstraints(vertGlue, constraints);
|
||||||
|
jPanel1.setLayout(gridBagLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a list of the DataSourceProcessors which should exist as options on this panel.
|
||||||
|
* The default Autopsy DataSourceProcessors will appear
|
||||||
|
* at the beggining of the list in the same order.
|
||||||
|
*
|
||||||
|
* @return dspList a list of DataSourceProcessors which can be chose in this panel
|
||||||
|
*/
|
||||||
|
private List<String> getListOfDsps() {
|
||||||
|
List<String> dspList = new ArrayList<>();
|
||||||
|
final Map<String, DataSourceProcessor> datasourceProcessorsMap = new HashMap<>();
|
||||||
|
for (DataSourceProcessor dsProcessor : Lookup.getDefault().lookupAll(DataSourceProcessor.class)) {
|
||||||
|
if (!datasourceProcessorsMap.containsKey(dsProcessor.getDataSourceType())) {
|
||||||
|
datasourceProcessorsMap.put(dsProcessor.getDataSourceType(), dsProcessor);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, "discoverDataSourceProcessors(): A DataSourceProcessor already exists for type = {0}", dsProcessor.getDataSourceType()); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dspList.add(ImageDSProcessor.getType());
|
||||||
|
if (Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
|
||||||
|
dspList.add(LocalDiskDSProcessor.getType());
|
||||||
|
} else {
|
||||||
|
// remove LocalDiskDSProcessor from list of DSPs
|
||||||
|
datasourceProcessorsMap.remove(LocalDiskDSProcessor.getType());
|
||||||
|
}
|
||||||
|
dspList.add(LocalFilesDSProcessor.getType());
|
||||||
|
dspList.add(RawDSProcessor.getType());
|
||||||
|
// now add any addtional DSPs that haven't already been added
|
||||||
|
for (String dspType : datasourceProcessorsMap.keySet()) {
|
||||||
|
if (!dspList.contains(dspType)) {
|
||||||
|
dspList.add(dspType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dspList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single button for a DataSourceProcessor
|
||||||
|
*
|
||||||
|
* @param dspType - the name of the DataSourceProcessor
|
||||||
|
*
|
||||||
|
* @return dspButton a JToggleButton for the specified dspType
|
||||||
|
*/
|
||||||
|
private JToggleButton createDspButton(String dspType) {
|
||||||
|
JToggleButton dspButton = new JToggleButton();
|
||||||
|
dspButton.setMaximumSize(new java.awt.Dimension(48, 48));
|
||||||
|
dspButton.setMinimumSize(new java.awt.Dimension(48, 48));
|
||||||
|
dspButton.setPreferredSize(new java.awt.Dimension(48, 48));
|
||||||
|
dspButton.setName(dspType);
|
||||||
|
dspButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/fileextmismatch/options-icon.png")));
|
||||||
|
dspButton.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/corecomponents/checkbox32.png")));
|
||||||
|
dspButton.setFocusable(false);
|
||||||
|
if (dspType.equals(selectedDsp)) {
|
||||||
|
dspButton.setSelected(true);
|
||||||
|
} else {
|
||||||
|
dspButton.setSelected(false);
|
||||||
|
}
|
||||||
|
return dspButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
buttonGroup1 = new javax.swing.ButtonGroup();
|
||||||
|
jScrollPane1 = new javax.swing.JScrollPane();
|
||||||
|
jPanel1 = new javax.swing.JPanel();
|
||||||
|
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(6, 8), new java.awt.Dimension(6, 8), new java.awt.Dimension(6, 8));
|
||||||
|
|
||||||
|
jPanel1.setLayout(new java.awt.GridBagLayout());
|
||||||
|
jPanel1.add(filler1, new java.awt.GridBagConstraints());
|
||||||
|
|
||||||
|
jScrollPane1.setViewportView(jPanel1);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 588, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 588, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 328, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 328, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.ButtonGroup buttonGroup1;
|
||||||
|
private javax.swing.Box.Filler filler1;
|
||||||
|
private javax.swing.JPanel jPanel1;
|
||||||
|
private javax.swing.JScrollPane jScrollPane1;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -55,8 +55,6 @@ LocalFilesPanel.localFileChooser.approveButtonText=Select
|
|||||||
LocalFilesPanel.localFileChooser.approveButtonToolTipText=
|
LocalFilesPanel.localFileChooser.approveButtonToolTipText=
|
||||||
LocalFilesPanel.selectButton.actionCommand=Add
|
LocalFilesPanel.selectButton.actionCommand=Add
|
||||||
AddImageWizardAddingProgressVisual.statusLabel.text=Data source has been added to the local database. Files are being analyzed.
|
AddImageWizardAddingProgressVisual.statusLabel.text=Data source has been added to the local database. Files are being analyzed.
|
||||||
AddImageWizardChooseDataSourceVisual.typeTabel.text=Select data source type:
|
|
||||||
AddImageWizardChooseDataSourceVisual.jLabel2.text=jLabel2
|
|
||||||
AddImageWizardAddingProgressVisual.progressLabel.text=<progress>
|
AddImageWizardAddingProgressVisual.progressLabel.text=<progress>
|
||||||
AddImageWizardAddingProgressVisual.viewLogButton.text=View Log
|
AddImageWizardAddingProgressVisual.viewLogButton.text=View Log
|
||||||
AddImageWizardAddingProgressVisual.subTitle1Label.text=Processing data source and adding it to a local database. File analysis will start when this finishes.
|
AddImageWizardAddingProgressVisual.subTitle1Label.text=Processing data source and adding it to a local database. File analysis will start when this finishes.
|
||||||
|
@ -42,8 +42,6 @@ LocalFilesPanel.clearButton.toolTipText=\u73fe\u5728\u9078\u629e\u3055\u308c\u30
|
|||||||
LocalFilesPanel.localFileChooser.approveButtonText=\u9078\u629e
|
LocalFilesPanel.localFileChooser.approveButtonText=\u9078\u629e
|
||||||
LocalFilesPanel.selectButton.actionCommand=\u8ffd\u52a0
|
LocalFilesPanel.selectButton.actionCommand=\u8ffd\u52a0
|
||||||
AddImageWizardAddingProgressVisual.statusLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d\u3067\u3059\u3002
|
AddImageWizardAddingProgressVisual.statusLabel.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d\u3067\u3059\u3002
|
||||||
AddImageWizardChooseDataSourceVisual.typeTabel.text=\u8ffd\u52a0\u3059\u308b\u30bd\u30fc\u30b9\u30bf\u30a4\u30d7\u3092\u9078\u629e\uff1a
|
|
||||||
AddImageWizardChooseDataSourceVisual.jLabel2.text=jLabel2
|
|
||||||
AddImageWizardAddingProgressVisual.progressLabel.text=\uff1c\u30d7\u30ed\u30b0\u30ec\u30b9\uff1e
|
AddImageWizardAddingProgressVisual.progressLabel.text=\uff1c\u30d7\u30ed\u30b0\u30ec\u30b9\uff1e
|
||||||
AddImageWizardAddingProgressVisual.viewLogButton.text=\u30ed\u30b0\u3092\u8868\u793a
|
AddImageWizardAddingProgressVisual.viewLogButton.text=\u30ed\u30b0\u3092\u8868\u793a
|
||||||
AddImageWizardAddingProgressVisual.subTitle1Label.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u60c5\u5831\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\u3002\u3053\u3061\u3089\u304c\u5b8c\u4e86\u6b21\u7b2c\u3001\u30d5\u30a1\u30a4\u30eb\u89e3\u6790\u304c\u59cb\u307e\u308a\u307e\u3059\u3002
|
AddImageWizardAddingProgressVisual.subTitle1Label.text=\u30ed\u30fc\u30ab\u30eb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u60c5\u5831\u3092\u8ffd\u52a0\u4e2d\u3067\u3059\u3002\u3053\u3061\u3089\u304c\u5b8c\u4e86\u6b21\u7b2c\u3001\u30d5\u30a1\u30a4\u30eb\u89e3\u6790\u304c\u59cb\u307e\u308a\u307e\u3059\u3002
|
||||||
|
@ -72,9 +72,9 @@ import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
|||||||
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.services.Services;
|
import org.sleuthkit.autopsy.casemodule.services.Services;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||||
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
||||||
@ -673,7 +673,7 @@ public class Case {
|
|||||||
* cannot be deleted if another node has it open.
|
* cannot be deleted if another node has it open.
|
||||||
*/
|
*/
|
||||||
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
|
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
|
||||||
try (CoordinationService.Lock dirLock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, metadata.getCaseDirectory())) {
|
try (CoordinationService.Lock dirLock = CoordinationService.getInstance().tryGetExclusiveLock(CategoryNode.CASES, metadata.getCaseDirectory())) {
|
||||||
assert (null != dirLock);
|
assert (null != dirLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -945,7 +945,7 @@ public class Case {
|
|||||||
@Messages({"Case.creationException.couldNotAcquireNameLock=Failed to get lock on case name"})
|
@Messages({"Case.creationException.couldNotAcquireNameLock=Failed to get lock on case name"})
|
||||||
private static CoordinationService.Lock acquireExclusiveCaseNameLock(String caseName) throws CaseActionException {
|
private static CoordinationService.Lock acquireExclusiveCaseNameLock(String caseName) throws CaseActionException {
|
||||||
try {
|
try {
|
||||||
Lock lock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, caseName, NAME_LOCK_TIMOUT_HOURS, TimeUnit.HOURS);
|
Lock lock = CoordinationService.getInstance().tryGetExclusiveLock(CategoryNode.CASES, caseName, NAME_LOCK_TIMOUT_HOURS, TimeUnit.HOURS);
|
||||||
if (null == lock) {
|
if (null == lock) {
|
||||||
throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireNameLock());
|
throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireNameLock());
|
||||||
}
|
}
|
||||||
@ -971,7 +971,7 @@ public class Case {
|
|||||||
private static CoordinationService.Lock acquireExclusiveCaseResourcesLock(String caseName) throws CaseActionException {
|
private static CoordinationService.Lock acquireExclusiveCaseResourcesLock(String caseName) throws CaseActionException {
|
||||||
try {
|
try {
|
||||||
String resourcesNodeName = caseName + "_resources";
|
String resourcesNodeName = caseName + "_resources";
|
||||||
Lock lock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, resourcesNodeName, RESOURCE_LOCK_TIMOUT_HOURS, TimeUnit.HOURS);
|
Lock lock = CoordinationService.getInstance().tryGetExclusiveLock(CategoryNode.CASES, resourcesNodeName, RESOURCE_LOCK_TIMOUT_HOURS, TimeUnit.HOURS);
|
||||||
if (null == lock) {
|
if (null == lock) {
|
||||||
throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
|
throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
|
||||||
}
|
}
|
||||||
@ -2337,7 +2337,7 @@ public class Case {
|
|||||||
@Messages({"Case.creationException.couldNotAcquireDirLock=Failed to get lock on case directory."})
|
@Messages({"Case.creationException.couldNotAcquireDirLock=Failed to get lock on case directory."})
|
||||||
private void acquireSharedCaseDirLock(String caseDir) throws CaseActionException {
|
private void acquireSharedCaseDirLock(String caseDir) throws CaseActionException {
|
||||||
try {
|
try {
|
||||||
caseDirLock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetSharedLock(CoordinationService.CategoryNode.CASES, caseDir, SHARED_DIR_LOCK_TIMOUT_HOURS, TimeUnit.HOURS);
|
caseDirLock = CoordinationService.getInstance().tryGetSharedLock(CategoryNode.CASES, caseDir, SHARED_DIR_LOCK_TIMOUT_HOURS, TimeUnit.HOURS);
|
||||||
if (null == caseDirLock) {
|
if (null == caseDirLock) {
|
||||||
throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireDirLock());
|
throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireDirLock());
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,13 @@
|
|||||||
package org.sleuthkit.autopsy.coordinationservice;
|
package org.sleuthkit.autopsy.coordinationservice;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import org.apache.curator.RetryPolicy;
|
import org.apache.curator.RetryPolicy;
|
||||||
import org.apache.curator.framework.CuratorFramework;
|
import org.apache.curator.framework.CuratorFramework;
|
||||||
import org.apache.curator.framework.CuratorFrameworkFactory;
|
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||||
@ -34,25 +38,28 @@ import org.apache.zookeeper.KeeperException.NoNodeException;
|
|||||||
import org.apache.zookeeper.WatchedEvent;
|
import org.apache.zookeeper.WatchedEvent;
|
||||||
import org.apache.zookeeper.ZooDefs;
|
import org.apache.zookeeper.ZooDefs;
|
||||||
import org.apache.zookeeper.ZooKeeper;
|
import org.apache.zookeeper.ZooKeeper;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A coordination service for maintaining configuration information and
|
* A coordination service for maintaining configuration information and
|
||||||
* providing distributed synchronization using a shared hierarchical namespace
|
* providing distributed synchronization using a shared hierarchical namespace
|
||||||
* of nodes.
|
* of nodes.
|
||||||
*
|
|
||||||
* TODO (JIRA 2205): Simple refactoring for general use.
|
|
||||||
*/
|
*/
|
||||||
|
@ThreadSafe
|
||||||
public final class CoordinationService {
|
public final class CoordinationService {
|
||||||
|
|
||||||
private static CuratorFramework curator = null;
|
|
||||||
private static final Map<String, CoordinationService> rootNodesToServices = new HashMap<>();
|
|
||||||
private static final int SESSION_TIMEOUT_MILLISECONDS = 300000;
|
private static final int SESSION_TIMEOUT_MILLISECONDS = 300000;
|
||||||
private static final int CONNECTION_TIMEOUT_MILLISECONDS = 300000;
|
private static final int CONNECTION_TIMEOUT_MILLISECONDS = 300000;
|
||||||
private static final int ZOOKEEPER_SESSION_TIMEOUT_MILLIS = 3000;
|
private static final int ZOOKEEPER_SESSION_TIMEOUT_MILLIS = 3000;
|
||||||
private static final int ZOOKEEPER_CONNECTION_TIMEOUT_MILLIS = 15000;
|
private static final int ZOOKEEPER_CONNECTION_TIMEOUT_MILLIS = 15000;
|
||||||
private static final int PORT_OFFSET = 1000; // When run in Solr, ZooKeeper defaults to Solr port + 1000
|
private static final int PORT_OFFSET = 1000; // When run in Solr, ZooKeeper defaults to Solr port + 1000
|
||||||
private final Map<String, String> categoryNodeToPath = new HashMap<>();
|
private static final String DEFAULT_NAMESPACE_ROOT = "autopsy";
|
||||||
|
@GuardedBy("CoordinationService.class")
|
||||||
|
private static CoordinationService instance;
|
||||||
|
private final CuratorFramework curator;
|
||||||
|
@GuardedBy("categoryNodeToPath")
|
||||||
|
private final Map<String, String> categoryNodeToPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if ZooKeeper is accessible with the current settings. Closes
|
* Determines if ZooKeeper is accessible with the current settings. Closes
|
||||||
@ -86,44 +93,31 @@ public final class CoordinationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a coordination service for a specific namespace.
|
* Gets the coordination service for maintaining configuration information
|
||||||
|
* and providing distributed synchronization using a shared hierarchical
|
||||||
|
* namespace of nodes.
|
||||||
*
|
*
|
||||||
* @param rootNode The name of the root node that defines the namespace.
|
* @return The corrdination service.
|
||||||
*
|
*
|
||||||
* @return The coordination service.
|
* @throws CoordinationServiceException
|
||||||
*
|
|
||||||
* @throws CoordinationServiceException If an instance of the coordination
|
|
||||||
* service cannot be created.
|
|
||||||
*/
|
*/
|
||||||
public static synchronized CoordinationService getServiceForNamespace(String rootNode) throws CoordinationServiceException {
|
public synchronized static CoordinationService getInstance() throws CoordinationServiceException {
|
||||||
/*
|
if (null == instance) {
|
||||||
* Connect to ZooKeeper via Curator.
|
String rootNode;
|
||||||
*/
|
Collection<? extends CoordinationServiceNamespace> providers = Lookup.getDefault().lookupAll(CoordinationServiceNamespace.class);
|
||||||
if (null == curator) {
|
Iterator<? extends CoordinationServiceNamespace> it = providers.iterator();
|
||||||
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
|
if (it.hasNext()) {
|
||||||
int zooKeeperServerPort = Integer.valueOf(UserPreferences.getIndexingServerPort()) + PORT_OFFSET;
|
rootNode = it.next().getNamespaceRoot();
|
||||||
String connectString = UserPreferences.getIndexingServerHost() + ":" + zooKeeperServerPort;
|
} else {
|
||||||
curator = CuratorFrameworkFactory.newClient(connectString, SESSION_TIMEOUT_MILLISECONDS, CONNECTION_TIMEOUT_MILLISECONDS, retryPolicy);
|
rootNode = DEFAULT_NAMESPACE_ROOT;
|
||||||
curator.start();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get or create a coordination service for the namespace defined by the
|
|
||||||
* specified root node.
|
|
||||||
*/
|
|
||||||
if (rootNodesToServices.containsKey(rootNode)) {
|
|
||||||
return rootNodesToServices.get(rootNode);
|
|
||||||
} else {
|
|
||||||
CoordinationService service;
|
|
||||||
try {
|
try {
|
||||||
service = new CoordinationService(rootNode);
|
instance = new CoordinationService(rootNode);
|
||||||
} catch (IOException | InterruptedException | KeeperException | CoordinationServiceException ex) {
|
} catch (IOException | InterruptedException | KeeperException | CoordinationServiceException ex) {
|
||||||
curator = null;
|
|
||||||
throw new CoordinationServiceException("Failed to create coordination service", ex);
|
throw new CoordinationServiceException("Failed to create coordination service", ex);
|
||||||
}
|
}
|
||||||
rootNodesToServices.put(rootNode, service);
|
|
||||||
return service;
|
|
||||||
}
|
}
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,11 +135,23 @@ public final class CoordinationService {
|
|||||||
throw new CoordinationServiceException("Unable to access ZooKeeper");
|
throw new CoordinationServiceException("Unable to access ZooKeeper");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect to ZooKeeper via Curator.
|
||||||
|
*/
|
||||||
|
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
|
||||||
|
int zooKeeperServerPort = Integer.valueOf(UserPreferences.getIndexingServerPort()) + PORT_OFFSET;
|
||||||
|
String connectString = UserPreferences.getIndexingServerHost() + ":" + zooKeeperServerPort;
|
||||||
|
curator = CuratorFrameworkFactory.newClient(connectString, SESSION_TIMEOUT_MILLISECONDS, CONNECTION_TIMEOUT_MILLISECONDS, retryPolicy);
|
||||||
|
curator.start();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the top-level root and category nodes.
|
||||||
|
*/
|
||||||
String rootNode = rootNodeName;
|
String rootNode = rootNodeName;
|
||||||
if (!rootNode.startsWith("/")) {
|
if (!rootNode.startsWith("/")) {
|
||||||
rootNode = "/" + rootNode;
|
rootNode = "/" + rootNode;
|
||||||
}
|
}
|
||||||
|
categoryNodeToPath = new ConcurrentHashMap<>();
|
||||||
for (CategoryNode node : CategoryNode.values()) {
|
for (CategoryNode node : CategoryNode.values()) {
|
||||||
String nodePath = rootNode + "/" + node.getDisplayName();
|
String nodePath = rootNode + "/" + node.getDisplayName();
|
||||||
try {
|
try {
|
||||||
@ -422,8 +428,7 @@ public final class CoordinationService {
|
|||||||
|
|
||||||
CASES("cases"),
|
CASES("cases"),
|
||||||
MANIFESTS("manifests"),
|
MANIFESTS("manifests"),
|
||||||
CONFIG("config"),
|
CONFIG("config");
|
||||||
RESOURCE("resource");
|
|
||||||
|
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2016-2017 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");
|
||||||
@ -19,15 +19,18 @@
|
|||||||
package org.sleuthkit.autopsy.coordinationservice;
|
package org.sleuthkit.autopsy.coordinationservice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root node for Autopsy coordination service namespace.
|
* An interface that allows the root node of the coordination service namespace
|
||||||
|
* for the application to be specified at runtime. An application built on the
|
||||||
|
* Autopsy platform should provide at most one implementation of this interface
|
||||||
|
* (additional implementations are ignored).
|
||||||
*/
|
*/
|
||||||
public final class CoordinationServiceNamespace {
|
public interface CoordinationServiceNamespace {
|
||||||
private static final String ROOT = "autopsy";
|
|
||||||
|
|
||||||
public static String getRoot() {
|
/**
|
||||||
return ROOT;
|
* Gets the name of the root node of the coordination service namespace.
|
||||||
}
|
*
|
||||||
|
* @return The name of the root node.
|
||||||
|
*/
|
||||||
|
public String getNamespaceRoot();
|
||||||
|
|
||||||
private CoordinationServiceNamespace() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,9 @@ abstract class AbstractContentChildren<T> extends Keys<T> {
|
|||||||
* Uses lazy Content.Keys
|
* Uses lazy Content.Keys
|
||||||
*/
|
*/
|
||||||
AbstractContentChildren() {
|
AbstractContentChildren() {
|
||||||
super(true); // use lazy behavior
|
/*This was turned off because we were getting out of memory errors when the
|
||||||
|
filter nodes were hiding nodes. Turning this off seemed to help */
|
||||||
|
super(false); //don't use lazy behavior
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,7 +61,7 @@ public class ArtifactStringContent implements StringContent {
|
|||||||
* @return The HTML representation of the artifact as a string.
|
* @return The HTML representation of the artifact as a string.
|
||||||
*/
|
*/
|
||||||
@Messages({
|
@Messages({
|
||||||
"ArtifactStringContent.attrsTableHeader.attribute=Attribute",
|
"ArtifactStringContent.attrsTableHeader.type=Type",
|
||||||
"ArtifactStringContent.attrsTableHeader.value=Value",
|
"ArtifactStringContent.attrsTableHeader.value=Value",
|
||||||
"ArtifactStringContent.attrsTableHeader.sources=Source(s)",
|
"ArtifactStringContent.attrsTableHeader.sources=Source(s)",
|
||||||
"ArtifactStringContent.failedToGetSourcePath.message=Failed to get source file path from case database",
|
"ArtifactStringContent.failedToGetSourcePath.message=Failed to get source file path from case database",
|
||||||
@ -90,15 +90,15 @@ public class ArtifactStringContent implements StringContent {
|
|||||||
*/
|
*/
|
||||||
buffer.append("<table border='1'>"); //NON-NLS
|
buffer.append("<table border='1'>"); //NON-NLS
|
||||||
buffer.append("<tr>"); //NON-NLS
|
buffer.append("<tr>"); //NON-NLS
|
||||||
buffer.append("<td>"); //NON-NLS
|
buffer.append("<td><b>"); //NON-NLS
|
||||||
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_attribute());
|
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_type());
|
||||||
buffer.append("</td>"); //NON-NLS
|
buffer.append("</b></td>"); //NON-NLS
|
||||||
buffer.append("<td>"); //NON-NLS
|
buffer.append("<td><b>"); //NON-NLS
|
||||||
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_value());
|
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_value());
|
||||||
buffer.append("</td>"); //NON-NLS
|
buffer.append("</b></td>"); //NON-NLS
|
||||||
buffer.append("<td>"); //NON-NLS
|
buffer.append("<td><b>"); //NON-NLS
|
||||||
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_sources());
|
buffer.append(Bundle.ArtifactStringContent_attrsTableHeader_sources());
|
||||||
buffer.append("</td>"); //NON-NLS
|
buffer.append("</b></td>"); //NON-NLS
|
||||||
buffer.append("</tr>\n"); //NON-NLS
|
buffer.append("</tr>\n"); //NON-NLS
|
||||||
try {
|
try {
|
||||||
Content content = artifact.getSleuthkitCase().getContentById(artifact.getObjectID());
|
Content content = artifact.getSleuthkitCase().getContentById(artifact.getObjectID());
|
||||||
|
@ -25,6 +25,7 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -413,19 +414,34 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
|||||||
FilesSetDefsPanel fileIngestFilterPanel;
|
FilesSetDefsPanel fileIngestFilterPanel;
|
||||||
fileIngestFilterPanel = new FilesSetDefsPanel(FilesSetDefsPanel.PANEL_TYPE.FILE_INGEST_FILTERS);
|
fileIngestFilterPanel = new FilesSetDefsPanel(FilesSetDefsPanel.PANEL_TYPE.FILE_INGEST_FILTERS);
|
||||||
fileIngestFilterPanel.load();
|
fileIngestFilterPanel.load();
|
||||||
|
//save the filters that exist before any are created
|
||||||
|
final ArrayList<String> oldFilterList = new ArrayList<>(Arrays.asList(getComboBoxContents()));
|
||||||
dialog.addApplyButtonListener(
|
dialog.addApplyButtonListener(
|
||||||
(ActionEvent e) -> {
|
(ActionEvent e) -> {
|
||||||
fileIngestFilterPanel.store();
|
fileIngestFilterPanel.store();
|
||||||
|
ArrayList<FilesSet> newFilterList = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
newFilterList.addAll(FilesSetsManager.getInstance().getCustomFileIngestFilters().values());
|
||||||
|
} catch (FilesSetsManager.FilesSetsManagerException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to get user created file ingest filters, only default available for selection", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
for (FilesSet filter : newFilterList) { //getting one of the recently created filters
|
||||||
|
if (!oldFilterList.contains(filter.getName())) {
|
||||||
|
//set newly created filter to selected filter
|
||||||
|
settings.setFileIngestFilter(filter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
fileIngestFilterComboBox.setModel(new DefaultComboBoxModel<>(getComboBoxContents()));
|
fileIngestFilterComboBox.setModel(new DefaultComboBoxModel<>(getComboBoxContents()));
|
||||||
|
//set the selected filter after the comboBox Contents were updated to include it
|
||||||
|
fileIngestFilterComboBox.setSelectedItem(settings.getFileIngestFilter().getName());
|
||||||
dialog.close();
|
dialog.close();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
dialog.display(fileIngestFilterPanel);
|
dialog.display(fileIngestFilterPanel);
|
||||||
|
//return to saved selection in case they cancel out of filter creation
|
||||||
fileIngestFilterComboBox.setSelectedItem(settings.getFileIngestFilter().getName());
|
fileIngestFilterComboBox.setSelectedItem(settings.getFileIngestFilter().getName());
|
||||||
|
|
||||||
} else if (evt.getActionCommand().equals("comboBoxChanged")) {
|
} else if (evt.getActionCommand().equals("comboBoxChanged")) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance()
|
Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance()
|
||||||
.getCustomFileIngestFilters();
|
.getCustomFileIngestFilters();
|
||||||
|
@ -47,6 +47,7 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
private final static int INDEX_OF_SETTINGS_PANEL = 2;
|
private final static int INDEX_OF_SETTINGS_PANEL = 2;
|
||||||
private ProfileSettingsPanel profilePanel;
|
private ProfileSettingsPanel profilePanel;
|
||||||
private final static int INDEX_OF_PROFILE_PANEL = 1;
|
private final static int INDEX_OF_PROFILE_PANEL = 1;
|
||||||
|
private int indexOfPreviousTab;
|
||||||
/**
|
/**
|
||||||
* This panel implements a property change listener that listens to ingest
|
* This panel implements a property change listener that listens to ingest
|
||||||
* job events so it can disable the buttons on the panel if ingest is
|
* job events so it can disable the buttons on the panel if ingest is
|
||||||
@ -58,6 +59,7 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
public IngestOptionsPanel() {
|
public IngestOptionsPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
customizeComponents();
|
customizeComponents();
|
||||||
|
indexOfPreviousTab = tabbedPane.getSelectedIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void customizeComponents() {
|
private void customizeComponents() {
|
||||||
@ -78,15 +80,16 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
@Override
|
@Override
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
if (e.getSource() instanceof JTabbedPane) {
|
if (e.getSource() instanceof JTabbedPane) {
|
||||||
//because we can have two filterPanels open at the same time
|
//If we are switching to a filter panel we should load
|
||||||
//we need to save the settings when we change tabs otherwise
|
//load the filter panel to ensure it is up to date
|
||||||
//they could be overwritten with out of date
|
//incase a filter was addded through the Profile->new->create new filter manner
|
||||||
if (tabbedPane.getSelectedIndex() == INDEX_OF_FILTER_PANEL) {
|
if (tabbedPane.getSelectedIndex() == INDEX_OF_FILTER_PANEL && tabbedPane.getSelectedIndex() != indexOfPreviousTab) {
|
||||||
filterPanel.load();
|
filterPanel.load();
|
||||||
}
|
}
|
||||||
else {
|
//save the contents of whichever Tab we just switched from
|
||||||
filterPanel.saveSettings();
|
saveTabByIndex(indexOfPreviousTab);
|
||||||
}
|
//save the index of the current tab for the next time we switch
|
||||||
|
indexOfPreviousTab = tabbedPane.getSelectedIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -160,8 +163,30 @@ public class IngestOptionsPanel extends IngestModuleGlobalSettingsPanel implemen
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void saveSettings() {
|
public void saveSettings() {
|
||||||
filterPanel.store();
|
saveTabByIndex(tabbedPane.getSelectedIndex());
|
||||||
settingsPanel.store();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the panel which is in the tab corresponding to the specified index.
|
||||||
|
*
|
||||||
|
* @param index - the index of the tab you wish to save the contents of
|
||||||
|
*/
|
||||||
|
private void saveTabByIndex(int index) {
|
||||||
|
//Because we can create filters in two seperate windows here we need
|
||||||
|
//to be careful not to save an out of date list over the current list
|
||||||
|
switch (index) {
|
||||||
|
case (INDEX_OF_FILTER_PANEL):
|
||||||
|
filterPanel.saveSettings();
|
||||||
|
break;
|
||||||
|
case (INDEX_OF_PROFILE_PANEL):
|
||||||
|
profilePanel.saveSettings();
|
||||||
|
break;
|
||||||
|
case (INDEX_OF_SETTINGS_PANEL):
|
||||||
|
settingsPanel.saveSettings();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//don't save anything if it wasn't a tab index that should exist
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,22 +27,28 @@
|
|||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<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">
|
||||||
<EmptySpace min="-2" 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="profileListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Group type="102" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="profileListPane" alignment="1" min="-2" pref="339" max="-2" attributes="0"/>
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Component id="newProfileButton" linkSize="5" min="-2" pref="107" max="-2" attributes="0"/>
|
||||||
<Component id="newProfileButton" linkSize="5" min="-2" pref="107" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<Component id="editProfileButton" linkSize="5" min="-2" pref="107" max="-2" attributes="0"/>
|
||||||
<Component id="editProfileButton" linkSize="5" min="-2" pref="107" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<Component id="deleteProfileButton" linkSize="5" min="-2" pref="109" max="-2" attributes="0"/>
|
||||||
<Component id="deleteProfileButton" linkSize="5" min="-2" pref="109" max="-2" attributes="0"/>
|
</Group>
|
||||||
|
<Component id="jScrollPane2" linkSize="6" alignment="1" min="-2" pref="346" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
<Component id="profileListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<Component id="profileListPane" linkSize="6" min="-2" pref="346" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="jSeparator2" min="-2" pref="2" max="-2" attributes="0"/>
|
<Component id="jSeparator2" min="-2" pref="2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
@ -60,7 +66,7 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="69" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="profileDescPane" alignment="1" max="32767" attributes="0"/>
|
<Component id="profileDescPane" alignment="1" max="32767" attributes="0"/>
|
||||||
<Component id="selectedModulesPane" alignment="1" max="32767" attributes="0"/>
|
<Component id="selectedModulesPane" alignment="1" max="32767" attributes="0"/>
|
||||||
@ -97,13 +103,10 @@
|
|||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="profileListLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="profileDescLabel" alignment="3" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="profileDescLabel" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="profileDescPane" min="-2" max="-2" attributes="0"/>
|
<Component id="profileDescPane" min="-2" max="-2" 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">
|
||||||
@ -115,9 +118,16 @@
|
|||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="selectedModulesLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="selectedModulesLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="selectedModulesPane" max="32767" attributes="0"/>
|
<Component id="selectedModulesPane" pref="171" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="jScrollPane2" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="profileListLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="profileListPane" pref="346" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace min="9" pref="9" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="profileListPane" pref="415" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
@ -128,7 +138,7 @@
|
|||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="jSeparator2" alignment="1" max="32767" attributes="0"/>
|
<Component id="jSeparator2" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -355,5 +365,41 @@
|
|||||||
<Property name="orientation" type="int" value="1"/>
|
<Property name="orientation" type="int" value="1"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||||
|
<Properties>
|
||||||
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||||
|
<FontInfo relative="true">
|
||||||
|
<Font bold="false" component="jScrollPane2" property="font" relativeSize="false" size="11"/>
|
||||||
|
</FontInfo>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTextArea" name="infoTextArea">
|
||||||
|
<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.modules.form.editors2.FontEditor">
|
||||||
|
<FontInfo relative="true">
|
||||||
|
<Font bold="false" component="infoTextArea" property="font" relativeSize="false" size="11"/>
|
||||||
|
</FontInfo>
|
||||||
|
</Property>
|
||||||
|
<Property name="lineWrap" type="boolean" value="true"/>
|
||||||
|
<Property name="rows" type="int" value="3"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="ProfileSettingsPanel.infoTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -27,7 +27,6 @@ import javax.swing.event.ListSelectionEvent;
|
|||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import org.netbeans.spi.options.OptionsPanelController;
|
import org.netbeans.spi.options.OptionsPanelController;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.windows.WindowManager;
|
|
||||||
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestProfiles.IngestProfile;
|
import org.sleuthkit.autopsy.ingest.IngestProfiles.IngestProfile;
|
||||||
@ -46,12 +45,15 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
"ProfileSettingsPanel.deleteProfileButton.text=Delete Profile",
|
"ProfileSettingsPanel.deleteProfileButton.text=Delete Profile",
|
||||||
"ProfileSettingsPanel.messages.filterLoadFailed=Failed to load file ingest filter",
|
"ProfileSettingsPanel.messages.filterLoadFailed=Failed to load file ingest filter",
|
||||||
"# {0} - profile name",
|
"# {0} - profile name",
|
||||||
"ProfileSettingsPanel.doFileSetsDialog.duplicateProfile.text=Profile with name {0} already exists."
|
"ProfileSettingsPanel.doFileSetsDialog.duplicateProfile.text=Profile with name {0} already exists.",
|
||||||
|
"ProfileSettingsPanel.infoTextArea.text=An Ingest Profile runs a preconfigured set of ingest modules"
|
||||||
|
+ " on some or all of the files in a data source. Create a profile if you frequently run the same set of modules on a subset of the files."
|
||||||
})
|
})
|
||||||
|
|
||||||
private final DefaultListModel<IngestProfile> profilesListModel;
|
private final DefaultListModel<IngestProfile> profilesListModel;
|
||||||
private Map<String, IngestProfile> profiles;
|
private Map<String, IngestProfile> profiles;
|
||||||
private ProfilePanel panel;
|
private ProfilePanel panel;
|
||||||
|
private boolean canBeEnabled; //if something can be enabled ingest is not running
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form ProfileOptionsPanel
|
* Creates new form ProfileOptionsPanel
|
||||||
@ -62,8 +64,8 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
this.profileList.setModel(profilesListModel);
|
this.profileList.setModel(profilesListModel);
|
||||||
this.profileList.addListSelectionListener(new ProfileSettingsPanel.ProfileListSelectionListener());
|
this.profileList.addListSelectionListener(new ProfileSettingsPanel.ProfileListSelectionListener());
|
||||||
ingestWarningLabel.setVisible(false);
|
ingestWarningLabel.setVisible(false);
|
||||||
editProfileButton.setEnabled(false);
|
canBeEnabled = !IngestManager.getInstance().isIngestRunning();
|
||||||
deleteProfileButton.setEnabled(false);
|
refreshButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,6 +95,8 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
selectedModulesLabel = new javax.swing.JLabel();
|
selectedModulesLabel = new javax.swing.JLabel();
|
||||||
ingestWarningLabel = new javax.swing.JLabel();
|
ingestWarningLabel = new javax.swing.JLabel();
|
||||||
jSeparator2 = new javax.swing.JSeparator();
|
jSeparator2 = new javax.swing.JSeparator();
|
||||||
|
jScrollPane2 = new javax.swing.JScrollPane();
|
||||||
|
infoTextArea = new javax.swing.JTextArea();
|
||||||
|
|
||||||
setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||||
setPreferredSize(new java.awt.Dimension(800, 488));
|
setPreferredSize(new java.awt.Dimension(800, 488));
|
||||||
@ -177,6 +181,18 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
|
|
||||||
jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);
|
jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL);
|
||||||
|
|
||||||
|
jScrollPane2.setFont(jScrollPane2.getFont().deriveFont(jScrollPane2.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
|
|
||||||
|
infoTextArea.setEditable(false);
|
||||||
|
infoTextArea.setBackground(new java.awt.Color(240, 240, 240));
|
||||||
|
infoTextArea.setColumns(20);
|
||||||
|
infoTextArea.setFont(infoTextArea.getFont().deriveFont(infoTextArea.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
|
||||||
|
infoTextArea.setLineWrap(true);
|
||||||
|
infoTextArea.setRows(3);
|
||||||
|
infoTextArea.setText(org.openide.util.NbBundle.getMessage(ProfileSettingsPanel.class, "ProfileSettingsPanel.infoTextArea.text")); // NOI18N
|
||||||
|
infoTextArea.setWrapStyleWord(true);
|
||||||
|
jScrollPane2.setViewportView(infoTextArea);
|
||||||
|
|
||||||
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(
|
||||||
@ -184,17 +200,21 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(profileListLabel)
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(newProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(editProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(deleteProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 346, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addComponent(profileListLabel))
|
||||||
|
.addGap(6, 6, 6))
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addComponent(profileListPane, javax.swing.GroupLayout.PREFERRED_SIZE, 346, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(profileListPane, javax.swing.GroupLayout.PREFERRED_SIZE, 339, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
|
||||||
.addComponent(newProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(editProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(deleteProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
|
||||||
.addGap(6, 6, 6)))
|
|
||||||
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
@ -210,7 +230,7 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(ingestWarningLabel)
|
.addComponent(ingestWarningLabel)
|
||||||
.addGap(0, 0, Short.MAX_VALUE))
|
.addGap(0, 69, Short.MAX_VALUE))
|
||||||
.addComponent(profileDescPane, javax.swing.GroupLayout.Alignment.TRAILING)
|
.addComponent(profileDescPane, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(selectedModulesPane, javax.swing.GroupLayout.Alignment.TRAILING)))
|
.addComponent(selectedModulesPane, javax.swing.GroupLayout.Alignment.TRAILING)))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
@ -231,18 +251,18 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
|
|
||||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deleteProfileButton, editProfileButton, newProfileButton});
|
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {deleteProfileButton, editProfileButton, newProfileButton});
|
||||||
|
|
||||||
|
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jScrollPane2, profileListPane});
|
||||||
|
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(profileListLabel)
|
|
||||||
.addComponent(profileDescLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(profileDescLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(profileDescPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(profileDescPane, 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)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -253,8 +273,14 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(selectedModulesLabel)
|
.addComponent(selectedModulesLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(selectedModulesPane))
|
.addComponent(selectedModulesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 171, Short.MAX_VALUE))
|
||||||
.addComponent(profileListPane, javax.swing.GroupLayout.DEFAULT_SIZE, 415, Short.MAX_VALUE))
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(profileListLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(profileListPane, javax.swing.GroupLayout.DEFAULT_SIZE, 346, Short.MAX_VALUE)
|
||||||
|
.addGap(9, 9, 9)))
|
||||||
.addGap(4, 4, 4)
|
.addGap(4, 4, 4)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(newProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(newProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
@ -262,7 +288,7 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
.addComponent(deleteProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(deleteProfileButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addComponent(ingestWarningLabel))
|
.addComponent(ingestWarningLabel))
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
.addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.TRAILING)))
|
.addComponent(jSeparator2)))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@ -290,10 +316,9 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
* @param isEnabled
|
* @param isEnabled
|
||||||
*/
|
*/
|
||||||
void enableButtons(boolean isEnabled) {
|
void enableButtons(boolean isEnabled) {
|
||||||
newProfileButton.setEnabled(isEnabled);
|
canBeEnabled = isEnabled; //update value of canBeEnabled to be used by refresh
|
||||||
editProfileButton.setEnabled(isEnabled);
|
refreshButtons();
|
||||||
deleteProfileButton.setEnabled(isEnabled);
|
ingestWarningLabel.setVisible(!canBeEnabled);
|
||||||
ingestWarningLabel.setVisible(!isEnabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,23 +334,20 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
this.filterNameText.setText("");
|
this.filterNameText.setText("");
|
||||||
this.selectedModulesArea.setText("");
|
this.selectedModulesArea.setText("");
|
||||||
}
|
}
|
||||||
refreshEditDeleteButtons();
|
refreshButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When Ingest is not running this will changed enabled status of the edit
|
* When Ingest is not running this will change the enabled status of the
|
||||||
* and delete buttons to reflect their current availability.
|
* edit and delete buttons to reflect their current availability.
|
||||||
*/
|
*/
|
||||||
private void refreshEditDeleteButtons() {
|
private void refreshButtons() {
|
||||||
if (newProfileButton.isEnabled()) {
|
IngestProfile selectedProfile = ProfileSettingsPanel.this.profileList.getSelectedValue();
|
||||||
if (profilesListModel.isEmpty()) {
|
boolean profileIsSelected = (selectedProfile != null);
|
||||||
editProfileButton.setEnabled(false);
|
newProfileButton.setEnabled(canBeEnabled);
|
||||||
deleteProfileButton.setEnabled(false);
|
editProfileButton.setEnabled(canBeEnabled && profileIsSelected);
|
||||||
} else {
|
deleteProfileButton.setEnabled(canBeEnabled && profileIsSelected);
|
||||||
editProfileButton.setEnabled(true);
|
|
||||||
deleteProfileButton.setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -372,7 +394,6 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
panel.saveSettings();
|
panel.saveSettings();
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -398,7 +419,7 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
if (currentIndex < 0 || currentIndex >= profilesListModel.getSize()) {
|
if (currentIndex < 0 || currentIndex >= profilesListModel.getSize()) {
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
}
|
}
|
||||||
refreshEditDeleteButtons();
|
refreshButtons();
|
||||||
this.profileList.setSelectedIndex(currentIndex);
|
this.profileList.setSelectedIndex(currentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,11 +433,10 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
// Get the selected interesting files set and populate the set
|
// Get the selected interesting files set and populate the set
|
||||||
// components.
|
// components.
|
||||||
IngestProfile selectedProfile = ProfileSettingsPanel.this.profileList.getSelectedValue();
|
IngestProfile selectedProfile = ProfileSettingsPanel.this.profileList.getSelectedValue();
|
||||||
|
refreshButtons();
|
||||||
if (selectedProfile != null) {
|
if (selectedProfile != null) {
|
||||||
profileDescArea.setText(selectedProfile.getDescription());
|
profileDescArea.setText(selectedProfile.getDescription());
|
||||||
filterNameText.setText(selectedProfile.getFileIngestFilter());
|
filterNameText.setText(selectedProfile.getFileIngestFilter());
|
||||||
editProfileButton.setEnabled(true);
|
|
||||||
deleteProfileButton.setEnabled(true);
|
|
||||||
try {
|
try {
|
||||||
Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance().getCustomFileIngestFilters();
|
Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance().getCustomFileIngestFilters();
|
||||||
for (FilesSet fSet : FilesSetsManager.getStandardFileIngestFilters()) {
|
for (FilesSet fSet : FilesSetsManager.getStandardFileIngestFilters()) {
|
||||||
@ -430,10 +450,6 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
for (String moduleName : IngestJobSettings.getEnabledModules(selectedProfile.getName())) {
|
for (String moduleName : IngestJobSettings.getEnabledModules(selectedProfile.getName())) {
|
||||||
selectedModulesArea.append(moduleName + "\n");
|
selectedModulesArea.append(moduleName + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
editProfileButton.setEnabled(false);
|
|
||||||
deleteProfileButton.setEnabled(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,7 +461,9 @@ class ProfileSettingsPanel extends IngestModuleGlobalSettingsPanel implements Op
|
|||||||
private javax.swing.JScrollPane filterDescPane;
|
private javax.swing.JScrollPane filterDescPane;
|
||||||
private javax.swing.JLabel filterNameLabel;
|
private javax.swing.JLabel filterNameLabel;
|
||||||
private javax.swing.JLabel filterNameText;
|
private javax.swing.JLabel filterNameText;
|
||||||
|
private javax.swing.JTextArea infoTextArea;
|
||||||
private javax.swing.JLabel ingestWarningLabel;
|
private javax.swing.JLabel ingestWarningLabel;
|
||||||
|
private javax.swing.JScrollPane jScrollPane2;
|
||||||
private javax.swing.JSeparator jSeparator2;
|
private javax.swing.JSeparator jSeparator2;
|
||||||
private javax.swing.JButton newProfileButton;
|
private javax.swing.JButton newProfileButton;
|
||||||
private javax.swing.JTextArea profileDescArea;
|
private javax.swing.JTextArea profileDescArea;
|
||||||
|
@ -855,6 +855,8 @@ class ReportHTML implements TableReportModule {
|
|||||||
if (iconPath == null) {
|
if (iconPath == null) {
|
||||||
// use default Autopsy icon if custom icon is not set
|
// use default Autopsy icon if custom icon is not set
|
||||||
iconPath = "favicon.ico";
|
iconPath = "favicon.ico";
|
||||||
|
} else {
|
||||||
|
iconPath = "agency_logo"; //ref to writeNav() for agency_logo
|
||||||
}
|
}
|
||||||
index.append("<head>\n<title>").append(reportTitle).append(" ").append(
|
index.append("<head>\n<title>").append(reportTitle).append(" ").append(
|
||||||
NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.title", currentCase.getDisplayName())).append(
|
NbBundle.getMessage(this.getClass(), "ReportHTML.writeIndex.title", currentCase.getDisplayName())).append(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2015 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");
|
||||||
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.experimental.autoingest;
|
package org.sleuthkit.autopsy.experimental.autoingest;
|
||||||
|
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@ -29,15 +28,12 @@ import java.nio.file.Paths;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.List;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestModuleError;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager.IngestManagerException;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||||
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A logger for the processing of an auto ingest job by an auto ingest node. An
|
* A logger for the processing of an auto ingest job by an auto ingest node. An
|
||||||
@ -107,14 +103,16 @@ final class AutoIngestJobLogger {
|
|||||||
* Advanced users doing troubleshooting of an automated ingest cluster
|
* Advanced users doing troubleshooting of an automated ingest cluster
|
||||||
* should also consult the Autopsy and system logs as needed.
|
* should also consult the Autopsy and system logs as needed.
|
||||||
*
|
*
|
||||||
* @param manifestPath The manifest for the auto ingest job.
|
* @param manifestPath The manifest for the auto ingest job.
|
||||||
* @param caseDirectoryPath The case directory.
|
* @param dataSourceFileName The file name of the data source for the auto
|
||||||
|
* ingest job.
|
||||||
|
* @param caseDirectoryPath The absolute path to the case directory.
|
||||||
*/
|
*/
|
||||||
AutoIngestJobLogger(Path manifestPath, String dataSourceFileName, Path caseDirectoryPath) {
|
AutoIngestJobLogger(Path manifestPath, String dataSourceFileName, Path caseDirectoryPath) {
|
||||||
this.manifestPath = manifestPath;
|
this.manifestPath = manifestPath;
|
||||||
manifestFileName = manifestPath.getFileName().toString();
|
manifestFileName = manifestPath.getFileName().toString();
|
||||||
this.dataSourceFileName = dataSourceFileName;
|
this.dataSourceFileName = dataSourceFileName;
|
||||||
this.caseDirectoryPath = caseDirectoryPath;
|
this.caseDirectoryPath = caseDirectoryPath;
|
||||||
hostName = NetworkUtils.getLocalHostName();
|
hostName = NetworkUtils.getLocalHostName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,30 +193,34 @@ final class AutoIngestJobLogger {
|
|||||||
void logDataSourceProcessorCancelled() throws AutoIngestJobLoggerException, InterruptedException {
|
void logDataSourceProcessorCancelled() throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.WARNING, "Cancelled adding data source to case");
|
log(MessageCategory.WARNING, "Cancelled adding data source to case");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs selection of a data source processor
|
* Logs selection of a data source processor
|
||||||
* @param dsp Name of the data source processor
|
*
|
||||||
|
* @param dsp Name of the data source processor
|
||||||
|
*
|
||||||
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* message.
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* to acquire an exclusive lock on the
|
* to acquire an exclusive lock on the
|
||||||
* log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceProcessorSelected(String dsp) throws AutoIngestJobLoggerException, InterruptedException{
|
void logDataSourceProcessorSelected(String dsp) throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.INFO, "Using data source processor: " + dsp);
|
log(MessageCategory.INFO, "Using data source processor: " + dsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the failure of the selected data source processor.
|
* Logs the failure of the selected data source processor.
|
||||||
* @param dsp Name of the data source processor
|
*
|
||||||
|
* @param dsp Name of the data source processor
|
||||||
|
*
|
||||||
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
* @throws AutoIngestJobLoggerException if there is an error writing the log
|
||||||
* message.
|
* message.
|
||||||
* @throws InterruptedException if interrupted while blocked waiting
|
* @throws InterruptedException if interrupted while blocked waiting
|
||||||
* to acquire an exclusive lock on the
|
* to acquire an exclusive lock on the
|
||||||
* log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
void logDataSourceProcessorError(String dsp) throws AutoIngestJobLoggerException, InterruptedException{
|
void logDataSourceProcessorError(String dsp) throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
log(MessageCategory.ERROR, "Error processing with data source processor: " + dsp);
|
log(MessageCategory.ERROR, "Error processing with data source processor: " + dsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,9 +433,10 @@ final class AutoIngestJobLogger {
|
|||||||
* log file.
|
* log file.
|
||||||
*/
|
*/
|
||||||
private void log(MessageCategory category, String message) throws AutoIngestJobLoggerException, InterruptedException {
|
private void log(MessageCategory category, String message) throws AutoIngestJobLoggerException, InterruptedException {
|
||||||
try (Lock lock = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot()).tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, getLogPath(caseDirectoryPath).toString(), LOCK_TIME_OUT, LOCK_TIME_OUT_UNIT)) {
|
Path logPath = getLogPath(caseDirectoryPath);
|
||||||
|
try (Lock lock = CoordinationService.getInstance().tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, logPath.toString(), LOCK_TIME_OUT, LOCK_TIME_OUT_UNIT)) {
|
||||||
if (null != lock) {
|
if (null != lock) {
|
||||||
File logFile = getLogPath(caseDirectoryPath).toFile();
|
File logFile = logPath.toFile();
|
||||||
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true)) {
|
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true)) {
|
||||||
writer.println(String.format("%s %s: %s: %s: %-8s: %s", logDateFormat.format((Date.from(Instant.now()).getTime())), hostName, manifestFileName, dataSourceFileName, category.toString(), message));
|
writer.println(String.format("%s %s: %s: %s: %-8s: %s", logDateFormat.format((Date.from(Instant.now()).getTime())), hostName, manifestFileName, dataSourceFileName, category.toString(), message));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
@ -73,14 +73,11 @@ import org.sleuthkit.autopsy.casemodule.CaseMetadata;
|
|||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationServiceNamespace;
|
|
||||||
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
import org.sleuthkit.autopsy.core.RuntimeProperties;
|
||||||
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
||||||
import org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException;
|
import org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
import org.sleuthkit.autopsy.core.UserPreferencesException;
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
|
||||||
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
|
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback.DataSourceProcessorResult;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
@ -100,6 +97,8 @@ import static org.sleuthkit.autopsy.experimental.autoingest.ManifestNodeData.Pro
|
|||||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestUserPreferences;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
|
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
|
||||||
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor;
|
||||||
|
import org.sleuthkit.autopsy.framework.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
|
||||||
@ -212,7 +211,7 @@ public final class AutoIngestManager extends Observable implements PropertyChang
|
|||||||
void startUp() throws AutoIngestManagerStartupException {
|
void startUp() throws AutoIngestManagerStartupException {
|
||||||
SYS_LOGGER.log(Level.INFO, "Auto ingest starting");
|
SYS_LOGGER.log(Level.INFO, "Auto ingest starting");
|
||||||
try {
|
try {
|
||||||
coordinationService = CoordinationService.getServiceForNamespace(CoordinationServiceNamespace.getRoot());
|
coordinationService = CoordinationService.getInstance();
|
||||||
} catch (CoordinationServiceException ex) {
|
} catch (CoordinationServiceException ex) {
|
||||||
throw new AutoIngestManagerStartupException("Failed to get coordination service", ex);
|
throw new AutoIngestManagerStartupException("Failed to get coordination service", ex);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ import org.sleuthkit.autopsy.core.ServicesMonitor;
|
|||||||
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
|
import org.sleuthkit.autopsy.modules.hashdatabase.HashDbManager.HashDb;
|
||||||
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestSettingsPanel.UpdateConfigSwingWorker;
|
import org.sleuthkit.autopsy.experimental.configuration.AutoIngestSettingsPanel.UpdateConfigSwingWorker;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
|
||||||
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
|
||||||
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
|
||||||
|
|
||||||
@ -86,7 +87,6 @@ public class SharedConfiguration {
|
|||||||
private static final String PREFERENCES_FOLDER = "Preferences"; //NON-NLS
|
private static final String PREFERENCES_FOLDER = "Preferences"; //NON-NLS
|
||||||
public static final String FILE_EXPORTER_FOLDER = "Automated File Exporter"; //NON-NLS
|
public static final String FILE_EXPORTER_FOLDER = "Automated File Exporter"; //NON-NLS
|
||||||
|
|
||||||
private static final String LOCK_ROOT = "/autopsy"; // NON-NLS
|
|
||||||
private static final String UPLOAD_IN_PROGRESS_FILE = "uploadInProgress"; // NON-NLS
|
private static final String UPLOAD_IN_PROGRESS_FILE = "uploadInProgress"; // NON-NLS
|
||||||
private static final String moduleDirPath = PlatformUtil.getUserConfigDirectory();
|
private static final String moduleDirPath = PlatformUtil.getUserConfigDirectory();
|
||||||
private static final Logger logger = Logger.getLogger(SharedConfiguration.class.getName());
|
private static final Logger logger = Logger.getLogger(SharedConfiguration.class.getName());
|
||||||
@ -160,7 +160,7 @@ public class SharedConfiguration {
|
|||||||
|
|
||||||
File remoteFolder = getSharedFolder();
|
File remoteFolder = getSharedFolder();
|
||||||
|
|
||||||
try (Lock writeLock = CoordinationService.getServiceForNamespace(LOCK_ROOT).tryGetExclusiveLock(CoordinationService.CategoryNode.CONFIG, remoteFolder.getAbsolutePath(), 30, TimeUnit.MINUTES)) {
|
try (Lock writeLock = CoordinationService.getInstance().tryGetExclusiveLock(CategoryNode.CONFIG, remoteFolder.getAbsolutePath(), 30, TimeUnit.MINUTES)) {
|
||||||
if (writeLock == null) {
|
if (writeLock == null) {
|
||||||
logger.log(Level.INFO, String.format("Failed to lock %s - another node is currently uploading or downloading configuration", remoteFolder.getAbsolutePath()));
|
logger.log(Level.INFO, String.format("Failed to lock %s - another node is currently uploading or downloading configuration", remoteFolder.getAbsolutePath()));
|
||||||
return SharedConfigResult.LOCKED;
|
return SharedConfigResult.LOCKED;
|
||||||
@ -230,7 +230,7 @@ public class SharedConfiguration {
|
|||||||
|
|
||||||
File remoteFolder = getSharedFolder();
|
File remoteFolder = getSharedFolder();
|
||||||
|
|
||||||
try (Lock readLock = CoordinationService.getServiceForNamespace(LOCK_ROOT).tryGetSharedLock(CoordinationService.CategoryNode.CONFIG, remoteFolder.getAbsolutePath(), 30, TimeUnit.MINUTES)) {
|
try (Lock readLock = CoordinationService.getInstance().tryGetSharedLock(CategoryNode.CONFIG, remoteFolder.getAbsolutePath(), 30, TimeUnit.MINUTES)) {
|
||||||
if (readLock == null) {
|
if (readLock == null) {
|
||||||
return SharedConfigResult.LOCKED;
|
return SharedConfigResult.LOCKED;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
@ -244,7 +243,6 @@ class HighlightedText implements IndexedText {
|
|||||||
@Override
|
@Override
|
||||||
public boolean hasNextPage() {
|
public boolean hasNextPage() {
|
||||||
return getIndexOfCurrentPage() < pages.size() - 1;
|
return getIndexOfCurrentPage() < pages.size() - 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -255,7 +253,7 @@ class HighlightedText implements IndexedText {
|
|||||||
@Override
|
@Override
|
||||||
public int nextPage() {
|
public int nextPage() {
|
||||||
if (hasNextPage()) {
|
if (hasNextPage()) {
|
||||||
currentPage = Iterators.get(pages.iterator(),getIndexOfCurrentPage() + 1);
|
currentPage = Iterators.get(pages.iterator(), getIndexOfCurrentPage() + 1);
|
||||||
return currentPage;
|
return currentPage;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("No next page.");
|
throw new IllegalStateException("No next page.");
|
||||||
@ -265,7 +263,7 @@ class HighlightedText implements IndexedText {
|
|||||||
@Override
|
@Override
|
||||||
public int previousPage() {
|
public int previousPage() {
|
||||||
if (hasPreviousPage()) {
|
if (hasPreviousPage()) {
|
||||||
currentPage = Iterators.get(pages.iterator(),getIndexOfCurrentPage()-1);
|
currentPage = Iterators.get(pages.iterator(), getIndexOfCurrentPage() - 1);
|
||||||
return currentPage;
|
return currentPage;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("No previous page.");
|
throw new IllegalStateException("No previous page.");
|
||||||
@ -387,7 +385,7 @@ class HighlightedText implements IndexedText {
|
|||||||
highlightedContent = insertAnchors(highlightedContent);
|
highlightedContent = insertAnchors(highlightedContent);
|
||||||
|
|
||||||
return "<html><pre>" + highlightedContent + "</pre></html>"; //NON-NLS
|
return "<html><pre>" + highlightedContent + "</pre></html>"; //NON-NLS
|
||||||
} catch (Exception ex) {
|
} catch (TskCoreException | KeywordSearchModuleException | NoOpenCoreException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting highlighted text for " + objectId, ex); //NON-NLS
|
logger.log(Level.SEVERE, "Error getting highlighted text for " + objectId, ex); //NON-NLS
|
||||||
return NbBundle.getMessage(this.getClass(), "HighlightedMatchesSource.getMarkup.queryFailedMsg");
|
return NbBundle.getMessage(this.getClass(), "HighlightedMatchesSource.getMarkup.queryFailedMsg");
|
||||||
}
|
}
|
||||||
@ -453,8 +451,8 @@ class HighlightedText implements IndexedText {
|
|||||||
//we also need to escape the keyword so that it matches the escpared text
|
//we also need to escape the keyword so that it matches the escpared text
|
||||||
final String escapedKeyword = StringEscapeUtils.escapeHtml(keyword);
|
final String escapedKeyword = StringEscapeUtils.escapeHtml(keyword);
|
||||||
int textOffset = 0;
|
int textOffset = 0;
|
||||||
int hitOffset;
|
int hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, textOffset);
|
||||||
while ((hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, textOffset)) != -1) {
|
while (hitOffset != -1) {
|
||||||
// Append the portion of text up to (but not including) the hit.
|
// Append the portion of text up to (but not including) the hit.
|
||||||
highlightedText.append(text.substring(textOffset, hitOffset));
|
highlightedText.append(text.substring(textOffset, hitOffset));
|
||||||
// Add in the highlighting around the keyword.
|
// Add in the highlighting around the keyword.
|
||||||
@ -464,13 +462,15 @@ class HighlightedText implements IndexedText {
|
|||||||
|
|
||||||
// Advance the text offset past the keyword.
|
// Advance the text offset past the keyword.
|
||||||
textOffset = hitOffset + escapedKeyword.length();
|
textOffset = hitOffset + escapedKeyword.length();
|
||||||
|
|
||||||
|
hitOffset = StringUtils.indexOfIgnoreCase(text, escapedKeyword, textOffset);
|
||||||
}
|
}
|
||||||
// Append the remainder of text field
|
// Append the remainder of text field
|
||||||
highlightedText.append(text.substring(textOffset, text.length()));
|
highlightedText.append(text.substring(textOffset, text.length()));
|
||||||
|
|
||||||
if (highlightedText.length() == 0) {
|
if (highlightedText.length() == 0) {
|
||||||
return NbBundle.getMessage(HighlightedText.class, "HighlightedMatchesSource.getMarkup.noMatchMsg");
|
return NbBundle.getMessage(HighlightedText.class, "HighlightedMatchesSource.getMarkup.noMatchMsg");
|
||||||
}
|
}
|
||||||
//reset for next pass
|
//reset for next pass
|
||||||
text = highlightedText.toString();
|
text = highlightedText.toString();
|
||||||
highlightedText = new StringBuilder("");
|
highlightedText = new StringBuilder("");
|
||||||
@ -487,22 +487,21 @@ class HighlightedText implements IndexedText {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String insertAnchors(String searchableContent) {
|
private String insertAnchors(String searchableContent) {
|
||||||
int searchOffset = 0;
|
|
||||||
int index = -1;
|
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder(searchableContent);
|
StringBuilder buf = new StringBuilder(searchableContent);
|
||||||
|
|
||||||
final String searchToken = HIGHLIGHT_PRE;
|
final String searchToken = HIGHLIGHT_PRE;
|
||||||
final int indexSearchTokLen = searchToken.length();
|
final int indexSearchTokLen = searchToken.length();
|
||||||
final String insertPre = "<a name='" + ANCHOR_PREFIX; //NON-NLS
|
final String insertPre = "<a name='" + ANCHOR_PREFIX; //NON-NLS
|
||||||
final String insertPost = "'></a>"; //NON-NLS
|
final String insertPost = "'></a>"; //NON-NLS
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while ((index = buf.indexOf(searchToken, searchOffset)) >= 0) {
|
int searchOffset = 0;
|
||||||
|
int index = buf.indexOf(searchToken, searchOffset);
|
||||||
|
while (index >= 0) {
|
||||||
String insertString = insertPre + Integer.toString(count + 1) + insertPost;
|
String insertString = insertPre + Integer.toString(count + 1) + insertPost;
|
||||||
int insertStringLen = insertString.length();
|
int insertStringLen = insertString.length();
|
||||||
buf.insert(index, insertString);
|
buf.insert(index, insertString);
|
||||||
searchOffset = index + indexSearchTokLen + insertStringLen; //next offset past this anchor
|
searchOffset = index + indexSearchTokLen + insertStringLen; //next offset past this anchor
|
||||||
++count;
|
++count;
|
||||||
|
index = buf.indexOf(searchToken, searchOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
//store total hits for this page, now that we know it
|
//store total hits for this page, now that we know it
|
||||||
|
@ -27,17 +27,23 @@ import java.util.logging.Level;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
|
import org.apache.solr.client.solrj.SolrRequest;
|
||||||
import org.apache.solr.client.solrj.SolrRequest.METHOD;
|
import org.apache.solr.client.solrj.SolrRequest.METHOD;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
import org.apache.solr.common.SolrDocument;
|
import org.apache.solr.common.SolrDocument;
|
||||||
import org.apache.solr.common.SolrDocumentList;
|
import org.apache.solr.common.SolrDocumentList;
|
||||||
|
import org.apache.solr.common.params.CursorMarkParams;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Version;
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
import static org.sleuthkit.autopsy.keywordsearch.RegexQuery.LOGGER;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskException;
|
import org.sleuthkit.datamodel.TskException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +60,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
private KeywordList keywordList = null;
|
private KeywordList keywordList = null;
|
||||||
private final List<KeywordQueryFilter> filters = new ArrayList<>();
|
private final List<KeywordQueryFilter> filters = new ArrayList<>();
|
||||||
private String field = null;
|
private String field = null;
|
||||||
private static final int MAX_RESULTS = 20000;
|
private static final int MAX_RESULTS_PER_CURSOR_MARK = 512;
|
||||||
static final int SNIPPET_LENGTH = 50;
|
static final int SNIPPET_LENGTH = 50;
|
||||||
static final String HIGHLIGHT_FIELD = Server.Schema.TEXT.toString();
|
static final String HIGHLIGHT_FIELD = Server.Schema.TEXT.toString();
|
||||||
|
|
||||||
@ -65,7 +71,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
*
|
*
|
||||||
* @param keyword
|
* @param keyword
|
||||||
*/
|
*/
|
||||||
public LuceneQuery(KeywordList keywordList, Keyword keyword) {
|
LuceneQuery(KeywordList keywordList, Keyword keyword) {
|
||||||
this.keywordList = keywordList;
|
this.keywordList = keywordList;
|
||||||
this.originalKeyword = keyword;
|
this.originalKeyword = keyword;
|
||||||
|
|
||||||
@ -89,7 +95,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
public void setSubstringQuery() {
|
public void setSubstringQuery() {
|
||||||
// Note that this is not a full substring search. Normally substring
|
// Note that this is not a full substring search. Normally substring
|
||||||
// searches will be done with TermComponentQuery objects instead.
|
// searches will be done with TermComponentQuery objects instead.
|
||||||
keywordStringEscaped = keywordStringEscaped + "*";
|
keywordStringEscaped += "*";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -120,17 +126,17 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResults performQuery() throws KeywordSearchModuleException, NoOpenCoreException {
|
public QueryResults performQuery() throws KeywordSearchModuleException, NoOpenCoreException {
|
||||||
QueryResults results = new QueryResults(this, keywordList);
|
QueryResults results = new QueryResults(this);
|
||||||
//in case of single term literal query there is only 1 term
|
//in case of single term literal query there is only 1 term
|
||||||
boolean showSnippets = KeywordSearchSettings.getShowSnippets();
|
results.addResult(new Keyword(keywordString, true),
|
||||||
results.addResult(new Keyword(keywordString, true), performLuceneQuery(showSnippets));
|
performLuceneQuery(KeywordSearchSettings.getShowSnippets()));
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate() {
|
public boolean validate() {
|
||||||
return keywordString != null && !keywordString.equals("");
|
return StringUtils.isNotBlank(keywordString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -180,7 +186,7 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
bba.addAttributes(attributes); //write out to bb
|
bba.addAttributes(attributes); //write out to bb
|
||||||
writeResult.add(attributes);
|
writeResult.add(attributes);
|
||||||
return writeResult;
|
return writeResult;
|
||||||
} catch (TskException e) {
|
} catch (TskCoreException e) {
|
||||||
logger.log(Level.WARNING, "Error adding bb attributes to artifact", e); //NON-NLS
|
logger.log(Level.WARNING, "Error adding bb attributes to artifact", e); //NON-NLS
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -191,46 +197,41 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
*
|
*
|
||||||
* @param snippets True if results should have a snippet
|
* @param snippets True if results should have a snippet
|
||||||
*
|
*
|
||||||
* @return list of ContentHit objects. One per file with hit (ignores
|
* @return list of KeywordHit objects. One per file with hit (ignores
|
||||||
* multiple hits of the word in the same doc)
|
* multiple hits of the word in the same doc)
|
||||||
*
|
*
|
||||||
* @throws NoOpenCoreException
|
|
||||||
*/
|
*/
|
||||||
private List<KeywordHit> performLuceneQuery(boolean snippets) throws KeywordSearchModuleException, NoOpenCoreException {
|
private List<KeywordHit> performLuceneQuery(boolean snippets) throws KeywordSearchModuleException, NoOpenCoreException {
|
||||||
List<KeywordHit> matches = new ArrayList<>();
|
List<KeywordHit> matches = new ArrayList<>();
|
||||||
boolean allMatchesFetched = false;
|
|
||||||
final Server solrServer = KeywordSearch.getServer();
|
final Server solrServer = KeywordSearch.getServer();
|
||||||
|
double indexSchemaVersion = NumberUtils.toDouble(solrServer.getIndexInfo().getSchemaVersion());
|
||||||
|
|
||||||
SolrQuery q = createAndConfigureSolrQuery(snippets);
|
SolrQuery solrQuery = createAndConfigureSolrQuery(snippets);
|
||||||
QueryResponse response;
|
|
||||||
SolrDocumentList resultList;
|
|
||||||
Map<String, Map<String, List<String>>> highlightResponse;
|
|
||||||
|
|
||||||
response = solrServer.query(q, METHOD.POST);
|
|
||||||
|
|
||||||
resultList = response.getResults();
|
|
||||||
// objectId_chunk -> "text" -> List of previews
|
|
||||||
highlightResponse = response.getHighlighting();
|
|
||||||
|
|
||||||
final String strippedQueryString = StringUtils.strip(getQueryString(), "\"");
|
final String strippedQueryString = StringUtils.strip(getQueryString(), "\"");
|
||||||
|
|
||||||
// cycle through results in sets of MAX_RESULTS
|
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
|
||||||
for (int start = 0; !allMatchesFetched; start = start + MAX_RESULTS) {
|
boolean allResultsProcessed = false;
|
||||||
q.setStart(start);
|
|
||||||
|
|
||||||
allMatchesFetched = start + MAX_RESULTS >= resultList.getNumFound();
|
while (!allResultsProcessed) {
|
||||||
|
solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
|
||||||
|
QueryResponse response = solrServer.query(solrQuery, SolrRequest.METHOD.POST);
|
||||||
|
SolrDocumentList resultList = response.getResults();
|
||||||
|
// objectId_chunk -> "text" -> List of previews
|
||||||
|
Map<String, Map<String, List<String>>> highlightResponse = response.getHighlighting();
|
||||||
|
|
||||||
for (SolrDocument resultDoc : resultList) {
|
for (SolrDocument resultDoc : resultList) {
|
||||||
try {
|
try {
|
||||||
/* for each result, check that the first occurence of that
|
/*
|
||||||
|
* for each result, check that the first occurence of that
|
||||||
* term is before the window. if all the ocurences start
|
* term is before the window. if all the ocurences start
|
||||||
* within the window, don't record them for this chunk, they
|
* within the window, don't record them for this chunk, they
|
||||||
* will get picked up in the next one. */
|
* will get picked up in the next one.
|
||||||
|
*/
|
||||||
final String docId = resultDoc.getFieldValue(Server.Schema.ID.toString()).toString();
|
final String docId = resultDoc.getFieldValue(Server.Schema.ID.toString()).toString();
|
||||||
final Integer chunkSize = (Integer) resultDoc.getFieldValue(Server.Schema.CHUNK_SIZE.toString());
|
final Integer chunkSize = (Integer) resultDoc.getFieldValue(Server.Schema.CHUNK_SIZE.toString());
|
||||||
final Collection<Object> content = resultDoc.getFieldValues(Server.Schema.CONTENT_STR.toString());
|
final Collection<Object> content = resultDoc.getFieldValues(Server.Schema.CONTENT_STR.toString());
|
||||||
|
|
||||||
double indexSchemaVersion = NumberUtils.toDouble(KeywordSearch.getServer().getIndexInfo().getSchemaVersion());
|
|
||||||
if (indexSchemaVersion < 2.0) {
|
if (indexSchemaVersion < 2.0) {
|
||||||
//old schema versions don't support chunk_size or the content_str fields, so just accept hits
|
//old schema versions don't support chunk_size or the content_str fields, so just accept hits
|
||||||
matches.add(createKeywordtHit(highlightResponse, docId));
|
matches.add(createKeywordtHit(highlightResponse, docId));
|
||||||
@ -250,11 +251,17 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String nextCursorMark = response.getNextCursorMark();
|
||||||
|
if (cursorMark.equals(nextCursorMark)) {
|
||||||
|
allResultsProcessed = true;
|
||||||
|
}
|
||||||
|
cursorMark = nextCursorMark;
|
||||||
|
|
||||||
}
|
}
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Create the query object for the stored keyword
|
* Create the query object for the stored keyword
|
||||||
*
|
*
|
||||||
* @param snippets True if query should request snippets
|
* @param snippets True if query should request snippets
|
||||||
@ -271,17 +278,17 @@ class LuceneQuery implements KeywordSearchQuery {
|
|||||||
// Run the query against an optional alternative field.
|
// Run the query against an optional alternative field.
|
||||||
if (field != null) {
|
if (field != null) {
|
||||||
//use the optional field
|
//use the optional field
|
||||||
StringBuilder sb = new StringBuilder();
|
theQueryStr = field + ":" + theQueryStr;
|
||||||
sb.append(field).append(":").append(theQueryStr);
|
|
||||||
theQueryStr = sb.toString();
|
|
||||||
}
|
}
|
||||||
q.setQuery(theQueryStr);
|
q.setQuery(theQueryStr);
|
||||||
q.setRows(MAX_RESULTS);
|
q.setRows(MAX_RESULTS_PER_CURSOR_MARK);
|
||||||
|
// Setting the sort order is necessary for cursor based paging to work.
|
||||||
|
q.setSort(SolrQuery.SortClause.asc(Server.Schema.ID.toString()));
|
||||||
|
|
||||||
q.setFields(Server.Schema.ID.toString(),
|
q.setFields(Server.Schema.ID.toString(),
|
||||||
Server.Schema.CHUNK_SIZE.toString(),
|
Server.Schema.CHUNK_SIZE.toString(),
|
||||||
Server.Schema.CONTENT_STR.toString());
|
Server.Schema.CONTENT_STR.toString());
|
||||||
q.addSort(Server.Schema.ID.toString(), SolrQuery.ORDER.asc);
|
|
||||||
for (KeywordQueryFilter filter : filters) {
|
for (KeywordQueryFilter filter : filters) {
|
||||||
q.addFilterQuery(filter.toString());
|
q.addFilterQuery(filter.toString());
|
||||||
}
|
}
|
||||||
|
@ -60,25 +60,17 @@ class QueryResults {
|
|||||||
*/
|
*/
|
||||||
private final Map<Keyword, List<KeywordHit>> results = new HashMap<>();
|
private final Map<Keyword, List<KeywordHit>> results = new HashMap<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of keywords
|
|
||||||
*/
|
|
||||||
// TODO: This is redundant. The keyword list is in the query.
|
|
||||||
private final KeywordList keywordList;
|
|
||||||
|
|
||||||
QueryResults(KeywordSearchQuery query, KeywordList keywordList) {
|
QueryResults(KeywordSearchQuery query) {
|
||||||
this.keywordSearchQuery = query;
|
this.keywordSearchQuery = query;
|
||||||
this.keywordList = keywordList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addResult(Keyword keyword, List<KeywordHit> hits) {
|
void addResult(Keyword keyword, List<KeywordHit> hits) {
|
||||||
results.put(keyword, hits);
|
results.put(keyword, hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This is redundant. The keyword list is in the query.
|
|
||||||
KeywordList getKeywordList() {
|
|
||||||
return keywordList;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeywordSearchQuery getQuery() {
|
KeywordSearchQuery getQuery() {
|
||||||
return keywordSearchQuery;
|
return keywordSearchQuery;
|
||||||
@ -129,7 +121,7 @@ class QueryResults {
|
|||||||
if (hitDisplayStr.length() > 50) {
|
if (hitDisplayStr.length() > 50) {
|
||||||
hitDisplayStr = hitDisplayStr.substring(0, 49) + "...";
|
hitDisplayStr = hitDisplayStr.substring(0, 49) + "...";
|
||||||
}
|
}
|
||||||
subProgress.progress(keywordList.getName() + ": " + hitDisplayStr, unitProgress);
|
subProgress.progress(keywordSearchQuery.getKeywordList().getName() + ": " + hitDisplayStr, unitProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (KeywordHit hit : getOneHitPerObject(keyword)) {
|
for (KeywordHit hit : getOneHitPerObject(keyword)) {
|
||||||
@ -138,7 +130,11 @@ class QueryResults {
|
|||||||
if (StringUtils.isBlank(snippet)) {
|
if (StringUtils.isBlank(snippet)) {
|
||||||
final String snippetQuery = KeywordSearchUtil.escapeLuceneQuery(termString);
|
final String snippetQuery = KeywordSearchUtil.escapeLuceneQuery(termString);
|
||||||
try {
|
try {
|
||||||
//this doesn't work for regex queries...
|
/*
|
||||||
|
* this doesn't work for regex queries... But that is
|
||||||
|
* okay because regex queries always have snippets made
|
||||||
|
* from the content_str field we pull back from Solr
|
||||||
|
*/
|
||||||
snippet = LuceneQuery.querySnippet(snippetQuery, hit.getSolrObjectId(), hit.getChunkId(), !keywordSearchQuery.isLiteral(), true);
|
snippet = LuceneQuery.querySnippet(snippetQuery, hit.getSolrObjectId(), hit.getChunkId(), !keywordSearchQuery.isLiteral(), true);
|
||||||
} catch (NoOpenCoreException e) {
|
} catch (NoOpenCoreException e) {
|
||||||
logger.log(Level.WARNING, "Error querying snippet: " + snippetQuery, e); //NON-NLS
|
logger.log(Level.WARNING, "Error querying snippet: " + snippetQuery, e); //NON-NLS
|
||||||
@ -149,16 +145,14 @@ class QueryResults {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (snippet != null) {
|
KeywordCachedArtifact writeResult = keywordSearchQuery.writeSingleFileHitsToBlackBoard(keyword, hit, snippet, keywordSearchQuery.getKeywordList().getName());
|
||||||
KeywordCachedArtifact writeResult = keywordSearchQuery.writeSingleFileHitsToBlackBoard(keyword, hit, snippet, keywordList.getName());
|
if (writeResult != null) {
|
||||||
if (writeResult != null) {
|
newArtifacts.add(writeResult.getArtifact());
|
||||||
newArtifacts.add(writeResult.getArtifact());
|
if (notifyInbox) {
|
||||||
if (notifyInbox) {
|
writeSingleFileInboxMessage(writeResult, hit.getContent());
|
||||||
writeSingleFileInboxMessage(writeResult, hit.getContent());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.log(Level.WARNING, "BB artifact for keyword hit not written, file: {0}, hit: {1}", new Object[]{hit.getContent(), keyword.toString()}); //NON-NLS
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, "BB artifact for keyword hit not written, file: {0}, hit: {1}", new Object[]{hit.getContent(), keyword.toString()}); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++unitProgress;
|
++unitProgress;
|
||||||
|
@ -81,7 +81,7 @@ final class RegexQuery implements KeywordSearchQuery {
|
|||||||
private final Keyword originalKeyword; // The regular expression originalKeyword used to perform the search.
|
private final Keyword originalKeyword; // The regular expression originalKeyword used to perform the search.
|
||||||
private String field = Server.Schema.CONTENT_STR.toString();
|
private String field = Server.Schema.CONTENT_STR.toString();
|
||||||
private final String keywordString;
|
private final String keywordString;
|
||||||
static final private int MAX_RESULTS = 512;
|
static final private int MAX_RESULTS_PER_CURSOR_MARK = 512;
|
||||||
private boolean escaped;
|
private boolean escaped;
|
||||||
private String escapedQuery;
|
private String escapedQuery;
|
||||||
|
|
||||||
@ -154,7 +154,6 @@ final class RegexQuery implements KeywordSearchQuery {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResults performQuery() throws NoOpenCoreException {
|
public QueryResults performQuery() throws NoOpenCoreException {
|
||||||
QueryResults results = new QueryResults(this, keywordList);
|
|
||||||
|
|
||||||
final Server solrServer = KeywordSearch.getServer();
|
final Server solrServer = KeywordSearch.getServer();
|
||||||
SolrQuery solrQuery = new SolrQuery();
|
SolrQuery solrQuery = new SolrQuery();
|
||||||
@ -187,12 +186,12 @@ final class RegexQuery implements KeywordSearchQuery {
|
|||||||
.map(KeywordQueryFilter::toString)
|
.map(KeywordQueryFilter::toString)
|
||||||
.forEach(solrQuery::addFilterQuery);
|
.forEach(solrQuery::addFilterQuery);
|
||||||
|
|
||||||
solrQuery.setRows(MAX_RESULTS);
|
solrQuery.setRows(MAX_RESULTS_PER_CURSOR_MARK);
|
||||||
// Setting the sort order is necessary for cursor based paging to work.
|
// Setting the sort order is necessary for cursor based paging to work.
|
||||||
solrQuery.setSort(SortClause.asc(Server.Schema.ID.toString()));
|
solrQuery.setSort(SortClause.asc(Server.Schema.ID.toString()));
|
||||||
|
|
||||||
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
|
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
|
||||||
SolrDocumentList resultList = null;
|
SolrDocumentList resultList ;
|
||||||
boolean allResultsProcessed = false;
|
boolean allResultsProcessed = false;
|
||||||
|
|
||||||
while (!allResultsProcessed) {
|
while (!allResultsProcessed) {
|
||||||
@ -218,15 +217,14 @@ final class RegexQuery implements KeywordSearchQuery {
|
|||||||
}
|
}
|
||||||
cursorMark = nextCursorMark;
|
cursorMark = nextCursorMark;
|
||||||
} catch (KeywordSearchModuleException ex) {
|
} catch (KeywordSearchModuleException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Error executing Lucene Solr Query: " + keywordString, ex); //NON-NLS
|
LOGGER.log(Level.SEVERE, "Error executing Regex Solr Query: " + keywordString, ex); //NON-NLS
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(Server.class, "Server.query.exception.msg", keywordString), ex.getCause().getMessage());
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(Server.class, "Server.query.exception.msg", keywordString), ex.getCause().getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QueryResults results = new QueryResults(this);
|
||||||
for (Keyword k : hitsMultiMap.keySet()) {
|
for (Keyword k : hitsMultiMap.keySet()) {
|
||||||
results.addResult(k, hitsMultiMap.get(k));
|
results.addResult(k, hitsMultiMap.get(k));
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ public final class SearchRunner {
|
|||||||
|
|
||||||
// Create a new (empty) QueryResults object to hold the most recently
|
// Create a new (empty) QueryResults object to hold the most recently
|
||||||
// found hits.
|
// found hits.
|
||||||
QueryResults newResults = new QueryResults(queryResult.getQuery(), queryResult.getKeywordList());
|
QueryResults newResults = new QueryResults(queryResult.getQuery());
|
||||||
|
|
||||||
// For each keyword represented in the results.
|
// For each keyword represented in the results.
|
||||||
for (Keyword keyword : queryResult.getKeywords()) {
|
for (Keyword keyword : queryResult.getKeywords()) {
|
||||||
|
@ -280,7 +280,7 @@ final class TermsComponentQuery implements KeywordSearchQuery {
|
|||||||
/*
|
/*
|
||||||
* Do a term query for each term that matched the regex.
|
* Do a term query for each term that matched the regex.
|
||||||
*/
|
*/
|
||||||
QueryResults results = new QueryResults(this, keywordList);
|
QueryResults results = new QueryResults(this);
|
||||||
for (Term term : terms) {
|
for (Term term : terms) {
|
||||||
/*
|
/*
|
||||||
* If searching for credit card account numbers, do a Luhn check on
|
* If searching for credit card account numbers, do a Luhn check on
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<import file="nbproject/build-impl.xml"/>
|
<import file="nbproject/build-impl.xml"/>
|
||||||
|
|
||||||
<!-- IMPORTANT: nbproject/platform.properties has a netbeans-plat-version property that MUST be kept in sync (manually) -->
|
<!-- IMPORTANT: nbproject/platform.properties has a netbeans-plat-version property that MUST be kept in sync (manually) -->
|
||||||
<property name="netbeans-plat-version" value="8.1" />
|
<property name="netbeans-plat-version" value="8.2" />
|
||||||
<property name="nbplatform.active.dir" value="${basedir}/netbeans-plat/${netbeans-plat-version}" />
|
<property name="nbplatform.active.dir" value="${basedir}/netbeans-plat/${netbeans-plat-version}" />
|
||||||
<!-- Supported java versions.-->
|
<!-- Supported java versions.-->
|
||||||
<condition property="supported-java-versions">
|
<condition property="supported-java-versions">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
branding.token=autopsy
|
branding.token=autopsy
|
||||||
# Version of platform that is automatically downloaded
|
# Version of platform that is automatically downloaded
|
||||||
# IMPORTANT: autopsy/build.xml has a netbeans-plat-version property that MUST be kept in sync (manually)
|
# IMPORTANT: autopsy/build.xml has a netbeans-plat-version property that MUST be kept in sync (manually)
|
||||||
netbeans-plat-version=8.1
|
netbeans-plat-version=8.2
|
||||||
suite.dir=${basedir}
|
suite.dir=${basedir}
|
||||||
nbplatform.active.dir=${suite.dir}/netbeans-plat/${netbeans-plat-version}
|
nbplatform.active.dir=${suite.dir}/netbeans-plat/${netbeans-plat-version}
|
||||||
harness.dir=${nbplatform.active.dir}/harness
|
harness.dir=${nbplatform.active.dir}/harness
|
||||||
|
BIN
thirdparty/junit/8.2/junit.zip
vendored
Normal file
BIN
thirdparty/junit/8.2/junit.zip
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user