mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-27 06:32:10 +00:00
Merge remote-tracking branch
'origin/GP-1764-dragonmacher-csv-boolean-fix' into patch (Closes #3947, Closes #4026)
This commit is contained in:
commit
2ba866cb3f
@ -42,6 +42,10 @@ public class GBooleanCellRenderer extends GTableCellRenderer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return cb.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
superValidate();
|
||||
|
@ -77,7 +77,7 @@ public final class GTableToCSV {
|
||||
private static List<TableColumn> getVisibleColumnsInOrder(JTable table, TaskMonitor monitor) {
|
||||
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
List<TableColumn> columns = new ArrayList<TableColumn>();
|
||||
List<TableColumn> columns = new ArrayList<>();
|
||||
for (int columnIndex = 0; columnIndex < table.getColumnCount(); ++columnIndex) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
@ -92,7 +92,7 @@ public final class GTableToCSV {
|
||||
List<Integer> columnIndices) {
|
||||
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
List<TableColumn> columns = new ArrayList<TableColumn>();
|
||||
List<TableColumn> columns = new ArrayList<>();
|
||||
for (Integer index : columnIndices) {
|
||||
TableColumn column = columnModel.getColumn(index);
|
||||
columns.add(column);
|
||||
@ -163,7 +163,7 @@ public final class GTableToCSV {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get the text value for the cell so that the data will match what the user sees.
|
||||
* Attempts to get the text value for the cell so that the data will match what the user sees.
|
||||
*/
|
||||
private static String getTableCellValue(JTable table, TableModel model, int row, int column) {
|
||||
TableCellRenderer renderer = table.getCellRenderer(row, column);
|
||||
@ -174,6 +174,10 @@ public final class GTableToCSV {
|
||||
Component component =
|
||||
renderer.getTableCellRendererComponent(table, value, false, false, row, column);
|
||||
|
||||
if (isCheckBox(component)) {
|
||||
return getCheckBoxValue(component);
|
||||
}
|
||||
|
||||
if (component instanceof JLabel) {
|
||||
JLabel label = (JLabel) component;
|
||||
return getTextForLabel(label);
|
||||
@ -187,7 +191,27 @@ public final class GTableToCSV {
|
||||
return value == null ? "" : value.toString();
|
||||
}
|
||||
|
||||
private static boolean isCheckBox(Component component) {
|
||||
return component instanceof JCheckBox || component instanceof GBooleanCellRenderer;
|
||||
}
|
||||
|
||||
private static String getCheckBoxValue(Component component) {
|
||||
|
||||
if (component instanceof JCheckBox) {
|
||||
JCheckBox cb = (JCheckBox) component;
|
||||
return Boolean.toString(cb.isSelected());
|
||||
}
|
||||
|
||||
if (component instanceof GBooleanCellRenderer) {
|
||||
GBooleanCellRenderer renderer = (GBooleanCellRenderer) component;
|
||||
return Boolean.toString(renderer.isSelected());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getTextForLabel(JLabel label) {
|
||||
|
||||
String text = label.getText();
|
||||
if (text != null) {
|
||||
return text;
|
||||
@ -334,7 +358,7 @@ public final class GTableToCSV {
|
||||
private final GTable table;
|
||||
|
||||
private File file;
|
||||
private List<Integer> columns = new ArrayList<Integer>();
|
||||
private List<Integer> columns = new ArrayList<>();
|
||||
|
||||
ConvertTask(File file, GTable table) {
|
||||
super(GTableToCSV.TITLE, true, true, true);
|
||||
|
@ -28,20 +28,17 @@ import ghidra.util.task.TaskMonitor;
|
||||
public class GTableCSVTest {
|
||||
|
||||
@Test
|
||||
public void testCSV_QuotesGetEscaped() {
|
||||
public void testCsv_QuotesGetEscaped() {
|
||||
|
||||
AnyObjectTableModel<CSVRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CSVRowObject.class,
|
||||
AnyObjectTableModel<CsvRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CsvRowObject.class,
|
||||
"getName", "getDescription", "getNumber");
|
||||
|
||||
//@formatter:off
|
||||
List<CSVRowObject> data = Arrays.asList(
|
||||
new CSVRowObject("Bob", "Bobby", 11),
|
||||
new CSVRowObject("Joan", "Joan has \"quoted\" text", 0),
|
||||
new CSVRowObject("Sam", "\"Sam has a single quote text", 23),
|
||||
new CSVRowObject("Time", "Tim is last", 33)
|
||||
);
|
||||
//@formatter:on
|
||||
List<CsvRowObject> data = Arrays.asList(
|
||||
new CsvRowObject("Bob", "Bobby", 11),
|
||||
new CsvRowObject("Joan", "Joan has \"quoted\" text", 0),
|
||||
new CsvRowObject("Sam", "\"Sam has a single quote text", 23),
|
||||
new CsvRowObject("Time", "Tim is last", 33));
|
||||
model.setModelData(data);
|
||||
|
||||
GTable table = new GTable(model);
|
||||
@ -50,24 +47,21 @@ public class GTableCSVTest {
|
||||
PrintWriterSpy writer = new PrintWriterSpy();
|
||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||
|
||||
assertRowValues(data, writer);
|
||||
assertCsvRowValues(data, writer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCSV_CommasGetEscaped() {
|
||||
public void testCsv_CommasGetEscaped() {
|
||||
|
||||
AnyObjectTableModel<CSVRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CSVRowObject.class,
|
||||
AnyObjectTableModel<CsvRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CsvRowObject.class,
|
||||
"getName", "getDescription", "getNumber");
|
||||
|
||||
//@formatter:off
|
||||
List<CSVRowObject> data = Arrays.asList(
|
||||
new CSVRowObject("Bob", "Bobby", 11),
|
||||
new CSVRowObject("Joan", "Joan has a comma, in her text", 0),
|
||||
new CSVRowObject("Sam", ",Sam has a leading comma", 23),
|
||||
new CSVRowObject("Time", "Tim is last", 33)
|
||||
);
|
||||
//@formatter:on
|
||||
List<CsvRowObject> data = Arrays.asList(
|
||||
new CsvRowObject("Bob", "Bobby", 11),
|
||||
new CsvRowObject("Joan", "Joan has a comma, in her text", 0),
|
||||
new CsvRowObject("Sam", ",Sam has a leading comma", 23),
|
||||
new CsvRowObject("Time", "Tim is last", 33));
|
||||
model.setModelData(data);
|
||||
|
||||
GTable table = new GTable(model);
|
||||
@ -76,16 +70,39 @@ public class GTableCSVTest {
|
||||
PrintWriterSpy writer = new PrintWriterSpy();
|
||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||
|
||||
assertRowValues(data, writer);
|
||||
assertCsvRowValues(data, writer);
|
||||
}
|
||||
|
||||
private void assertRowValues(List<CSVRowObject> data, PrintWriterSpy writer) {
|
||||
@Test
|
||||
public void testCsv_BooleaValues() {
|
||||
|
||||
AnyObjectTableModel<BooleanCsvRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", BooleanCsvRowObject.class,
|
||||
"getName", "isSelected");
|
||||
|
||||
List<BooleanCsvRowObject> data = Arrays.asList(
|
||||
new BooleanCsvRowObject("Bob", true),
|
||||
new BooleanCsvRowObject("Joan", false),
|
||||
new BooleanCsvRowObject("Sam", false),
|
||||
new BooleanCsvRowObject("Time", true));
|
||||
model.setModelData(data);
|
||||
|
||||
GTable table = new GTable(model);
|
||||
List<Integer> columns = new ArrayList<>();
|
||||
|
||||
PrintWriterSpy writer = new PrintWriterSpy();
|
||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||
|
||||
assertBooleanCsvRowValues(data, writer);
|
||||
}
|
||||
|
||||
private void assertCsvRowValues(List<CsvRowObject> data, PrintWriterSpy writer) {
|
||||
|
||||
String results = writer.toString();
|
||||
String[] lines = results.split("\n");
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
int index = i - 1; // the first line is the header
|
||||
CSVRowObject row = data.get(index);
|
||||
CsvRowObject row = data.get(index);
|
||||
String line = lines[i];
|
||||
String[] columns = line.split("(?<!\\\\),");
|
||||
|
||||
@ -103,13 +120,32 @@ public class GTableCSVTest {
|
||||
}
|
||||
}
|
||||
|
||||
class CSVRowObject {
|
||||
private void assertBooleanCsvRowValues(List<BooleanCsvRowObject> data, PrintWriterSpy writer) {
|
||||
|
||||
String results = writer.toString();
|
||||
String[] lines = results.split("\n");
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
int index = i - 1; // the first line is the header
|
||||
BooleanCsvRowObject row = data.get(index);
|
||||
String line = lines[i];
|
||||
String[] columns = line.split("(?<!\\\\),");
|
||||
|
||||
String name = columns[0].replaceAll("\\\\,", ",");
|
||||
name = name.replaceAll("\\\\\"", "\"");
|
||||
assertEquals("\"" + row.getName() + "\"", name);
|
||||
|
||||
String isSelected = columns[1];
|
||||
assertEquals("\"" + row.isSelected() + "\"", isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
class CsvRowObject {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private int number;
|
||||
|
||||
CSVRowObject(String name, String description, int number) {
|
||||
CsvRowObject(String name, String description, int number) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.number = number;
|
||||
@ -128,6 +164,25 @@ public class GTableCSVTest {
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanCsvRowObject {
|
||||
|
||||
private String name;
|
||||
private boolean isSelected;
|
||||
|
||||
BooleanCsvRowObject(String name, boolean isSelected) {
|
||||
this.name = name;
|
||||
this.isSelected = isSelected;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
}
|
||||
|
||||
private class PrintWriterSpy extends PrintWriter {
|
||||
|
||||
private StringWriter stringWriter;
|
||||
|
Loading…
Reference in New Issue
Block a user