Skip to content

Commit 498730b

Browse files
committed
Refactored code for loading morph scripts.
In order to be able to include source file names in the location information (see commit e10de395592d082596354646e555083e4aa5e1e6) the XML input source needs to have the system id set to the file name of the source file. This happens only if the `InputSource` object is constructed from a URL. However, the old code for loading morph scripts used `Reader`s or `InputStream`s for constructing the `InputSource`. This commits rewrites the loading mechanism so that it works with URLs instead of streams. Additionally, the number of `walk` methods in `AbstractMetamorphDomWalker` are significantly reduced by moving the creation of the `InputSource` to the `Metamorph` class.
1 parent c16833e commit 498730b

File tree

5 files changed

+93
-64
lines changed

5 files changed

+93
-64
lines changed

src/main/java/org/culturegraph/mf/morph/AbstractMetamorphDomWalker.java

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
*/
1616
package org.culturegraph.mf.morph;
1717

18-
import java.io.FileNotFoundException;
19-
import java.io.InputStream;
20-
import java.io.Reader;
2118
import java.util.HashMap;
2219
import java.util.Map;
2320

@@ -26,7 +23,6 @@
2623
import org.culturegraph.mf.morph.functions.FunctionFactory;
2724
import org.culturegraph.mf.morph.maps.MapFactory;
2825
import org.culturegraph.mf.types.ScopedHashMap;
29-
import org.culturegraph.mf.util.ResourceUtil;
3026
import org.culturegraph.mf.util.StringUtil;
3127
import org.culturegraph.mf.util.xml.DomLoader;
3228
import org.w3c.dom.Document;
@@ -104,42 +100,13 @@ protected final MapFactory getMapFactory() {
104100
return mapFactory;
105101
}
106102

