Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ updates:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: org.glassfish.jaxb:jaxb-runtime
versions:
- ">=4.0.6"
- dependency-name: org.owasp:dependency-check-maven
versions:
- 6.1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Class to build export template from a file.
Expand All @@ -57,6 +56,7 @@ public class ExportTemplateBuilder {
private static final String OPENING_BRACKET = "(";
private static final String CLOSING_BRACKET = ")";
private static final String DATA_COLUMN_PREFIX = "$";
private static final String COMMENT_PREFIX = "//";

/**
* The entry point into building an ExportTemplate object by reading a template file.
Expand All @@ -70,7 +70,10 @@ public ExportTemplate buildExportTemplate(String pathToTemplate) {

List<String> templateLines;
try {
templateLines = Files.readAllLines(Paths.get(pathToTemplate));
templateLines = Files.readAllLines(Paths.get(pathToTemplate)).stream().filter(line -> {
String trimmedLine = line.trim();
return !trimmedLine.isEmpty() && !trimmedLine.startsWith(COMMENT_PREFIX);
}).toList();
Map<Integer, ExportTemplateColumnDef> columnMap = buildColumnMap(templateLines);
return new ExportTemplateImpl(columnMap);
} catch (IOException e) {
Expand All @@ -79,23 +82,23 @@ public ExportTemplate buildExportTemplate(String pathToTemplate) {
}

private Map<Integer, ExportTemplateColumnDef> buildColumnMap(List<String> templateLines) {
if ((templateLines == null) || (templateLines.size() == 0)) {
if ((templateLines == null) || (templateLines.isEmpty())) {
throw new ExportTemplateParseException("Export template is empty");
}
String versionLine = templateLines.get(0);
String versionLine = templateLines.getFirst();
String version = parseVersionLine(versionLine);

//we have only one version at the moment, but future provision for versioning
switch (version) {
case "1.0":
case "1.0" -> {
return parseExportTemplateV1(templateLines.subList(1, templateLines.size()));
default:
throw new ExportTemplateParseException("Unsupported version for the export template");
}
default -> throw new ExportTemplateParseException("Unsupported version for the export template");
}
}

private Map<Integer, ExportTemplateColumnDef> parseExportTemplateV1(List<String> templateLines) {
List<String> columnLines = templateLines.stream().filter(line -> line.trim().length() > 0).collect(Collectors.toList());
List<String> columnLines = templateLines.stream().filter(line -> !line.trim().isEmpty()).toList();
Map<Integer, ExportTemplateColumnDef> columnMap = new HashMap<>();
for (int i = 0; i < columnLines.size(); i++) {
String line = columnLines.get(i);
Expand Down Expand Up @@ -123,11 +126,11 @@ private Map<Integer, ExportTemplateColumnDef> parseExportTemplateV1(List<String>
private boolean isExpressionForDataModification(String expressionParam) {
List<String> operations = Arrays.stream(
ExportTemplateColumnDef.DataModification.values()).map(v -> v.toString() + OPENING_BRACKET).
collect(Collectors.toList());
toList();
String expression = expressionParam.trim();

List<String> possibleOperations = operations.stream().filter(op -> expression.startsWith(op)).collect(Collectors.toList());
return possibleOperations.size() > 0;
List<String> possibleOperations = operations.stream().filter(expression::startsWith).toList();
return !possibleOperations.isEmpty();
}

private ExportTemplateColumnDef createDataModifierDef(String header, String param2) {
Expand All @@ -138,8 +141,7 @@ private ExportTemplateColumnDef createDataModifierDef(String header, String para
String operationName = tokens[0].trim();

List<String> operations = Arrays.stream(
ExportTemplateColumnDef.DataModification.values()).map(v -> v.toString()).
collect(Collectors.toList());
ExportTemplateColumnDef.DataModification.values()).map(Enum::toString).toList();

if (!operations.contains(operationName)) {
throw new ExportTemplateParseException("Undefined operation '" + operationName + "' encountered in export template");
Expand Down Expand Up @@ -192,7 +194,7 @@ private ProfileResourceNodeColumnDef createProfileNodeDef(String header, String
throw new ExportTemplateParseException(String.format(messageFormat, param2));
}
String originalColumnName = param2.substring(1);
if (!(Arrays.stream(WriterConstants.HEADERS).collect(Collectors.toList()).contains(originalColumnName))) {
if (!Arrays.asList(WriterConstants.HEADERS).contains(originalColumnName)) {
throw new ExportTemplateParseException(String.format(messageFormat, originalColumnName));
}
return new ProfileResourceNodeColumnDef(originalColumnName, header);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,43 @@ public void should_throw_an_exception_when_a_column_name_is_not_prefixed_with_do
ExportTemplateParseException ex = assertThrows(ExportTemplateParseException.class, () -> builder.buildExportTemplate(tempFile.getAbsolutePath()));
assertEquals("Invalid syntax in data modifier expression 'LCASE(PUID)', expecting '$' after '('", ex.getMessage());
}

@Test
public void should_remove_comment_lines_from_the_template_when_multiple_comment_lines_at_the_beginning() throws IOException {
ExportTemplateBuilder builder = new ExportTemplateBuilder();
File tempFile = temporaryFolder.newFile("comments-at-the-beginning");
List<String> data = Arrays.asList(
"// This is a comment about the file",
"// Which can explain the use of template",
" // and some where the line begins with blank space before the comment prefix",
"version 1.0",
"Identifier: $ID",
"");
Files.write(tempFile.toPath(), data, StandardOpenOption.WRITE);
ExportTemplate template = builder.buildExportTemplate(tempFile.getAbsolutePath());
assertNotNull(template);
assertEquals(1, template.getColumnOrderMap().size());
assertEquals("Identifier",template.getColumnOrderMap().get(0).getHeaderLabel());
}

@Test
public void should_remove_comment_lines_and_blank_from_the_template_when_comment_lines_are_in_between_the_lines() throws IOException {
ExportTemplateBuilder builder = new ExportTemplateBuilder();
File tempFile = temporaryFolder.newFile("comments-at-the-beginning");
List<String> data = Arrays.asList(
"// This is a comment about the file",
"// Which can explain the use of template and add information such as ",
"",
"// Created on: 18-MAR-2020 by Dr. O. I. Dean (aka Droidean)",
"version 1.0",
"// Changing the 'ID' column to be called 'Identifier'",
"Identifier: $ID",
"",
" // Add a string column in the template",
"Language: \"English\" ",
"");
Files.write(tempFile.toPath(), data, StandardOpenOption.WRITE);
ExportTemplate template = builder.buildExportTemplate(tempFile.getAbsolutePath());
assertNotNull(template);
}
}
39 changes: 27 additions & 12 deletions droid-help/src/main/resources/pages/export.html
Original file line number Diff line number Diff line change
Expand Up @@ -454,12 +454,10 @@ <h2 class="tna-heading-m" id="predefined-template-for-export">Export Templates</
<p>
An export template is a simple text file, with a .template extension, which defines customisations of
columns to be exported. Using a template, you can customise headers for the data columns, add new
columns
to the export, convert the data in a column to be uppercase / lowercase and change the order in which
columns
appear in the export. You can make an export template available to Droid by copying it into the
<code>.droid6\export_templates</code> folder. You can customise the columns listed in the <a
href="#csv-file-columns">CSV Columns</a> section.
columns to the export, convert the data in a column to be uppercase / lowercase and change the order
in which columns appear in the export. You can make an export template available to Droid by copying
it into the <code>.droid6\export_templates</code> folder. You can customise the columns listed in
the <a href="#csv-file-columns">CSV Columns</a> section.
</p>
<h3 class="tna-heading-s" id="export-template-features">Features</h3>
<p>The current syntax for the export template is referred to as version 1.0. This version of the export
Expand All @@ -472,11 +470,16 @@ <h3 class="tna-heading-s" id="export-template-features">Features</h3>
</ul>
<h3 class="tna-heading-s" id="export-template-syntax">Syntax</h3>
<p>Syntactically, the export template is simple to define. The details for defining various customisations
are explained below.</p>
are explained below.</p>
<ul class="tna-ul">
<li>
<b>version line</b>: The very first line of the Export Template defines the version number. For now
it simply needs to be version 1.0
<b>Comment line</b>: The export template allows for comments to be added in the file. Any line that
begins with <code>//</code> is treated as a comment and it is ignored for column customisations.
Please note, Droid only supports single line comments as of the current version
</li>
<li>
<b>Version line</b>: The very first non-comment line of the Export Template defines the version
number. For now it simply needs to be <code>version 1.0</code>
</li>
<li>
<b>Modifying a header</b>: If you intend to use a different column header instead of one of the
Expand Down Expand Up @@ -514,19 +517,30 @@ <h3 class="tna-heading-s" id="export-template-syntax">Syntax</h3>
</ul>
<h3 class="tna-heading-s" id="export-template-putting-it-all-together">Putting it all together</h3>
<p>Consider the following template</p>
<pre class="notranslate"><code>version 1.0
<pre class="notranslate"><code>
// The following customisations are an example of how an export template can be used
// It defines a template version and customisations
//
// Created on: 21-SEP-2024

version 1.0
Identifier: $ID
Name: $NAME
LowerName: LCASE($NAME)
Language: "Simplified English"
Submitter: "Government Dept."

// Following column is added to the export but not populated
Background:
FormatName: $FORMAT_NAME
FormatVersion: $FORMAT_VERSION
Export Tool:
</code></pre>
<p>It indicates the following:</p>
<ul class="tna-ul">
<li>
<p>Initial few lines describe the template using comments</p>
</li>
<li>
<p>The version of the template is 1.0</p>
</li>
Expand Down Expand Up @@ -631,8 +645,9 @@ <h3 class="tna-heading-m" id="other-options">Other options</h3>
to the encoding used on your local machine instead, select 'Platform specific' instead.
</p>
<p>
When you are happy you want to export your profiles, press the <code>profiles...</code> button. This will bring up a standard file-save
dialog, in which you can specify where you want your CSV file to be saved.
When you are happy you want to export your profiles, press the <code>Export profiles...</code>
button. This will bring up a standard file-save dialog, in which you can specify where you want
your CSV file to be saved.
</p>
</section>
<section class="tna-section">
Expand Down
2 changes: 1 addition & 1 deletion droid-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
<derby.version>10.17.1.0</derby.version>
<cxf.version>4.1.3</cxf.version>
<java.iso-tools.version>2.1.0</java.iso-tools.version>
<jaxb.version>4.0.6</jaxb.version>
<jaxb.version>4.0.5</jaxb.version>
<jakarta.version>4.0.4</jakarta.version>
<jackson.version>2.19.2</jackson.version>
<flying-saucer.version>9.7.2</flying-saucer.version>
Expand Down
Loading