From 230d340d437e15472cc35ad8c066673540c2a9a5 Mon Sep 17 00:00:00 2001 From: ratcash Date: Tue, 26 Feb 2019 10:35:39 +0100 Subject: [PATCH 1/3] Allow the resolution of XInclude href's relative to the current directory of the including XML. --- .../java/uk/co/real_logic/sbe/SbeTool.java | 13 +++++- .../real_logic/sbe/xml/XmlSchemaParser.java | 28 ++++++++++-- .../sbe/xml/RelativeXIncludeTest.java | 43 +++++++++++++++++++ .../src/test/resources/sub/basic-schema.xml | 12 ++++++ .../src/test/resources/sub/sub2/common.xml | 10 +++++ 5 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java create mode 100644 sbe-tool/src/test/resources/sub/basic-schema.xml create mode 100644 sbe-tool/src/test/resources/sub/sub2/common.xml diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java index 02713043a6..5f67aa54ea 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java @@ -32,7 +32,9 @@ import java.io.File; import java.io.InputStream; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import org.xml.sax.InputSource; /** * A tool for running the SBE parser, validator, and code generator. @@ -281,9 +283,16 @@ public static MessageSchema parseSchema(final String sbeSchemaFilename) .warningsFatal(Boolean.parseBoolean(System.getProperty(VALIDATION_WARNINGS_FATAL))) .suppressOutput(Boolean.parseBoolean(System.getProperty(VALIDATION_SUPPRESS_OUTPUT))); - try (InputStream in = new BufferedInputStream(Files.newInputStream(Paths.get(sbeSchemaFilename)))) + final Path filePath = Paths.get(sbeSchemaFilename); + try (InputStream in = new BufferedInputStream(Files.newInputStream(filePath))) { - return XmlSchemaParser.parse(in, optionsBuilder.build()); + final InputSource inputSource = new InputSource(in); + final Path parentPath = filePath.toAbsolutePath().getParent(); + if (parentPath != null) + { + inputSource.setSystemId(filePath.toUri().toString()); + } + return XmlSchemaParser.parse(inputSource, optionsBuilder.build()); } } diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java index a1f0dd5b88..1c791ae3e1 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java @@ -34,6 +34,7 @@ import java.nio.ByteOrder; import java.util.HashMap; import java.util.Map; +import org.xml.sax.InputSource; import static uk.co.real_logic.sbe.PrimitiveType.*; import static uk.co.real_logic.sbe.xml.Presence.REQUIRED; @@ -94,16 +95,16 @@ public static void validate(final String xsdFilename, final InputStream in, fina } /** - * Take an {@link InputStream} and parse it generating map of template ID to Message objects, types, and schema. + * Take an {@link InputSource} and parse it generating map of template ID to Message objects, types, and schema. *