107-
public final void walk(final String morphDef) {
108-
try {
109-
walk(ResourceUtil.getStream(morphDef));
110-
} catch (final FileNotFoundException e) {
111-
throw new MorphDefException(e);
112-
}
113-
}
114-
115-
public final void walk(final InputStream inputStream) {
116-
if (inputStream == null) {
117-
throw new IllegalArgumentException("'inputStream' must not be null");
118-
}
119-
walk(DomLoader.parse(SCHEMA_FILE, new InputSource(inputStream)));
120-
}
121-
122-
public final void walk(final Reader reader) {
123-
if (reader == null) {
124-
throw new IllegalArgumentException("'reader' must not be null");
125-
}
126-
walk(DomLoader.parse(SCHEMA_FILE, new InputSource(reader)));
127-
}
128-
129-
public final void walk(final Reader morphDefReader, final Map<String, String> vars) {
103+
public final void walk(final InputSource morphScript, final Map<String, String> vars) {
130104
this.vars.putAll(vars);
131-
walk(morphDefReader);
105+
walk(morphScript);
132106
}
133107

134-
135-
public final void walk(final String morphDef, final Map<String, String> vars) {
136-
this.vars.putAll(vars);
137-
walk(morphDef);
138-
}
139-
140-
public final void walk(final InputStream inputStream, final Map<String, String> vars) {
141-
this.vars.putAll(vars);
142-
walk(inputStream);
108+
public final void walk(final InputSource morphScript) {
109+
walk(DomLoader.parse(SCHEMA_FILE, morphScript));
143110
}
144111

145112
private static MMTAG tagOf(final Node child) {

src/main/java/org/culturegraph/mf/morph/Metamorph.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
import java.io.IOException;
2020
import java.io.InputStream;
2121
import java.io.Reader;
22+
import java.net.MalformedURLException;
2223
import java.util.Collection;
2324
import java.util.Deque;
2425
import java.util.List;
2526
import java.util.Map;
2627

28+
import org.culturegraph.mf.exceptions.MorphDefException;
2729
import org.culturegraph.mf.framework.DefaultStreamReceiver;
2830
import org.culturegraph.mf.framework.StreamPipe;
2931
import org.culturegraph.mf.framework.StreamReceiver;
@@ -32,7 +34,10 @@
3234
import org.culturegraph.mf.framework.annotations.Out;
3335
import org.culturegraph.mf.stream.pipe.StreamFlattener;
3436
import org.culturegraph.mf.types.MultiMap;
37+
import org.culturegraph.mf.util.ResourceUtil;
3538
import org.culturegraph.mf.util.StreamConstants;
39+
import org.culturegraph.mf.util.xml.Location;
40+
import org.xml.sax.InputSource;
3641

3742
/**
3843
* Transforms a data stream send via the {@link StreamReceiver} interface. Use
@@ -54,6 +59,7 @@ public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValuePi
5459
public static final String VAR_END = "]";
5560

5661
private static final String ENTITIES_NOT_BALANCED = "Entity starts and ends are not balanced";
62+
private static final String COULD_NOT_LOAD_MORPH_FILE = "Could not load morph file";
5763

5864
private final Registry<NamedValueReceiver> dataRegistry = MorphCollectionFactory.createRegistry();
5965
private final List<NamedValueReceiver> elseSources = MorphCollectionFactory.createList();
@@ -77,42 +83,51 @@ protected Metamorph() {
7783
init();
7884
}
7985

80-
public Metamorph(final Reader morphDefReader) {
86+
public Metamorph(final String morphDef) {
8187
final MorphBuilder builder = new MorphBuilder(this);
82-
builder.walk(morphDefReader);
88+
builder.walk(getInputSource(morphDef));
8389
init();
8490
}
8591

86-
public Metamorph(final Reader morphDefReader, final Map<String, String> vars) {
92+
public Metamorph(final String morphDef, final Map<String, String> vars) {
8793
final MorphBuilder builder = new MorphBuilder(this);
88-
builder.walk(morphDefReader, vars);
94+
builder.walk(getInputSource(morphDef), vars);
8995
init();
9096
}
9197

92-
public Metamorph(final InputStream inputStream, final Map<String, String> vars) {
98+
public Metamorph(final Reader morphDef) {
9399
final MorphBuilder builder = new MorphBuilder(this);
94-
builder.walk(inputStream, vars);
100+
builder.walk(new InputSource(morphDef));
95101
init();
96102
}
97103

98-
public Metamorph(final InputStream inputStream) {
104+
public Metamorph(final Reader morphDef, final Map<String, String> vars) {
99105
final MorphBuilder builder = new MorphBuilder(this);
100-
builder.walk(inputStream);
106+
builder.walk(new InputSource(morphDef), vars);
101107
init();
102108
}
103109

104-
public Metamorph(final String morphDef) {
110+
public Metamorph(final InputStream morphDef) {
105111
final MorphBuilder builder = new MorphBuilder(this);
106-
builder.walk(morphDef);
112+
builder.walk(new InputSource(morphDef));
107113
init();
108114
}
109115

110-
public Metamorph(final String morphDef, final Map<String, String> vars) {
116+
public Metamorph(final InputStream morphDef, final Map<String, String> vars) {
111117
final MorphBuilder builder = new MorphBuilder(this);
112-
builder.walk(morphDef, vars);
118+
builder.walk(new InputSource(morphDef), vars);
113119
init();
114120
}
115121

122+
private InputSource getInputSource(final String morphDef) {
123+
try {
124+
return new InputSource(
125+
ResourceUtil.getUrl(morphDef).toExternalForm());
126+
} catch (final MalformedURLException e) {
127+
throw new MorphDefException(COULD_NOT_LOAD_MORPH_FILE, e);
128+
}
129+
}
130+
116131
private void init() {
117132
flattener.setReceiver(new DefaultStreamReceiver() {
118133
@Override

src/main/java/org/culturegraph/mf/util/ResourceUtil.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.InputStreamReader;
2525
import java.io.Reader;
2626
import java.io.UnsupportedEncodingException;
27+
import java.net.MalformedURLException;
2728
import java.net.URL;
2829
import java.util.List;
2930
import java.util.Properties;
@@ -89,8 +90,34 @@ public static Reader getReader(final File file, final String encoding) throws Fi
8990
return new InputStreamReader(getStream(file), encoding);
9091
}
9192

92-
public static URL getResourceUrl(final String name) {
93-
return Thread.currentThread().getContextClassLoader().getResource(name);
93+
/**
94+
* Attempts to return a URL for a file or resource. First, it is
95+
* checked whether {@code name} refers to an existing local file.
96+
* If not, the context class loader of the current thread is asked
97+
* if {@code name} refers to a resource. Finally, the method
98+
* attempts to interpret {@code name} as a URL.
99+
*
100+
* @param name reference to a file or resource maybe a URL
101+
* @return a URL referring to a file or resource
102+
* @throws MalformedURLException
103+
*/
104+
public static URL getUrl(final String name) throws MalformedURLException {
105+
final File file = new File(name);
106+
if (file.exists()) {
107+
return getUrl(file);
108+
}
109+
110+
final URL resourceUrl =
111+
Thread.currentThread().getContextClassLoader().getResource(name);
112+
if (resourceUrl != null) {
113+
return resourceUrl;
114+
}
115+
116+
return new URL(name);
117+
}
118+
119+
public static URL getUrl(final File file) throws MalformedURLException {
120+
return file.toURI().toURL();
94121
}
95122

96123
public static Properties loadProperties(final String location) {

src/main/java/org/culturegraph/mf/util/xml/DomLoader.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.culturegraph.mf.util.xml;
1717

18+
import java.net.MalformedURLException;
1819
import java.net.URL;
1920

2021
import javax.xml.XMLConstants;
@@ -66,9 +67,11 @@ private DomLoader() {
6667
}
6768

6869
public static Document parse(final String schemaFile, final InputSource inputSource) {
69-
final URL schemaUrl = ResourceUtil.getResourceUrl(schemaFile);
70-
if (schemaUrl == null) {
71-
throw new MorphDefException("'" + schemaFile + "' not found!");
70+
final URL schemaUrl;
71+
try {
72+
schemaUrl = ResourceUtil.getUrl(schemaFile);
73+
} catch (final MalformedURLException e) {
74+
throw new MorphDefException("'" + schemaFile + "' not found:", e);
7275
}
7376

7477
try {

src/test/java/org/culturegraph/mf/util/xml/DomBuilderTest.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.junit.Assert.assertTrue;
2020

2121
import java.io.FileNotFoundException;
22+
import java.net.MalformedURLException;
2223
import java.net.URL;
2324

2425
import org.culturegraph.mf.exceptions.MorphDefException;
@@ -42,7 +43,7 @@ public final class DomBuilderTest {
4243
private static final String SCHEMA_FILE = BASE_PATH + "test-schema.xsd";
4344

4445
@Test
45-
public void shouldCreateDOM() throws FileNotFoundException {
46+
public void shouldCreateDOM() throws FileNotFoundException, MalformedURLException {
4647
final String inputFile = "should-create-dom.xml";
4748

4849
final Document document = DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -55,7 +56,9 @@ public void shouldCreateDOM() throws FileNotFoundException {
5556
}
5657

5758
@Test(expected=MorphDefException.class)
58-
public void shouldValidateInputAgainstSchema() throws FileNotFoundException {
59+
public void shouldValidateInputAgainstSchema()
60+
throws FileNotFoundException, MalformedURLException {
61+
5962
final String inputFile = "should-validate-input-against-schema.xml";
6063

6164
DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -67,7 +70,9 @@ public void shouldValidateInputAgainstSchema() throws FileNotFoundException {
6770
}
6871

6972
@Test
70-
public void domShouldNotContainWhitespaceOnlyTextNodes() throws FileNotFoundException {
73+
public void domShouldNotContainWhitespaceOnlyTextNodes()
74+
throws FileNotFoundException, MalformedURLException {
75+
7176
final String inputFile = "dom-should-not-contain-whitespace-only-text-nodes.xml";
7277

7378
final Document document = DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -86,7 +91,9 @@ public void domShouldNotContainWhitespaceOnlyTextNodes() throws FileNotFoundExce
8691
}
8792

8893
@Test
89-
public void domShouldNotContainComments() throws FileNotFoundException {
94+
public void domShouldNotContainComments()
95+
throws FileNotFoundException, MalformedURLException {
96+
9097
final String inputFile = "dom-should-not-contain-comments.xml";
9198

9299
final Document document = DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -99,7 +106,9 @@ public void domShouldNotContainComments() throws FileNotFoundException {
99106
}
100107

101108
@Test
102-
public void shouldConvertAndAttachCDataNodesToTextNodes() throws FileNotFoundException {
109+
public void shouldConvertAndAttachCDataNodesToTextNodes()
110+
throws FileNotFoundException, MalformedURLException {
111+
103112
final String inputFile = "should-convert-and-attach-cdata-nodes-to-text-nodes.xml";
104113

105114
final Document document = DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -114,7 +123,9 @@ public void shouldConvertAndAttachCDataNodesToTextNodes() throws FileNotFoundExc
114123
}
115124

116125
@Test
117-
public void shouldBeXIncludeAware() throws FileNotFoundException {
126+
public void shouldBeXIncludeAware()
127+
throws FileNotFoundException, MalformedURLException {
128+
118129
final String inputFile = "should-be-xinclude-aware1.xml";
119130

120131
final Document document = DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -129,7 +140,9 @@ public void shouldBeXIncludeAware() throws FileNotFoundException {
129140
}
130141

131142
@Test
132-
public void shouldAnnotateDomWithLocationInformation() throws FileNotFoundException {
143+
public void shouldAnnotateDomWithLocationInformation()
144+
throws FileNotFoundException, MalformedURLException {
145+
133146
final String inputFile = "should-annotate-dom-with-location-information.xml";
134147

135148
final Document document = DomLoader.parse(SCHEMA_FILE, openStream(inputFile));
@@ -157,7 +170,9 @@ public void shouldAnnotateDomWithLocationInformation() throws FileNotFoundExcept
157170
// https://bugs.openjdk.java.net/browse/JDK-8038043
158171
@Ignore
159172
@Test
160-
public void shouldAnnotateIncludedFilesCorrectly() throws FileNotFoundException {
173+
public void shouldAnnotateIncludedFilesCorrectly()
174+
throws FileNotFoundException, MalformedURLException {
175+
161176
final String baseName = "should-annotate-included-files-correctly";
162177
final String inputFile = baseName + "1.xml";
163178

@@ -180,8 +195,10 @@ public void shouldAnnotateIncludedFilesCorrectly() throws FileNotFoundException
180195
assertEquals(62, location2.getElementEnd().getColumnNumber());
181196
}
182197

183-
private static InputSource openStream(final String resource) throws FileNotFoundException {
184-
final URL resourceUrl = ResourceUtil.getResourceUrl(BASE_PATH + resource);
198+
private static InputSource openStream(final String resource)
199+
throws FileNotFoundException, MalformedURLException {
200+
201+
final URL resourceUrl = ResourceUtil.getUrl(BASE_PATH + resource);
185202

186203
return new InputSource(resourceUrl.toExternalForm());
187204
}

0 commit comments

Comments
 (0)