From bcb4e914d6e54090dbaafda30b6141fc3b0ea2f0 Mon Sep 17 00:00:00 2001 From: "ROUSSY Christophe (OP-EXT)" Date: Thu, 28 Apr 2022 12:51:36 +0200 Subject: [PATCH] TEDEFO-760 first cleanup pass, renamed some variables, changes in JavaDoc, better tests, removed a file. --- .mvn/wrapper/MavenWrapperDownloader.java | 180 ++++---- README.md | 23 +- pom.xml | 46 ++ .../europa/ted/eforms/viewer/Application.java | 9 +- .../ted/eforms/viewer/CustomUriResolver.java | 19 +- .../ted/eforms/viewer/NoticeViewer.java | 24 +- .../ted/eforms/viewer/SdkSymbolResolver.java | 5 +- .../ted/eforms/viewer/XsltRenderer.java | 68 +-- .../eforms/viewer/helpers/MapFromJson.java | 32 +- .../eforms/viewer/helpers/ResourceLoader.java | 1 - .../eforms/viewer/helpers/SdkCodelistMap.java | 14 +- src/main/resources/checkstyle-step2.xml | 416 ++++++++++++++++++ .../ted/eforms/viewer/NoticeViewerTests.java | 49 +-- .../ted/eforms/viewer/SdkSymbolMapTests.java | 86 ---- 14 files changed, 669 insertions(+), 303 deletions(-) create mode 100644 src/main/resources/checkstyle-step2.xml delete mode 100644 src/test/java/eu/europa/ted/eforms/viewer/SdkSymbolMapTests.java diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index e76d1f3..8f40792 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -1,17 +1,15 @@ /* * Copyright 2007-present the original author or authors. * - * 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 + * 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 * - * https://www.apache.org/licenses/LICENSE-2.0 + * https://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. + * 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. */ import java.net.*; import java.io.*; @@ -20,98 +18,98 @@ public class MavenWrapperDownloader { - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + WRAPPER_VERSION + + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use + * instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar"; - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println("- ERROR creating output directory '" + + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); } + } - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); + }); } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } } diff --git a/README.md b/README.md index 535242d..431cc30 100644 --- a/README.md +++ b/README.md @@ -5,30 +5,31 @@ As input it takes an SDK view template EFX file and a notice XML file. The output is HTML showing labels, values and so on. + ## Building ### Required technologies -* Java 11, higher may work for example Java 15 worked -* Maven 3.8.2, lower or higher may work +* Java 11, higher may work for example Java 15 works +* Maven 3.8.2 as a reference but lower or higher may work + +### Required projects -### Required other projects +You will need https://citnet.tech.ec.europa.eu/CITnet/stash/projects/TEDEFO/repos/eforms-expression-language/browse (git clone, see README of that project) +After the setup, run `mvn clean install` in this project from the same folder as the `pom.xml` -1. https://citnet.tech.ec.europa.eu/CITnet/stash/projects/TEDEFO/repos/eforms-sdk-lib/browse (git clone and `mvn clean install`) -2. https://citnet.tech.ec.europa.eu/CITnet/stash/projects/TEDEFO/repos/eforms-expression-language/browse (git clone and `mvn clean install`) -3. After the setup of dependencies, run `mvn clean install` in this project from the same folder as the README.md ## Command line -Usage: ` []` +Usage: ` []` -Example: I want to generate HTML for the file `X02_registration.xml` with `english` (en) labels. +### Example -Example running it using Maven: +I want to generate an HTML to view the file `X02_registration.xml` in `en` (english). Running it using Maven: ``` mvn compile exec:java -Dspring.datasource.username=${EFORMS_DATABASE_USERNAME} -Dspring.datasource.password=${EFORMS_DATABASE_PASSWORD} -Dexec.mainClass="eu.europa.ted.eforms.viewer.Application" -Dexec.args="en X02_registration" ``` -Read the logs in the console for details about the location of the generated XSL, HTML, ... -For technical details see Application.java for the entry point, also see unit tests +After running it read the logs in the console for details about the location of the generated XSL, HTML, ... +For technical details see `Application.java` for the entry point, also see unit tests for usage. diff --git a/pom.xml b/pom.xml index 0906e73..dc45131 100644 --- a/pom.xml +++ b/pom.xml @@ -55,12 +55,20 @@ 11.3 + com.helger ph-genericode 6.2.0 + + + org.jsoup + jsoup + 1.14.3 + + @@ -91,6 +99,44 @@ + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.2 + + + com.puppycrawl.tools + checkstyle + + 9.0 + + + + /src/main/resources/checkstyle-step2.xml + + UTF-8 + true + false + false + + + + validate + validate + + check + + + + + + + diff --git a/src/main/java/eu/europa/ted/eforms/viewer/Application.java b/src/main/java/eu/europa/ted/eforms/viewer/Application.java index 1c9b5fc..542a5ec 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/Application.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/Application.java @@ -9,6 +9,9 @@ import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; +/** + * Entry point. + */ public class Application { private static final Logger logger = LoggerFactory.getLogger(Application.class); @@ -25,7 +28,7 @@ public static void main(final String[] args) logger.info("eForms Notice Viewer"); logger.info( - "Usage: []"); + "Usage: []"); logger.info("Example: en X02_registrations"); logger.info("args={}", Arrays.toString(args)); @@ -39,10 +42,10 @@ public static void main(final String[] args) "Language: expecting two letter code like 'en', 'fr', ..., but found '%s'", language)); } - final String noticeXml = args[1]; + final String noticeXmlName = args[1]; final Optional viewIdOpt = args.length > 2 ? Optional.of(args[2]) : Optional.empty(); - final Path htmlPath = NoticeViewer.generateHtml(language, noticeXml, viewIdOpt); + final Path htmlPath = NoticeViewer.generateHtml(language, noticeXmlName, viewIdOpt); logger.info("Created HTML file: {}", htmlPath); System.exit(0); } diff --git a/src/main/java/eu/europa/ted/eforms/viewer/CustomUriResolver.java b/src/main/java/eu/europa/ted/eforms/viewer/CustomUriResolver.java index 684e119..7385b1b 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/CustomUriResolver.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/CustomUriResolver.java @@ -13,18 +13,12 @@ import eu.europa.ted.eforms.viewer.helpers.SafeDocumentBuilder; public final class CustomUriResolver implements URIResolver { + + /** + * Currently this allows to load the labels. + */ @Override public Source resolve(final String href, final String base) { - // TODO lookup in SDK ? - // IDEALLY WE PASS THE LANGUAGE TO THE XSD AS A PARAMETER. - - // final String newHref; - // if ("labels.xml".equals(href)) { - // newHref = "eforms-sdk/translations/en.xml"; - // } else { - // newHref = href; - // } - try (InputStream is = ResourceLoader.getResourceAsStream("eforms-sdk/translations/" + href)) { if (is == null) { throw new RuntimeException( @@ -33,15 +27,12 @@ public Source resolve(final String href, final String base) { // DOM parser based. final DocumentBuilder builder = SafeDocumentBuilder.buildSafeDocumentBuilderAllowDoctype(); final Document document = builder.parse(is); - return new DOMSource(document); - } catch (SAXException | IOException | ParserConfigurationException e) { throw new RuntimeException(e.toString(), e); } - // An alternative is to use a StreamSource, this uses less memory. - // This can fail when it tries to load a dtd (proxy ...). + // This can fail when it tries to load a dtd (proxy issues ...). // return new StreamSource(is); } diff --git a/src/main/java/eu/europa/ted/eforms/viewer/NoticeViewer.java b/src/main/java/eu/europa/ted/eforms/viewer/NoticeViewer.java index 8420467..ba4dd18 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/NoticeViewer.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/NoticeViewer.java @@ -33,15 +33,6 @@ public class NoticeViewer { private static final Logger logger = LoggerFactory.getLogger(NoticeViewer.class); - public static Path generateHtmlForUnitTest(final String language, final String noticeXmlFilename, - final Optional viewIdOpt) { - try { - return generateHtml(language, noticeXmlFilename, viewIdOpt); - } catch (Exception e) { - throw new RuntimeException(e.toString(), e); - } - } - /** * @param language The language as a two letter code * @param noticeXmlFilename The notice xml filename but without the xml extension @@ -96,6 +87,15 @@ public static Path generateHtml(final String language, final String noticeXmlFil return applyXslTransform(language, noticeXmlPath, xslPath, viewId); } + public static Path generateHtmlForUnitTest(final String language, final String noticeXmlFilename, + final Optional viewIdOpt) { + try { + return generateHtml(language, noticeXmlFilename, viewIdOpt); + } catch (Exception e) { + throw new RuntimeException(e.toString(), e); + } + } + static Path applyXslTransform(final String language, final Path noticeXmlPath, final Path xslPath, final String viewId) throws IOException { @@ -115,6 +115,7 @@ static Path applyXslTransform(final String language, final Path noticeXmlPath, f factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + // Currently this is what allows to load the labels (i18n). factory.setURIResolver(new CustomUriResolver()); final Source xslSource = new StreamSource(inputStream); @@ -122,7 +123,6 @@ static Path applyXslTransform(final String language, final Path noticeXmlPath, f // transformer.setURIResolver(uriResolver); Already set by the factory! // Parameters. - // TODO use language in XsltUriResolver or pass it to transformer? transformer.setParameter("language", language); // For en.xml or fr.xml, ... // HTML as output of the transformation. @@ -160,10 +160,10 @@ public static final Path buildXsl(final String viewId, final String sdkVersion) final Path outFolder = Path.of("target", "output-xsl"); Files.createDirectories(outFolder); - final Path filePath = outFolder.resolve(viewId + ".xsl"); + final String nameByConvention = viewId + ".xsl"; + final Path filePath = outFolder.resolve(nameByConvention); try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath.toFile()))) { writer.write(translation); - writer.close(); } return filePath; } diff --git a/src/main/java/eu/europa/ted/eforms/viewer/SdkSymbolResolver.java b/src/main/java/eu/europa/ted/eforms/viewer/SdkSymbolResolver.java index 6da68a4..cd31ba9 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/SdkSymbolResolver.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/SdkSymbolResolver.java @@ -70,7 +70,7 @@ protected void loadMapData(final String sdkVersion) { this.codelistById = new SdkCodelistMap(sdkVersion); } catch (IOException e) { throw new RuntimeException( - String.format("Unable to load Symbols for eForms-SDK %s", sdkVersion), e); + String.format("Unable to load Symbols for eForms-SDK version=%s", sdkVersion), e); } } @@ -97,7 +97,8 @@ public String parentNodeOfField(final String fieldId) { public PathExpression absoluteXpathOfField(final String fieldId) { final SdkField sdkField = fieldById.get(fieldId); if (sdkField == null) { - throw new ParseCancellationException(String.format("Unknown field identifier '%s'.", fieldId)); + throw new ParseCancellationException( + String.format("Unknown field identifier '%s'.", fieldId)); } return new PathExpression(sdkField.getXpathAbsolute()); } diff --git a/src/main/java/eu/europa/ted/eforms/viewer/XsltRenderer.java b/src/main/java/eu/europa/ted/eforms/viewer/XsltRenderer.java index 50d3c16..cffa5f7 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/XsltRenderer.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/XsltRenderer.java @@ -19,7 +19,9 @@ public XsltRenderer() { } private final String[] assetTypes = {"business_term", "field", "code", "decoration"}; - private final String translations = Arrays.stream(assetTypes).map(assetType -> "fn:document(concat('" + assetType + "_' , $language, '.xml'))").collect(Collectors.joining(", ")); + private final String translations = Arrays.stream(assetTypes) + .map(assetType -> "fn:document(concat('" + assetType + "_' , $language, '.xml'))") + .collect(Collectors.joining(", ")); @Override public String toString() { @@ -27,15 +29,21 @@ public String toString() { } @Override - public Markup renderFile(List body, List templates) { - IndentedStringWriter writer = new IndentedStringWriter(0); + public Markup renderFile(final List body, final List templates) { + + // NOTE: you should use a library to build HTML and handle escaping, here we just use String + // format for demonstration purposes. + + final IndentedStringWriter writer = new IndentedStringWriter(0); writer.writeLine(""); - writer.openTag("xsl:stylesheet", "version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:efext=\"http://data.europa.eu/p27/eforms-ubl-extensions/1\" xmlns:efac=\"http://data.europa.eu/p27/eforms-ubl-extension-aggregate-components/1\" xmlns:efbc=\"http://data.europa.eu/p27/eforms-ubl-extension-basic-components/1\" xmlns:ext=\"urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2\""); + writer.openTag("xsl:stylesheet", + "version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:efext=\"http://data.europa.eu/p27/eforms-ubl-extensions/1\" xmlns:efac=\"http://data.europa.eu/p27/eforms-ubl-extension-aggregate-components/1\" xmlns:efbc=\"http://data.europa.eu/p27/eforms-ubl-extension-basic-components/1\" xmlns:ext=\"urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2\""); writer.writeLine(""); writer.writeLine(""); - writer.writeLine(String.format("", this.translations)); + writer.writeLine( + String.format("", this.translations)); // Root template. writer.openTag("xsl:template", "match=\"/\""); @@ -59,13 +67,15 @@ public Markup renderFile(List body, List templates) { writer.closeTag("html"); writer.closeTag("xsl:template"); - writer.writeBlock(templates.stream().map(template -> template.script).collect(Collectors.joining("\n"))); + writer.writeBlock( + templates.stream().map(template -> template.script).collect(Collectors.joining("\n"))); writer.closeTag("xsl:stylesheet"); + return new Markup(writer.toString()); } @Override - public Markup renderValueReference(Expression valueReference) { + public Markup renderValueReference(final Expression valueReference) { return new Markup(String.format("", valueReference.script)); } @@ -73,47 +83,55 @@ public Markup renderValueReference(Expression valueReference) { @Override public Markup renderLabelFromKey(final StringExpression key) { return new Markup(String.format( - "", + "", key.script, key.script)); } @Override public Markup renderLabelFromExpression(final Expression expression) { - IndentedStringWriter writer = new IndentedStringWriter(0); - String variableName = String.format("label%d", ++variableCounter); - writer.writeLine( - String.format("", variableName, expression.script)); + final IndentedStringWriter writer = new IndentedStringWriter(0); + final String variableName = String.format("label%d", ++variableCounter); + writer.writeLine(String.format("", variableName, + expression.script)); writer.writeLine(String.format( - "", + "", variableName, variableName)); return new Markup(writer.toString()); } @Override - public Markup renderFreeText(String freeText) { - return new Markup(String.format("%s", freeText)); + public Markup renderFreeText(final String freeText) { + return new Markup( + String.format("%s", freeText)); } @Override - public Markup renderTemplate(String name, String number, Markup content) { - IndentedStringWriter writer = new IndentedStringWriter(0); - writer.openTag("xsl:template", String.format("name='%s'", name)); - writer.openTag("section", "title=\"" + name + "\""); + public Markup renderTemplate(final String name, final String number, final Markup content) { + final IndentedStringWriter writer = new IndentedStringWriter(0); + final String tagTemplate = "xsl:template"; + writer.openTag(tagTemplate, String.format("name='%s'", name)); + + final String tagSection = "section"; + writer.openTag(String.format(tagSection, "title=\"%s\"", name)); if (StringUtils.isNotBlank(number)) { writer.writeLine(String.format("%s ", number)); } writer.writeBlock(content.script); - writer.closeTag("section"); - writer.closeTag("xsl:template"); + writer.closeTag(tagSection); + + writer.closeTag(tagTemplate); return new Markup(writer.toString()); } @Override - public Markup renderCallTemplate(String name, PathExpression context) { - IndentedStringWriter writer = new IndentedStringWriter(0); - writer.openTag("xsl:for-each", String.format("select=\"%s\"", context.script)); + public Markup renderCallTemplate(final String name, final PathExpression context) { + final IndentedStringWriter writer = new IndentedStringWriter(0); + final String tag = "xsl:for-each"; + writer.openTag(tag, String.format("select=\"%s\"", context.script)); writer.writeBlock(String.format("", name)); - writer.closeTag("xsl:for-each"); + writer.closeTag(tag); return new Markup(writer.toString()); } } diff --git a/src/main/java/eu/europa/ted/eforms/viewer/helpers/MapFromJson.java b/src/main/java/eu/europa/ted/eforms/viewer/helpers/MapFromJson.java index 977eb1f..24e3350 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/helpers/MapFromJson.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/helpers/MapFromJson.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.InputStream; -import java.net.URISyntaxException; import java.util.HashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,10 +20,7 @@ protected MapFromJson(final String sdkVersion, final String jsonPathname) throws } /** - * - * @param sdkVersion Currently ignored. It will be effective in a later implementation. - * @throws IOException - * @throws URISyntaxException + * @param sdkVersion Currently ignored. It will be effective in a later implementation */ private final void populateMap(final String sdkVersion, final String jsonPathname) throws IOException { @@ -32,7 +28,7 @@ private final void populateMap(final String sdkVersion, final String jsonPathnam logger.info("Populating maps for context, sdkVersion={}, jsonPathname={}", sdkVersion, jsonPathname); - final ObjectMapper objectMapper = buildStandardJacksonObjectMapper(); + final ObjectMapper mapper = buildStandardJacksonObjectMapper(); final InputStream fieldsJsonInputStream = ResourceLoader.getResourceAsStream(jsonPathname); if (fieldsJsonInputStream == null) { throw new RuntimeException(String.format("File not found: %s", jsonPathname)); @@ -40,38 +36,30 @@ private final void populateMap(final String sdkVersion, final String jsonPathnam if (fieldsJsonInputStream.available() == 0) { throw new RuntimeException(String.format("File is empty: %s", jsonPathname)); } - final JsonNode json = objectMapper.readTree(fieldsJsonInputStream); + final JsonNode json = mapper.readTree(fieldsJsonInputStream); this.populateMap(json); } - abstract protected void populateMap(final JsonNode json); - - protected final static String getTextNullOtherwise(final JsonNode node, final String key) { - final JsonNode otherNode = node.get(key); - if (otherNode == null) { - return null; - } - return otherNode.asText(null); - } + abstract void populateMap(final JsonNode json); /** * @return A reusable Jackson object mapper instance. */ private static ObjectMapper buildStandardJacksonObjectMapper() { - final ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.findAndRegisterModules(); - objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + final ObjectMapper mapper = new ObjectMapper(); + mapper.findAndRegisterModules(); + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); // https://fasterxml.github.io/jackson-annotations/javadoc/2.7/com/fasterxml/jackson/annotation/JsonInclude.Include.html // Value that indicates that only properties with non-null values are to be included. - objectMapper.setSerializationInclusion(Include.NON_NULL); + mapper.setSerializationInclusion(Include.NON_NULL); // Value that indicates that only properties with null value, // or what is considered empty, are not to be included. - objectMapper.setSerializationInclusion(Include.NON_EMPTY); + mapper.setSerializationInclusion(Include.NON_EMPTY); - return objectMapper; + return mapper; } } diff --git a/src/main/java/eu/europa/ted/eforms/viewer/helpers/ResourceLoader.java b/src/main/java/eu/europa/ted/eforms/viewer/helpers/ResourceLoader.java index a05cba0..7d6a5b6 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/helpers/ResourceLoader.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/helpers/ResourceLoader.java @@ -16,7 +16,6 @@ private ResourceLoader() { * @param resourcePath Path relative to "src/main/resources/" if you are in a Maven project. * * @return The path of the specified resource - * @throws URISyntaxException */ public static Path getResourceAsPath(final String resourcePath) { assert StringUtils.isNotBlank(resourcePath) : "resourcePath is blank"; diff --git a/src/main/java/eu/europa/ted/eforms/viewer/helpers/SdkCodelistMap.java b/src/main/java/eu/europa/ted/eforms/viewer/helpers/SdkCodelistMap.java index a34acfc..683549c 100644 --- a/src/main/java/eu/europa/ted/eforms/viewer/helpers/SdkCodelistMap.java +++ b/src/main/java/eu/europa/ted/eforms/viewer/helpers/SdkCodelistMap.java @@ -21,6 +21,9 @@ public class SdkCodelistMap extends HashMap { private static final long serialVersionUID = 1L; + /** + * Currently unused, this will be supported in future versions. + */ private final String sdkVersion; public SdkCodelistMap(final String sdkVersion) { @@ -42,12 +45,12 @@ public final SdkCodelist get(final String codelistId) { } @Override - public SdkCodelist get(Object codelistId) { + public SdkCodelist get(final Object codelistId) { return this.computeIfAbsent((String) codelistId, key -> loadSdkCodelist(key)); } @Override - public SdkCodelist getOrDefault(Object codelistId, SdkCodelist defaultValue) { + public SdkCodelist getOrDefault(final Object codelistId, final SdkCodelist defaultValue) { return this.computeIfAbsent((String) codelistId, key -> loadSdkCodelist(key)); } @@ -67,8 +70,8 @@ private static SdkCodelist loadSdkCodelist(final String codeListId) { final String filename = codelistIdToFilename.get(codeListId); assert filename != null : "filename is null"; - try (InputStream is = ResourceLoader.getResourceAsStream( - SdkConstants.EFORMS_SDK_CODELISTS.resolve(filename).toString())) { + try (InputStream is = ResourceLoader + .getResourceAsStream(SdkConstants.EFORMS_SDK_CODELISTS.resolve(filename).toString())) { final CodeListDocument cl = marshaller.read(is); final SimpleCodeList scl = cl.getSimpleCodeList(); @@ -78,8 +81,7 @@ private static SdkCodelist loadSdkCodelist(final String codeListId) { // We assume there are no duplicate code values in the referenced codelists. final List codes = scl.getRow().stream().map(row -> { final String codeVal = row.getValue().stream() - .filter( - value -> (GenericodeTools.KEY_CODE.equals(GenericodeTools.extractColRefId(value))))// + .filter(valu -> GenericodeTools.KEY_CODE.equals(GenericodeTools.extractColRefId(valu))) .findFirst()// .orElseThrow(RuntimeException::new)// .getSimpleValue()// diff --git a/src/main/resources/checkstyle-step2.xml b/src/main/resources/checkstyle-step2.xml new file mode 100644 index 0000000..2585a46 --- /dev/null +++ b/src/main/resources/checkstyle-step2.xml @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/eu/europa/ted/eforms/viewer/NoticeViewerTests.java b/src/test/java/eu/europa/ted/eforms/viewer/NoticeViewerTests.java index 611022d..c69e0df 100644 --- a/src/test/java/eu/europa/ted/eforms/viewer/NoticeViewerTests.java +++ b/src/test/java/eu/europa/ted/eforms/viewer/NoticeViewerTests.java @@ -1,15 +1,17 @@ package eu.europa.ted.eforms.viewer; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Optional; +import org.jsoup.Jsoup; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import eu.europa.ted.eforms.viewer.helpers.SdkConstants; -import eu.europa.ted.eforms.viewer.helpers.ResourceLoader; +@SuppressWarnings("static-method") public class NoticeViewerTests { private static final Logger logger = LoggerFactory.getLogger(NoticeViewerTests.class); @@ -17,39 +19,26 @@ public class NoticeViewerTests { private static final String SDK_VERSION = "latest"; @Test - @SuppressWarnings("static-method") - public void testEfxToXsl() throws IOException { - final String viewId = "X02"; - final Path xsl = NoticeViewer.buildXsl(viewId, SDK_VERSION); - logger.info("Wrote file: {}", xsl); - assertTrue(xsl.toFile().exists()); - } + public void testEfxToHtmlFull() throws IOException { + final String language = "en"; // In english. + final String noticeXmlFilename = "X02_registration"; // "X02_registration.xml" + final Optional viewIdOpt = Optional.empty(); // Equivalent to not passing any in cli. + final Path path = NoticeViewer.generateHtmlForUnitTest(language, noticeXmlFilename, viewIdOpt); + logger.info("Wrote html file: {}", path); + final File htmlFile = path.toFile(); + assertTrue(htmlFile.exists()); - /** - * A minimal test covering an XML to HTML transformation using XSL in isolation. This can be used - * to quickly try out things with XSL. - */ - @Test - @SuppressWarnings("static-method") - public void testXslToXml() throws IOException { - final String language = "en"; - final String viewId = "X02"; - final Path noticeXmlPath = ResourceLoader.getResourceAsPath( - SdkConstants.EFORMS_SDK_EXAMPLES_NOTICES.resolve("X02_registration.xml").toString()); - final Path xslPath = ResourceLoader.getResourceAsPath(Path.of("xsl", "X02.xsl").toString()); - final Path html = NoticeViewer.applyXslTransform(language, noticeXmlPath, xslPath, viewId); - logger.info("Wrote file: {}", html); - assertTrue(html.toFile().exists(), "Expecting HTML file to exist."); + // The test would have failed if there were errors, this is what the check is really about. + // In addition to that we can also check that the produced HTML can be parsed. + Jsoup.parse(htmlFile, StandardCharsets.UTF_8.toString()); } @Test - @SuppressWarnings("static-method") - public void testEfxToHtmlFull() { - final String language = "en"; - final String noticeXmlFilename = "X02_registration"; - final Path xsl = - NoticeViewer.generateHtmlForUnitTest(language, noticeXmlFilename, Optional.empty()); + public void testEfxToXsl() throws IOException { + final String viewId = "X02"; + final Path xsl = NoticeViewer.buildXsl(viewId, SDK_VERSION); logger.info("Wrote file: {}", xsl); assertTrue(xsl.toFile().exists()); + // The test would have failed if there were errors, this is what the check is really about. } } diff --git a/src/test/java/eu/europa/ted/eforms/viewer/SdkSymbolMapTests.java b/src/test/java/eu/europa/ted/eforms/viewer/SdkSymbolMapTests.java deleted file mode 100644 index a496ef9..0000000 --- a/src/test/java/eu/europa/ted/eforms/viewer/SdkSymbolMapTests.java +++ /dev/null @@ -1,86 +0,0 @@ -package eu.europa.ted.eforms.viewer; - - -import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Test; -import eu.europa.ted.efx.model.Expression.PathExpression; -import eu.europa.ted.efx.xpath.XPathScriptGenerator; - -public class SdkSymbolMapTests { - - private final String testSdkVersion = "latest"; - - private SdkSymbolResolver getDummyInstance() { - return SdkSymbolResolver.getInstance(testSdkVersion); - } - - @Test - void testGetCodelistCodesNonTailored() { - final SdkSymbolResolver symbols = getDummyInstance(); - final XPathScriptGenerator syntaxMap = new XPathScriptGenerator(); - final String expected = - "('all-rev-tic','cost-comp','exc-right','other','publ-ser-obl','soc-stand')"; - final String codelistReference = "contract-detail"; - final String efxList = syntaxMap.mapList(symbols.expandCodelist(codelistReference).stream().map(i -> syntaxMap.mapString(i)).collect(Collectors.toList())).script; // Has no parent. - assertEquals(expected, efxList); - } - - @Test - void testGetCodelistCodesTailored() { - final SdkSymbolResolver symbols = getDummyInstance(); - final XPathScriptGenerator syntaxMap = new XPathScriptGenerator(); - final String codelistReference = "eu-official-language"; - final String expected = - "('BUL','CES','DAN','DEU','ELL','ENG','EST','FIN','FRA','GLE','HRV','HUN','ITA','LAV','LIT','MLT','NLD','POL','POR','RON','SLK','SLV','SPA','SWE')"; - final String efxList = syntaxMap.mapList(symbols.expandCodelist(codelistReference).stream().map(i -> syntaxMap.mapString(i)).collect(Collectors.toList())).script; // Has no parent. - assertEquals(expected, efxList); - } - - @Test - public void testSymbolsContext() { - final SdkSymbolResolver symbols = getDummyInstance(); - final String fieldId = "BT-01(c)-Procedure"; - - final PathExpression contextPathOfField = symbols.absoluteXpathOfNode(symbols.parentNodeOfField(fieldId)); - assertEquals("/*/cac:TenderingTerms", contextPathOfField.script); - - final PathExpression relativePathOfField = symbols.relativeXpathOfField(fieldId, contextPathOfField); - assertEquals("cac:ProcurementLegislationDocumentReference/cbc:ID[not(text()='CrossBorderLaw')]", - relativePathOfField.script); - - // TODO What about cases like this: - // BT-71-Lot - // /*/cac:ProcurementProjectLot[cbc:ID/@schemeName='Lot']/cac:TenderingTerms/cac:TendererQualificationRequest[not(cbc:CompanyLegalFormCode)][not(cac:SpecificTendererRequirement/cbc:TendererRequirementTypeCode[@listName='missing-info-submission'])]/cac:SpecificTendererRequirement/cbc:TendererRequirementTypeCode[@listName='reserved-procurement'] - } - - // @Test - // public void testSymbolsFieldParentNode() { - // final SdkSymbols symbols = getDummyInstance(); - // symbols.useNewContextualizer(testNewContextualizer); - // final String fieldId = "BT-01(c)-Procedure"; - // final String parentNodeId = symbols.parentNodeOfField(fieldId); - // assertEquals("ND-1", parentNodeId); - // } - - // @Test - // public void testSymbolsFieldXpath() { - // final SdkSymbols symbols = getDummyInstance(); - // symbols.useNewContextualizer(testNewContextualizer); - // final String fieldId = "BT-01(c)-Procedure"; - // final String xpath = symbols.absoluteXpathOfField(fieldId); - // assertEquals( - // "/*/cac:TenderingTerms/cac:ProcurementLegislationDocumentReference/cbc:ID[not(text()='CrossBorderLaw')]", - // xpath); - // } - - // @Test - // public void testSymbolsNodeXpath() { - // final SdkSymbols symbols = getDummyInstance(); - // symbols.useNewContextualizer(testNewContextualizer); - // final String nodeId = "ND-609"; - // final String xpath = symbols.absoluteXpathOfNode(nodeId); - // assertEquals("/*/cac:AdditionalDocumentReference", xpath); - // } - -}