* Exceptions are passed back up for any problems. * - * @param in stream from which schema is read. + * @param is inputSource from which schema is read. Ideally it will have the systemId property set to resolve relative references * @param options to be applied during parsing. * @return {@link MessageSchema} encoding for the schema. * @throws Exception on parsing error. */ - public static MessageSchema parse(final InputStream in, final ParserOptions options) throws Exception + public static MessageSchema parse(final InputSource is, final ParserOptions options) throws Exception { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -114,7 +115,7 @@ public static MessageSchema parse(final InputStream in, final ParserOptions opti factory.setFeature("http://apache.org/xml/features/xinclude/fixup-base-uris", false); } - final Document document = factory.newDocumentBuilder().parse(in); + final Document document = factory.newDocumentBuilder().parse(is); final XPath xPath = XPathFactory.newInstance().newXPath(); final ErrorHandler errorHandler = new ErrorHandler(options); @@ -133,6 +134,25 @@ public static MessageSchema parse(final InputStream in, final ParserOptions opti return messageSchema; } + /** + * Wraps an {@link InputStream} into an {@link InputSource} and delegates to + * {@link #parse(org.xml.sax.InputSource, uk.co.real_logic.sbe.xml.ParserOptions) }. + *

Note: this method does not the the {@link InputSource#setSystemId(java.lang.String) } property, however. It is recommended to use the + * {@link #parse(org.xml.sax.InputSource, uk.co.real_logic.sbe.xml.ParserOptions) } method directly.

+ * + *

+ * Exceptions are passed back up for any problems. + * + * @param in stream from which schema is read. + * @param options to be applied during parsing. + * @return {@link MessageSchema} encoding for the schema. + * @throws Exception on parsing error. + */ + public static MessageSchema parse(final InputStream in, final ParserOptions options) throws Exception + { + return parse(new InputSource(in), options); + } + /** * Scan XML for all types (encodedDataType, compositeType, enumType, and setType) and save in map * diff --git a/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java b/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java new file mode 100644 index 0000000000..ac9ee97348 --- /dev/null +++ b/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2019 Real Logic Ltd. + * + * 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 + * + * 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. + */ +package uk.co.real_logic.sbe.xml; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; + +import org.junit.Test; + +import org.xml.sax.InputSource; +import static uk.co.real_logic.sbe.xml.XmlSchemaParser.parse; + +public class RelativeXIncludeTest +{ + @Test + public void shouldParseFileInSubDir() + throws Exception + { + ClassLoader classLoader = getClass().getClassLoader(); + URL testResource = classLoader.getResource("sub/basic-schema.xml"); + InputStream inStream = testResource.openStream(); + InputSource is = new InputSource(inStream); + + File file = new File(testResource.getFile()); + is.setSystemId(file.toPath().toAbsolutePath().getParent().toUri().toString()); + parse(is, ParserOptions.DEFAULT); + } + +} \ No newline at end of file diff --git a/sbe-tool/src/test/resources/sub/basic-schema.xml b/sbe-tool/src/test/resources/sub/basic-schema.xml new file mode 100644 index 0000000000..54c728ca24 --- /dev/null +++ b/sbe-tool/src/test/resources/sub/basic-schema.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/sbe-tool/src/test/resources/sub/sub2/common.xml b/sbe-tool/src/test/resources/sub/sub2/common.xml new file mode 100644 index 0000000000..ddf42c9ca1 --- /dev/null +++ b/sbe-tool/src/test/resources/sub/sub2/common.xml @@ -0,0 +1,10 @@ + + + + + + + + + + From e9222ccdb53c546cc2497140246af736a6daa9ee Mon Sep 17 00:00:00 2001 From: ratcash Date: Tue, 26 Feb 2019 11:04:29 +0100 Subject: [PATCH 2/3] Fix checkstyle. --- .../src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java index 1c791ae3e1..08e494e7dd 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java @@ -139,7 +139,7 @@ public static MessageSchema parse(final InputSource is, final ParserOptions opti * {@link #parse(org.xml.sax.InputSource, uk.co.real_logic.sbe.xml.ParserOptions) }. *

Note: this method does not the the {@link InputSource#setSystemId(java.lang.String) } property, however. It is recommended to use the * {@link #parse(org.xml.sax.InputSource, uk.co.real_logic.sbe.xml.ParserOptions) } method directly.

- * + * *

* Exceptions are passed back up for any problems. * From 2288df04a63c52d96be25f3b787e86cfcbac3417 Mon Sep 17 00:00:00 2001 From: ratcash Date: Tue, 26 Feb 2019 13:09:27 +0100 Subject: [PATCH 3/3] More checkstyle fixes. --- .../uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java b/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java index ac9ee97348..33b113055c 100644 --- a/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java +++ b/sbe-tool/src/test/java/uk/co/real_logic/sbe/xml/RelativeXIncludeTest.java @@ -30,12 +30,12 @@ public class RelativeXIncludeTest public void shouldParseFileInSubDir() throws Exception { - ClassLoader classLoader = getClass().getClassLoader(); - URL testResource = classLoader.getResource("sub/basic-schema.xml"); - InputStream inStream = testResource.openStream(); - InputSource is = new InputSource(inStream); + final ClassLoader classLoader = getClass().getClassLoader(); + final URL testResource = classLoader.getResource("sub/basic-schema.xml"); + final InputStream inStream = testResource.openStream(); + final InputSource is = new InputSource(inStream); - File file = new File(testResource.getFile()); + final File file = new File(testResource.getFile()); is.setSystemId(file.toPath().toAbsolutePath().getParent().toUri().toString()); parse(is, ParserOptions.DEFAULT); }