This is an automated email from the ASF dual-hosted git repository.

sgoeschl pushed a commit to branch FREEMARKER-199
in repository https://gitbox.apache.org/repos/asf/freemarker-generator.git


The following commit(s) were added to refs/heads/FREEMARKER-199 by this push:
     new 8b5287a  FREEMARKER-199 [freemarker-generator] Add "utah-parser-tool"
8b5287a is described below

commit 8b5287a208ef375776050d3e5e731936ae3d00fd
Author: Siegfried Goeschl <[email protected]>
AuthorDate: Sat Oct 23 11:19:00 2021 +0200

    FREEMARKER-199 [freemarker-generator] Add "utah-parser-tool"
---
 .../generator/base/datasource/DataSources.java     | 17 +++++++-
 .../generator/datasource/DataSourcesTest.java      | 33 +++++++++++++-
 .../src/app/examples/data/nginx/test1-api.nginx    | 30 +++++++++++++
 .../examples/data/nginx/test1-application.nginx    | 27 ++++++++++++
 .../utahparser/juniper_bgp_summary_template.xml    | 18 +++++++-
 .../nginx/confluence/nginx-config-parser.ftl       | 34 +++++++++++++++
 .../utahparser/csv/transform-streaming.ftl         | 34 ---------------
 .../src/app/scripts/run-examples.bat               | 10 +++++
 .../src/app/scripts/run-examples.sh                | 10 +++++
 .../app/templates/freemarker-generator/info.ftl    |  1 -
 .../freemarker/generator/cli/ManualTest.java       |  2 +-
 .../generator/tools/utahparser/UtahParserTool.java | 51 +++++++++++++++-------
 .../tools/utahparser/impl/ParserWrapper.java       |  8 +++-
 .../tools/utahparser/UtahParserToolTest.java       | 41 +++++++++++++++--
 14 files changed, 256 insertions(+), 60 deletions(-)

