Skip to content

Commit 31a72fc

Browse files
authored
Merge pull request #649 from ratcashdev/master
Support file-relative XInclude href's
2 parents 6ecd8d0 + 2288df0 commit 31a72fc

File tree

5 files changed

+100
-6
lines changed

5 files changed

+100
-6
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
import java.io.File;
3333
import java.io.InputStream;
3434
import java.nio.file.Files;
35+
import java.nio.file.Path;
3536
import java.nio.file.Paths;
37+
import org.xml.sax.InputSource;
3638

3739
/**
3840
* A tool for running the SBE parser, validator, and code generator.
@@ -281,9 +283,16 @@ public static MessageSchema parseSchema(final String sbeSchemaFilename)
281283
.warningsFatal(Boolean.parseBoolean(System.getProperty(VALIDATION_WARNINGS_FATAL)))
282284
.suppressOutput(Boolean.parseBoolean(System.getProperty(VALIDATION_SUPPRESS_OUTPUT)));
283285

284-
try (InputStream in = new BufferedInputStream(Files.newInputStream(Paths.get(sbeSchemaFilename))))
286+
final Path filePath = Paths.get(sbeSchemaFilename);
287+
try (InputStream in = new BufferedInputStream(Files.newInputStream(filePath)))
285288
{
286-
return XmlSchemaParser.parse(in, optionsBuilder.build());
289+
final InputSource inputSource = new InputSource(in);
290+
final Path parentPath = filePath.toAbsolutePath().getParent();
291+
if (parentPath != null)
292+
{
293+
inputSource.setSystemId(filePath.toUri().toString());
294+
}
295+
return XmlSchemaParser.parse(inputSource, optionsBuilder.build());
287296
}
288297
}
289298

sbe-tool/src/main/java/uk/co/real_logic/sbe/xml/XmlSchemaParser.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.nio.ByteOrder;
3535
import java.util.HashMap;
3636
import java.util.Map;
37+
import org.xml.sax.InputSource;
3738

3839
import static uk.co.real_logic.sbe.PrimitiveType.*;
3940
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
9495
}
9596

9697
/**
97-
* Take an {@link InputStream} and parse it generating map of template ID to Message objects, types, and schema.
98+
* Take an {@link InputSource} and parse it generating map of template ID to Message objects, types, and schema.
9899
* <p>
99100
* Exceptions are passed back up for any problems.
100101
*
101-
* @param in stream from which schema is read.
102+
* @param is inputSource from which schema is read. Ideally it will have the systemId property set to resolve relative references
102103
* @param options to be applied during parsing.
103104
* @return {@link MessageSchema} encoding for the schema.
104105
* @throws Exception on parsing error.
105106
*/
106-
public static MessageSchema parse(final InputStream in, final ParserOptions options) throws Exception
107+
public static MessageSchema parse(final InputSource is, final ParserOptions options) throws Exception
107108
{
108109
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
109110

@@ -114,7 +115,7 @@ public static MessageSchema parse(final InputStream in, final ParserOptions opti
114115
factory.setFeature("http://apache.org/xml/features/xinclude/fixup-base-uris", false);
115116
}
116117

117-
final Document document = factory.newDocumentBuilder().parse(in);
118+
final Document document = factory.newDocumentBuilder().parse(is);
118119
final XPath xPath = XPathFactory.newInstance().newXPath();
119120

120121
final ErrorHandler errorHandler = new ErrorHandler(options);
@@ -133,6 +134,25 @@ public static MessageSchema parse(final InputStream in, final ParserOptions opti
133134
return messageSchema;
134135
}
135136

137+
/**
138+
* Wraps an {@link InputStream} into an {@link InputSource} and delegates to
139+
* {@link #parse(org.xml.sax.InputSource, uk.co.real_logic.sbe.xml.ParserOptions) }.
140+
* <p>Note: this method does not the the {@link InputSource#setSystemId(java.lang.String) } property, however. It is recommended to use the
141+
* {@link #parse(org.xml.sax.InputSource, uk.co.real_logic.sbe.xml.ParserOptions) } method directly.</p>
142+
*
143+
* <p>
144+
* Exceptions are passed back up for any problems.
145+
*
146+
* @param in stream from which schema is read.
147+
* @param options to be applied during parsing.
148+
* @return {@link MessageSchema} encoding for the schema.
149+
* @throws Exception on parsing error.
150+
*/
151+
public static MessageSchema parse(final InputStream in, final ParserOptions options) throws Exception
152+
{
153+
return parse(new InputSource(in), options);
154+
}
155+
136156
/**
137157
* Scan XML for all types (encodedDataType, compositeType, enumType, and setType) and save in map
138158
*
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2013-2019 Real Logic Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package uk.co.real_logic.sbe.xml;
17+
18+
import java.io.File;
19+
import java.io.InputStream;
20+
import java.net.URL;
21+
22+
import org.junit.Test;
23+
24+
import org.xml.sax.InputSource;
25+
import static uk.co.real_logic.sbe.xml.XmlSchemaParser.parse;
26+
27+
public class RelativeXIncludeTest
28+
{
29+
@Test
30+
public void shouldParseFileInSubDir()
31+
throws Exception
32+
{
33+
final ClassLoader classLoader = getClass().getClassLoader();
34+
final URL testResource = classLoader.getResource("sub/basic-schema.xml");
35+
final InputStream inStream = testResource.openStream();
36+
final InputSource is = new InputSource(inStream);
37+
38+
final File file = new File(testResource.getFile());
39+
is.setSystemId(file.toPath().toAbsolutePath().getParent().toUri().toString());
40+
parse(is, ParserOptions.DEFAULT);
41+
}
42+
43+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<messageSchema package="SBE tests"
3+
id="2"
4+
xmlns:xi="http://www.w3.org/2001/XInclude"
5+
semanticVersion="5.2"
6+
description="Unit Test"
7+
byteOrder="littleEndian">
8+
<xi:include href='sub2/common.xml'/>
9+
<message name="TestMessage50001" id="50001" description="TestMessage" blockLength="16">
10+
<field name="Tag40001" id="40001" type="uint32" semanticType="int"/>
11+
</message>
12+
</messageSchema>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<types>
3+
<type name="Symbol" description="Symbol" length="20" primitiveType="char" semanticType="char"/>
4+
<composite name="messageHeader" description="Message identifiers and length of message root">
5+
<type name="blockLength" primitiveType="uint16"/>
6+
<type name="templateId" primitiveType="uint16"/>
7+
<type name="schemaId" primitiveType="uint16"/>
8+
<type name="version" primitiveType="uint16"/>
9+
</composite>
10+
</types>

0 commit comments

Comments
 (0)