mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
Handle empty tables.
Cleanup
This commit is contained in:
parent
f8d02a3002
commit
3ef9746d26
@ -32,6 +32,7 @@ DataResultViewerTable.commentRenderer.noComment.toolTip=No comments found
|
|||||||
DataResultViewerTable.commentRenderer.tagComment.toolTip=Comment exists on associated tag(s)
|
DataResultViewerTable.commentRenderer.tagComment.toolTip=Comment exists on associated tag(s)
|
||||||
DataResultViewerTable.countRender.name=O
|
DataResultViewerTable.countRender.name=O
|
||||||
DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository
|
DataResultViewerTable.countRender.toolTip=O(ccurrences) indicates the number of data sources containing the item in the Central Repository
|
||||||
|
DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export
|
||||||
DataResultViewerTable.firstColLbl=Name
|
DataResultViewerTable.firstColLbl=Name
|
||||||
DataResultViewerTable.goToPageTextField.err=Invalid page number
|
DataResultViewerTable.goToPageTextField.err=Invalid page number
|
||||||
# {0} - totalPages
|
# {0} - totalPages
|
||||||
|
@ -18,12 +18,11 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="outlineView" pref="904" max="32767" attributes="0"/>
|
<Component id="outlineView" pref="904" max="32767" attributes="0"/>
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="exportCSVButton" min="-2" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
|
||||||
<Component id="pageLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="pageLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="pageNumLabel" min="-2" pref="53" max="-2" attributes="0"/>
|
<Component id="pageNumLabel" min="-2" pref="53" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
|
||||||
<Component id="pagesLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="pagesLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="pagePrevButton" linkSize="1" min="-2" pref="16" max="-2" attributes="0"/>
|
<Component id="pagePrevButton" linkSize="1" min="-2" pref="16" max="-2" attributes="0"/>
|
||||||
@ -33,7 +32,8 @@
|
|||||||
<Component id="gotoPageLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="gotoPageLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="gotoPageTextField" min="-2" pref="33" max="-2" attributes="0"/>
|
<Component id="gotoPageTextField" min="-2" pref="33" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Component id="exportCSVButton" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
|
@ -77,6 +77,7 @@ import org.openide.util.lookup.ServiceProvider;
|
|||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
import org.sleuthkit.autopsy.datamodel.NodeProperty;
|
||||||
import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo;
|
import org.sleuthkit.autopsy.datamodel.NodeSelectionInfo;
|
||||||
@ -176,6 +177,13 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
initializePagingSupport();
|
initializePagingSupport();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable the CSV export button for the common properties results
|
||||||
|
*/
|
||||||
|
if (this instanceof org.sleuthkit.autopsy.commonpropertiessearch.CommonAttributesSearchResultsViewerTable) {
|
||||||
|
exportCSVButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the child OutlineView (explorer view) component.
|
* Configure the child OutlineView (explorer view) component.
|
||||||
@ -1352,12 +1360,11 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 904, Short.MAX_VALUE)
|
.addComponent(outlineView, javax.swing.GroupLayout.DEFAULT_SIZE, 904, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(exportCSVButton)
|
.addContainerGap()
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
.addComponent(pageLabel)
|
.addComponent(pageLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(pageNumLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addGap(14, 14, 14)
|
||||||
.addComponent(pagesLabel)
|
.addComponent(pagesLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(pagePrevButton, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
@ -1367,7 +1374,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
.addComponent(gotoPageLabel)
|
.addComponent(gotoPageLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(gotoPageTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addContainerGap())
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(exportCSVButton))
|
||||||
);
|
);
|
||||||
|
|
||||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {pageNextButton, pagePrevButton});
|
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {pageNextButton, pagePrevButton});
|
||||||
@ -1407,8 +1415,15 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
|||||||
pagingSupport.gotoPage();
|
pagingSupport.gotoPage();
|
||||||
}//GEN-LAST:event_gotoPageTextFieldActionPerformed
|
}//GEN-LAST:event_gotoPageTextFieldActionPerformed
|
||||||
|
|
||||||
|
@NbBundle.Messages({"DataResultViewerTable.exportCSVButtonActionPerformed.empty=No data to export"
|
||||||
|
})
|
||||||
private void exportCSVButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportCSVButtonActionPerformed
|
private void exportCSVButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportCSVButtonActionPerformed
|
||||||
org.sleuthkit.autopsy.directorytree.ExportCSVAction.saveNodesToCSV(java.util.Arrays.asList(rootNode.getChildren().getNodes()), this);
|
Node currentRoot = this.getExplorerManager().getRootContext();
|
||||||
|
if (currentRoot != null && currentRoot.getChildren().getNodesCount() > 0) {
|
||||||
|
org.sleuthkit.autopsy.directorytree.ExportCSVAction.saveNodesToCSV(java.util.Arrays.asList(currentRoot.getChildren().getNodes()), this);
|
||||||
|
} else {
|
||||||
|
MessageNotifyUtil.Message.info(Bundle.DataResultViewerTable_exportCSVButtonActionPerformed_empty());
|
||||||
|
}
|
||||||
}//GEN-LAST:event_exportCSVButtonActionPerformed
|
}//GEN-LAST:event_exportCSVButtonActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
@ -10,6 +10,7 @@ DirectoryTreeTopComponent.componentOpened.groupDataSources.text=This case contai
|
|||||||
DirectoryTreeTopComponent.componentOpened.groupDataSources.title=Group by data source?
|
DirectoryTreeTopComponent.componentOpened.groupDataSources.title=Group by data source?
|
||||||
DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.
|
DirectoryTreeTopComponent.emptyMimeNode.text=Data not available. Run file type identification module.
|
||||||
DirectoryTreeTopComponent.resultsView.title=Listing
|
DirectoryTreeTopComponent.resultsView.title=Listing
|
||||||
|
ExportCSV.saveNodesToCSV.empty=No data to export
|
||||||
# {0} - Output file
|
# {0} - Output file
|
||||||
ExportCSV.saveNodesToCSV.fileExists=File {0} already exists
|
ExportCSV.saveNodesToCSV.fileExists=File {0} already exists
|
||||||
ExportCSV.saveNodesToCSV.noCurrentCase=No open case available
|
ExportCSV.saveNodesToCSV.noCurrentCase=No open case available
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2013-2018 Basis Technology Corp.
|
* Copyright 2019 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");
|
||||||
@ -22,7 +22,6 @@ import java.awt.Component;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -31,10 +30,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
@ -48,14 +45,8 @@ import org.openide.util.NbBundle;
|
|||||||
import org.openide.util.Utilities;
|
import org.openide.util.Utilities;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.coreutils.FileUtil;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils.ExtractFscContentVisitor;
|
|
||||||
import org.sleuthkit.autopsy.datamodel.FileNode;
|
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
|
||||||
import org.openide.nodes.AbstractNode;
|
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.Node.PropertySet;
|
import org.openide.nodes.Node.PropertySet;
|
||||||
import org.openide.nodes.Node.Property;
|
import org.openide.nodes.Node.Property;
|
||||||
@ -76,6 +67,12 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
// node in the array returns a reference to the same action object from Node.getActions(boolean).
|
// node in the array returns a reference to the same action object from Node.getActions(boolean).
|
||||||
private static ExportCSVAction instance;
|
private static ExportCSVAction instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an instance of the Action. See above for why
|
||||||
|
* the class is a singleton.
|
||||||
|
*
|
||||||
|
* @return the instance
|
||||||
|
*/
|
||||||
public static synchronized ExportCSVAction getInstance() {
|
public static synchronized ExportCSVAction getInstance() {
|
||||||
if (null == instance) {
|
if (null == instance) {
|
||||||
instance = new ExportCSVAction();
|
instance = new ExportCSVAction();
|
||||||
@ -104,20 +101,28 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
saveNodesToCSV(selectedNodes, (Component)e.getSource());
|
saveNodesToCSV(selectedNodes, (Component)e.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the selected nodes to a CSV file
|
||||||
|
*
|
||||||
|
* @param nodesToExport the nodes to save
|
||||||
|
* @param component
|
||||||
|
*/
|
||||||
@NbBundle.Messages({
|
@NbBundle.Messages({
|
||||||
"# {0} - Output file",
|
"# {0} - Output file",
|
||||||
"ExportCSV.saveNodesToCSV.fileExists=File {0} already exists",
|
"ExportCSV.saveNodesToCSV.fileExists=File {0} already exists",
|
||||||
"ExportCSV.saveNodesToCSV.noCurrentCase=No open case available"})
|
"ExportCSV.saveNodesToCSV.noCurrentCase=No open case available",
|
||||||
|
"ExportCSV.saveNodesToCSV.empty=No data to export"})
|
||||||
public static void saveNodesToCSV(Collection<? extends Node> nodesToExport, Component component) {
|
public static void saveNodesToCSV(Collection<? extends Node> nodesToExport, Component component) {
|
||||||
|
|
||||||
if (nodesToExport.isEmpty()) {
|
if (nodesToExport.isEmpty()) {
|
||||||
|
MessageNotifyUtil.Message.info(Bundle.ExportCSV_saveNodesToCSV_empty());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Set up the file chooser with a default name and either the Export
|
||||||
|
// folder or the last used folder.
|
||||||
String fileName = getDefaultOutputFileName(nodesToExport.iterator().next().getParentNode());
|
String fileName = getDefaultOutputFileName(nodesToExport.iterator().next().getParentNode());
|
||||||
|
|
||||||
JFileChooser fileChooser = new JFileChooser();
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
fileChooser.setCurrentDirectory(new File(getExportDirectory(Case.getCurrentCaseThrows())));
|
fileChooser.setCurrentDirectory(new File(getExportDirectory(Case.getCurrentCaseThrows())));
|
||||||
fileChooser.setSelectedFile(new File(fileName));
|
fileChooser.setSelectedFile(new File(fileName));
|
||||||
@ -126,15 +131,18 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
int returnVal = fileChooser.showSaveDialog(component);
|
int returnVal = fileChooser.showSaveDialog(component);
|
||||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
|
||||||
|
// Get the file name, appending .csv if necessary
|
||||||
File selectedFile = fileChooser.getSelectedFile();
|
File selectedFile = fileChooser.getSelectedFile();
|
||||||
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
|
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
|
||||||
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
|
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the directory used for next time
|
||||||
updateExportDirectory(selectedFile.getParent(), Case.getCurrentCaseThrows());
|
updateExportDirectory(selectedFile.getParent(), Case.getCurrentCaseThrows());
|
||||||
|
|
||||||
if (selectedFile.exists()) {
|
if (selectedFile.exists()) {
|
||||||
logger.log(Level.SEVERE, "File {0} already exists", selectedFile.getAbsolutePath()); //NON-NLS
|
logger.log(Level.SEVERE, "File {0} already exists", selectedFile.getAbsolutePath()); //NON-NLS
|
||||||
MessageNotifyUtil.Message.info(Bundle.ExportCSV_actionPerformed_fileExists(selectedFile));
|
MessageNotifyUtil.Message.info(Bundle.ExportCSV_saveNodesToCSV_fileExists(selectedFile));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +150,7 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
writer.execute();
|
writer.execute();
|
||||||
}
|
}
|
||||||
} catch (NoCurrentCaseException ex) {
|
} catch (NoCurrentCaseException ex) {
|
||||||
JOptionPane.showMessageDialog(component, Bundle.ExportCSV_actionPerformed_noCurrentCase());
|
JOptionPane.showMessageDialog(component, Bundle.ExportCSV_saveNodesToCSV_noCurrentCase());
|
||||||
logger.log(Level.INFO, "Exception while getting open case.", ex); //NON-NLS
|
logger.log(Level.INFO, "Exception while getting open case.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,13 +173,10 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
String parentName = prop.getValue().toString();
|
String parentName = prop.getValue().toString();
|
||||||
|
|
||||||
// Strip off the count (if present)
|
// Strip off the count (if present)
|
||||||
System.out.println("parentName (raw) : " + parentName);
|
|
||||||
parentName = parentName.replaceAll("\\([0-9]+\\)$", "");
|
parentName = parentName.replaceAll("\\([0-9]+\\)$", "");
|
||||||
System.out.println("parentName (after paren regex) : " + parentName);
|
|
||||||
|
|
||||||
// Strip out any invalid characters
|
// Strip out any invalid characters
|
||||||
parentName = parentName.replaceAll("[\\\\/:*?\"<>|]", "_");
|
parentName = parentName.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||||
System.out.println("parentName (after char regex) : " + parentName);
|
|
||||||
|
|
||||||
return parentName + " " + dateStr;
|
return parentName + " " + dateStr;
|
||||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||||
@ -190,7 +195,7 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
*
|
*
|
||||||
* @return The export directory path.
|
* @return The export directory path.
|
||||||
*/
|
*/
|
||||||
private static String getExportDirectory(Case openCase) { // TODO sync
|
private static String getExportDirectory(Case openCase) {
|
||||||
String caseExportPath = openCase.getExportDirectory();
|
String caseExportPath = openCase.getExportDirectory();
|
||||||
|
|
||||||
if (userDefinedExportPath == null) {
|
if (userDefinedExportPath == null) {
|
||||||
@ -306,6 +311,13 @@ public final class ExportCSVAction extends AbstractAction {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert list of values to a comma separated string.
|
||||||
|
*
|
||||||
|
* @param values Values to convert
|
||||||
|
*
|
||||||
|
* @return values as CSV
|
||||||
|
*/
|
||||||
private String listToCSV(List<String> values) {
|
private String listToCSV(List<String> values) {
|
||||||
return "\"" + String.join("\",\"", values) + "\"\n";
|
return "\"" + String.join("\",\"", values) + "\"\n";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user