diff --git 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
index 31a6462..7762c41 100644
--- 
a/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
+++ 
b/freemarker-generator-base/src/main/java/org/apache/freemarker/generator/base/datasource/DataSources.java
@@ -27,6 +27,8 @@ import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static java.util.function.Function.identity;
@@ -180,7 +182,7 @@ public class DataSources implements Closeable {
     }
 
     /**
-     * Find data sources based on their metadata key and wildcard string.
+     * Find <code>DataSources</code> based on their metadata key and wildcard 
string.
      *
      * @param key      metadata key to match
      * @param wildcard the wildcard string to match against
@@ -206,6 +208,19 @@ public class DataSources implements Closeable {
         return new DataSources(find(key, wildcard));
     }
 
+    /**
+     * Group the <code>DataSources</code> by a metadata value.
+     * @param key metadata key to group by
+     * @return groups of <code>DataSources</code>
+     */
+    public Map<String, DataSources> groupingBy(String key) {
+        final Function<DataSource, String> metadataFunction = dataSource -> 
dataSource.getMetadata(key);
+        return dataSources.stream()
+                .collect(Collectors.groupingBy(metadataFunction))
+                .entrySet().stream()
+                .collect(Collectors.toMap(Entry::getKey, p -> new 
DataSources(p.getValue())));
+    }
+
     @Override
     public void close() {
         dataSources.forEach(ClosableUtils::closeQuietly);
diff --git 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
index 4bdf193..9885a81 100644
--- 
a/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
+++ 
b/freemarker-generator-base/src/test/java/org/apache/freemarker/generator/datasource/DataSourcesTest.java
@@ -25,6 +25,7 @@ import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
+import java.util.Map;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Arrays.asList;
@@ -119,6 +120,36 @@ public class DataSourcesTest {
         assertEquals(singletonList(DEFAULT_GROUP), dataSources().getGroups());
     }
 
+    @Test
+    public void shouldSupportGroupingByMetadata() {
+        try (DataSources dataSources = dataSources()) {
+            final Map<String, DataSources> map = 
dataSources.groupingBy("mimeType");
+
+            assertEquals(2, map.size());
+            assertEquals(1, map.get("application/xml").size());
+            assertEquals(2, map.get("text/plain").size());
+        }
+    }
+
+    @Test
+    public void shouldSupportFilteringByMetadata() {
+        try (DataSources dataSources = dataSources().filter("mimeType", 
"text/plain")) {
+            assertEquals(2, dataSources.size());
+            assertEquals("text/plain", dataSources.get(0).getMimeType());
+            assertEquals("text/plain", dataSources.get(1).getMimeType());
+        }
+
+        try (DataSources dataSources = dataSources().filter("mimeType", 
"application/xml")) {
+            assertEquals(1, dataSources.size());
+            assertEquals("application/xml", dataSources.get(0).getMimeType());
+        }
+
+        try (DataSources dataSources = dataSources().filter("mimeType", 
"!text/plain")) {
+            assertEquals(1, dataSources.size());
+            assertEquals("application/xml", dataSources.get(0).getMimeType());
+        }
+    }
+
     @Test(expected = IllegalArgumentException.class)
     public void shouldThrowExceptionWhenGetDoesNotFindDataSource() {
         dataSources().get("file-does-not-exist");
@@ -142,7 +173,7 @@ public class DataSourcesTest {
     }
 
     private static DataSource urlDataSource() {
-        return DataSourceFactory.fromUrl("server.invalid?foo=bar", "default", 
toUrl(ANY_URL), "plain/text", UTF_8, new HashMap<>());
+        return DataSourceFactory.fromUrl("server.invalid?foo=bar", "default", 
toUrl(ANY_URL), "text/plain", UTF_8, new HashMap<>());
     }
 
     private static URL toUrl(String value) {
diff --git 
a/freemarker-generator-cli/src/app/examples/data/nginx/test1-api.nginx 
b/freemarker-generator-cli/src/app/examples/data/nginx/test1-api.nginx
new file mode 100644
index 0000000..2c2486f
--- /dev/null
+++ b/freemarker-generator-cli/src/app/examples/data/nginx/test1-api.nginx
@@ -0,0 +1,30 @@
+server {
+  listen               443 ssl;
+  server_name          test1-api.company.org;
+
+  access_log           /var/log/nginx/test1-api.access.log;
+  error_log            /var/log/nginx/test1-api.error.log;
+
+  ssl_certificate      /etc/nginx/ssl/wildcard.company.org-public.crt;
+  ssl_certificate_key  /etc/nginx/ssl/wildcard.company.org-private.rsa;
+
+  include              /etc/nginx/includes/FLKPMM.nginx;
+
+  proxy_buffers        16 64k;
+  proxy_buffer_size    128k;
+  proxy_next_upstream  error timeout invalid_header http_500 http_502 http_503 
http_504;
+  proxy_redirect       off;
+  proxy_set_header     Host              $host;
+  proxy_set_header     X-Real-IP         $remote_addr;
+  proxy_set_header     X-Forwarded-For   $proxy_add_x_forwarded_for;
+  proxy_set_header     X-Forwarded-Proto https;
+  proxy_set_header     X-TPP-QWAC        $ssl_client_cert;
+
+  ssl_verify_client    optional_no_ca;
+
+
+  location / {
+    return 403;
+  }
+
+}
diff --git 
a/freemarker-generator-cli/src/app/examples/data/nginx/test1-application.nginx 
b/freemarker-generator-cli/src/app/examples/data/nginx/test1-application.nginx
new file mode 100644
index 0000000..b618991
--- /dev/null
+++ 
b/freemarker-generator-cli/src/app/examples/data/nginx/test1-application.nginx
@@ -0,0 +1,27 @@
+server {
+  listen 443 ssl;
+  server_name test1-application.company.org;
+
+  access_log /var/log/nginx/test1-application.access.log;
+  error_log /var/log/nginx/test1-application.error.log;
+
+  ssl_certificate /etc/nginx/ssl/wildcard.company.org-public.crt;
+  ssl_certificate_key /etc/nginx/ssl/wildcard.company.org-private.rsa;
+
+  proxy_buffers 16 64k;
+  proxy_buffer_size 128k;
+
+  location / {
+    proxy_pass https://osroutercpssl/;
+    proxy_next_upstream error timeout invalid_header http_500 http_502 
http_503 http_504;
+    proxy_redirect off;
+
+    proxy_set_header    Host              $host;
+    proxy_set_header    X-Real-IP         $remote_addr;
+    proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
+    proxy_set_header    X-Forwarded-Proto https;
+  }
+
+}
+
+
diff --git 
a/freemarker-generator-cli/src/app/examples/data/text/utahparser/juniper_bgp_summary_template.xml
 
b/freemarker-generator-cli/src/app/examples/data/text/utahparser/juniper_bgp_summary_template.xml
index bb1093a..76084aa 100644
--- 
a/freemarker-generator-cli/src/app/examples/data/text/utahparser/juniper_bgp_summary_template.xml
+++ 
b/freemarker-generator-cli/src/app/examples/data/text/utahparser/juniper_bgp_summary_template.xml
@@ -1,11 +1,25 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
 <config>
     <searches>
 
         <!-- in this case, we have a CSV (space delimited file) so we define 
the line once, and then reuse it over
         and again for each value -->
         <search 
id="QUERY-LINE"><![CDATA[\s*{ipAddress}\s+{numbers}\s+{numbers}\s+{numbers}\s+{numbers}\s+{numbers}\s+{numbersThenText}]]></search>
-
-
         <search id="inetInline"><![CDATA[{inet} {inet}]]></search>
         <search id="inet4"><![CDATA[inet.0:\s*{inet}]]></search>
         <search id="inet6"><![CDATA[inet6.0:\s*{inet}]]></search>
diff --git 
a/freemarker-generator-cli/src/app/examples/templates/nginx/confluence/nginx-config-parser.ftl
 
b/freemarker-generator-cli/src/app/examples/templates/nginx/confluence/nginx-config-parser.ftl
new file mode 100644
index 0000000..79331a5
--- /dev/null
+++ 
b/freemarker-generator-cli/src/app/examples/templates/nginx/confluence/nginx-config-parser.ftl
@@ -0,0 +1,34 @@
+<#compress>
+    || FILE || SERVER || ACCESSLOG || SPLUNK ||
+    <#list dataSources as dataSource>
+        <#assign fileName = dataSource.fileName>
+        <#assign serverName = "N.A">
+        <#-- Transform to a single line to avoid matching OS-specific line 
endings -->
+        <#assign text = dataSource.getText()?replace("\r", "")?replace("\n", " 
")>
+        <#assign accessLog = getAccessLog(text)>
+        <#assign serverName = getServerName(text)>
+        | ${fileName} | ${serverName} | ${accessLog} | 
[${splunkSearchUrl(accessLog)}] |
+    </#list>
+</#compress>
+<#--------------------------------------------------------------------------->
+<#function splunkSearchUrl accessLog>
+    <#return 
"https://splunk.p.santanderconsumer.at/en-US/app/scbdevteam/search?q=search%20source%3D%22${accessLog?url}%22";>
+</#function>
+<#--------------------------------------------------------------------------->
+<#function getAccessLog text>
+    <#assign matches = text?matches(r".*access_log\s*([\w\.\-\/\\]*);.*")>
+    <#if matches>
+        <#return matches?groups[1]?trim>
+    <#else>
+        <#return "N.A.">
+    </#if>
+</#function>
+<#--------------------------------------------------------------------------->
+<#function getServerName text>
+    <#assign matches = text?matches(r".*server_name\s*([\w\.\-\\]*);.*")>
+    <#if matches>
+        <#return matches?groups[1]?trim>
+    <#else>
+        <#return "N.A.">
+    </#if>
+</#function>
\ No newline at end of file
diff --git 
a/freemarker-generator-cli/src/app/examples/templates/utahparser/csv/transform-streaming.ftl
 
b/freemarker-generator-cli/src/app/examples/templates/utahparser/csv/transform-streaming.ftl
deleted file mode 100644
index ebb2829..0000000
--- 
a/freemarker-generator-cli/src/app/examples/templates/utahparser/csv/transform-streaming.ftl
+++ /dev/null
@@ -1,34 +0,0 @@
-<#--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you 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.
--->
-<#-- Setup Utah-Parser -->
-<#assign conf =  tools.utahparser.getConfig(dataSources[0])>
-<#assign parser = tools.utahparser.getParser(conf, dataSources[1])>
-<#assign csvPrinter = "">
-<#-- Print records as CSV  -->
-<#compress>
-    <#list parser.iterator() as record>
-        <#if !csvPrinter?has_content>
-            <#-- Lazy creation of a CSVFormat for writing the records -->
-            <#assign defaultCsvformat = 
tools.csv.formats[CSV_TARGET_FORMAT!"DEFAULT"]>
-            <#assign delimiter = 
tools.csv.toDelimiter(CSV_TARGET_DELIMITER!defaultCsvformat.getDelimiter())>
-            <#assign csvHeaders = tools.utahparser.getHeaders(record)>
-            <#assign cvsFormat = 
defaultCsvformat.withHeader(csvHeaders).withDelimiter(delimiter)>
-            <#assign csvPrinter = tools.csv.printer(cvsFormat)>
-        </#if>
-        ${csvPrinter.printRecord(record, csvHeaders)}
-    </#list>
-</#compress>
diff --git a/freemarker-generator-cli/src/app/scripts/run-examples.bat 
b/freemarker-generator-cli/src/app/scripts/run-examples.bat
index 551b5c1..cfb7a33 100644
--- a/freemarker-generator-cli/src/app/scripts/run-examples.bat
+++ b/freemarker-generator-cli/src/app/scripts/run-examples.bat
@@ -176,6 +176,16 @@ echo "examples\data\template"
 %FREEMARKER_CMD% -t examples\data\template -PNGINX_HOSTNAME=localhost -o 
target\out\template
 
 REM =========================================================================
+REM Utah Parser
+REM =========================================================================
+
+echo "examples\templates\utahparser\csv\transform.ftl"
+%FREEMARKER_CMD% -PCSV_TARGET_FORMAT=EXCEL -PCSV_TARGET_DELIMITER=SEMICOLON -t 
examples\templates\utahparser\csv\transform.ftl 
examples\data\text\utahparser\juniper_bgp_summary_template.xml 
examples\data\text\utahparser\juniper_bgp_summary_example.txt -o 
target\out\utahparserjuniper_bgp_summary_example.csv
+
+echo "examples\templates\utahparser\json\transform.ftl"
+%FREEMARKER_CMD% -t examples\templates\utahparser\json\transform.ftl 
examples\data\text\utahparser\juniper_bgp_summary_template.xml 
examples\data\text\utahparser\juniper_bgp_summary_example.txt -o 
target\out\utahparser\uniper_bgp_summary_example.json
+
+REM =========================================================================
 REM XML
 REM =========================================================================
 
diff --git a/freemarker-generator-cli/src/app/scripts/run-examples.sh 
b/freemarker-generator-cli/src/app/scripts/run-examples.sh
index 979f0b1..c034789 100755
--- a/freemarker-generator-cli/src/app/scripts/run-examples.sh
+++ b/freemarker-generator-cli/src/app/scripts/run-examples.sh
@@ -197,6 +197,16 @@ echo "examples/data/template"
 $FREEMARKER_CMD -t examples/data/template -PNGINX_HOSTNAME=localhost -o 
target/out/template  || { echo >&2 "Test failed.  Aborting."; exit 1; }
 
 #############################################################################
+# Utah Parser
+#############################################################################
+
+echo "examples/templates/utahparser/csv/transform.ftl"
+$FREEMARKER_CMD -PCSV_TARGET_FORMAT=EXCEL -PCSV_TARGET_DELIMITER=SEMICOLON -t 
examples/templates/utahparser/csv/transform.ftl 
examples/data/text/utahparser/juniper_bgp_summary_template.xml 
examples/data/text/utahparser/juniper_bgp_summary_example.txt -o 
target/out/utahparserjuniper_bgp_summary_example.csv || { echo >&2 "Test 
failed.  Aborting."; exit 1; }
+
+echo "examples/templates/utahparser/json/transform.ftl"
+$FREEMARKER_CMD -t examples/templates/utahparser/json/transform.ftl 
examples/data/text/utahparser/juniper_bgp_summary_template.xml 
examples/data/text/utahparser/juniper_bgp_summary_example.txt -o 
target/out/utahparser/juniper_bgp_summary_example.json || { echo >&2 "Test 
failed.  Aborting."; exit 1; }
+
+#############################################################################
 # XML
 #############################################################################
 
diff --git 
a/freemarker-generator-cli/src/app/templates/freemarker-generator/info.ftl 
b/freemarker-generator-cli/src/app/templates/freemarker-generator/info.ftl
index d5725d0..0a3f0ce 100644
--- a/freemarker-generator-cli/src/app/templates/freemarker-generator/info.ftl
+++ b/freemarker-generator-cli/src/app/templates/freemarker-generator/info.ftl
@@ -60,7 +60,6 @@ contentType           : ${dataSource.contentType}
 fileName              : ${dataSource.fileName}
 baseName              : ${dataSource.baseName}
 extension             : ${dataSource.extension}
-extension             : ${dataSource.extension}
 relativeFilePath      : ${dataSource.relativeFilePath}
 charset               : ${dataSource.charset}
 mimeType              : ${dataSource.mimeType}
diff --git 
a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
 
b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
index 2f1596b..2f1dd69 100644
--- 
a/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
+++ 
b/freemarker-generator-cli/src/test/java/org/apache/freemarker/generator/cli/ManualTest.java
@@ -25,7 +25,7 @@ public class ManualTest extends AbstractMainTest {
 
     // private static final String CMD = "-V";
     private static final String CMD =
-            "-t src/app/examples/templates/datasources.ftl 
readme:documentation=README.md src/main/assembly";
+            "-t 
src/app/examples/templates/nginx/confluence/nginx-config-parser.ftl -s 
src/app/examples/data/nginx";
             // "-t src/app/examples/templates/datasources.ftl";
 
     @Override
diff --git 
a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/UtahParserTool.java
 
b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/UtahParserTool.java
index 0da3491..82520ef 100644
--- 
a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/UtahParserTool.java
+++ 
b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/UtahParserTool.java
@@ -26,47 +26,68 @@ import 
org.apache.freemarker.generator.tools.utahparser.impl.ParserWrapper;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
 import java.util.stream.Collectors;
 
 public class UtahParserTool {
 
+    /**
+     * Create a Utah Parser config based on the given source.
+     *
+     * @param source source of configuration file
+     * @return config instance
+     */
     public Config getConfig(String source) {
-        return this.getConfig(DataSourceLoaderFactory.create().load(source));
+        return getConfig(DataSourceLoaderFactory.create().load(source));
     }
 
+    /**
+     * Create a Utah Parser config based on teh textual content of the data 
source,
+     *
+     * @param dataSource XML configuration file
+     * @return config instance
+     */
     public Config getConfig(DataSource dataSource) {
         try (InputStream is = dataSource.getUnsafeInputStream()) {
             return loadConfig(is);
-        } catch (IOException var16) {
-            throw new RuntimeException("Failed to load parser configuration: " 
+ dataSource, var16);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to load parser configuration: " 
+ dataSource, e);
         }
     }
 
+    /**
+     * Create a parser instance.
+     *
+     * @param config     configuration
+     * @param dataSource data source to be parsed
+     * @return parser
+     */
     public ParserWrapper getParser(Config config, DataSource dataSource) {
         final InputStreamReader is = new 
InputStreamReader(dataSource.getInputStream());
-        return new ParserWrapper(Parser.parse(config, is));
+        final Parser parser = Parser.parse(config, is);
+        return new ParserWrapper(parser);
     }
 
-    public String[] getHeaders(Map<String, Object> map) {
-        final Set<String> keySet = map.keySet();
-        return keySet.toArray(new String[0]);
+    public List<String> getHeaders(Map<String, Object> record) {
+        if (record == null || record.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        return new ArrayList<>(record.keySet());
     }
 
-    public Set<String> getHeaders(Collection<Map<String, String>> records) {
+    public List<String> getHeaders(Collection<Map<String, String>> records) {
         if (records == null || records.isEmpty()) {
-            return Collections.emptySet();
+            return Collections.emptyList();
         }
 
         return records.stream()
-                .map(record -> record.keySet())
-                .flatMap(Collection::stream)
-                .collect(Collectors.toCollection(() -> new TreeSet<>())
-                );
+                .map(Map::keySet)
+                
.flatMap(Collection::stream).distinct().sorted().collect(Collectors.toList());
     }
 
     public String toString() {
diff --git 
a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/impl/ParserWrapper.java
 
b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/impl/ParserWrapper.java
index 585f8f8..9aad9bc 100644
--- 
a/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/impl/ParserWrapper.java
+++ 
b/freemarker-generator-tools/src/main/java/org/apache/freemarker/generator/tools/utahparser/impl/ParserWrapper.java
@@ -28,7 +28,7 @@ import static java.util.Objects.requireNonNull;
 
 /**
  * Wraps the <code>com.sonalake.utah.Parser</code> to provide convenience
- * methods such support of iterators.
+ * methods such as support of iterators.
  */
 public class ParserWrapper implements Iterable<Map<String, String>> {
 
@@ -44,6 +44,11 @@ public class ParserWrapper implements Iterable<Map<String, 
String>> {
         return new RecordsIterator(parser);
     }
 
+    /**
+     * Iterates over all records and return a list.
+     *
+     * @return list of records
+     */
     public List<Map<String, String>> toList() {
         final List<Map<String, String>> result = new ArrayList<>();
         for (Map<String, String> record : this) {
@@ -57,7 +62,6 @@ public class ParserWrapper implements Iterable<Map<String, 
String>> {
         private final Parser parser;
         private Map<String, String> nextRecord;
 
-        // constructor
         RecordsIterator(Parser parser) {
             this.parser = requireNonNull(parser);
             this.nextRecord = parser.next();
diff --git 
a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/utahparser/UtahParserToolTest.java
 
b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/utahparser/UtahParserToolTest.java
index 4e742bb..fac9e75 100644
--- 
a/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/utahparser/UtahParserToolTest.java
+++ 
b/freemarker-generator-tools/src/test/java/org/apache/freemarker/generator/tools/utahparser/UtahParserToolTest.java
@@ -3,10 +3,13 @@ package org.apache.freemarker.generator.tools.utahparser;
 import com.sonalake.utah.config.Config;
 import org.apache.freemarker.generator.base.datasource.DataSource;
 import org.apache.freemarker.generator.base.datasource.DataSourceFactory;
+import org.apache.freemarker.generator.base.util.MapBuilder;
 import org.apache.freemarker.generator.tools.utahparser.impl.ParserWrapper;
 import org.junit.Test;
 
 import java.io.File;
+import java.util.List;
+import java.util.Map;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static junit.framework.TestCase.assertEquals;
@@ -15,8 +18,8 @@ import static junit.framework.TestCase.assertTrue;
 
 public class UtahParserToolTest {
 
-    private final static String EXAMPLE_FILE_NAME = 
"src/test/data/utahparser/juniper_bgp_summary_example.txt";
-    private final static String TEMPLATE_FILE_NAME = 
"src/test/data/utahparser/juniper_bgp_summary_template.xml";
+    private static final String EXAMPLE_FILE_NAME = 
"src/test/data/utahparser/juniper_bgp_summary_example.txt";
+    private static final String TEMPLATE_FILE_NAME = 
"src/test/data/utahparser/juniper_bgp_summary_template.xml";
 
     @Test
 
@@ -53,8 +56,40 @@ public class UtahParserToolTest {
         final UtahParserTool utahParserTool = utahParserTool();
         final Config config = utahParserTool.getConfig(TEMPLATE_FILE_NAME);
         final ParserWrapper parser = utahParserTool.getParser(config, 
dataSource);
+        final List<Map<String, String>> records = parser.toList();
 
-        assertEquals(3, parser.toList().size());
+        assertEquals(3, records.size());
+    }
+
+    @Test
+    public void shallGetHeadersFromRecord() {
+        final UtahParserTool utahParserTool = utahParserTool();
+        final Map<String, Object> record = MapBuilder.toLinkedMap("header1", 
"foo", "header2", "bar");
+
+        final List<String> headers = utahParserTool.getHeaders(record);
+
+        assertEquals("header1", headers.get(0));
+        assertEquals("header2", headers.get(1));
+    }
+
+    @Test
+    public void shallGetHeadersFromRecords() {
+        final DataSource dataSource = dataSource(EXAMPLE_FILE_NAME);
+        final UtahParserTool utahParserTool = utahParserTool();
+        final Config config = utahParserTool.getConfig(TEMPLATE_FILE_NAME);
+        final ParserWrapper parser = utahParserTool.getParser(config, 
dataSource);
+        final List<Map<String, String>> records = parser.toList();
+
+        final List<String> headers = utahParserTool.getHeaders(records);
+
+        assertEquals("accepted_V4", headers.get(0));
+        assertEquals("accepted_V6", headers.get(1));
+        assertEquals("activeV4", headers.get(2));
+        assertEquals("activeV6", headers.get(3));
+        assertEquals("receivedV4", headers.get(4));
+        assertEquals("receivedV6", headers.get(5));
+        assertEquals("remoteIp", headers.get(6));
+        assertEquals("uptime", headers.get(7));
     }
 
     private static UtahParserTool utahParserTool() {

Reply via email to