Skip to content

Commit 3a509d9

Browse files
committed
Fix #205: Exception during Metamorph build
The refactored Metamorph builder failed to build scripts with collectors which use `flushWith` and `<postprocess>`. Such scripts could no longer be built but the builder aborted with an exception. The exception was caused be the builder attempting to register the `flushWith` with the end of the last function in the `<postprocess>` element instead of with the collector.
1 parent cece564 commit 3a509d9

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

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

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,19 @@ public final class MorphBuilder extends AbstractMetamorphDomWalker {
5252

5353
private static final class StackFrame {
5454

55+
private final NamedValuePipe headPipe;
56+
5557
private NamedValuePipe pipe;
5658
private boolean inEntityName;
5759
private boolean inCondition;
5860

59-
public StackFrame(final NamedValuePipe pipe) {
60-
this.pipe = pipe;
61+
public StackFrame(final NamedValuePipe headPipe) {
62+
this.headPipe = headPipe;
63+
this.pipe = headPipe;
64+
}
65+
66+
public NamedValuePipe getHeadPipe() {
67+
return headPipe;
6168
}
6269

6370
public void setPipe(final NamedValuePipe pipe) {
@@ -250,7 +257,8 @@ protected void exitIf(final Node nameNode) {
250257
@Override
251258
protected void enterCollect(final Node node) {
252259
final Map<String, String> attributes = resolvedAttributeMap(node);
253-
// must be set after recursive calls to flush descendants before parent
260+
// flushWith should not be passed to the headPipe object via a
261+
// setter (see newInstance):
254262
attributes.remove(AttributeName.FLUSH_WITH.getString());
255263

256264
if (!getCollectFactory().containsKey(node.getLocalName())) {
@@ -264,22 +272,24 @@ protected void enterCollect(final Node node) {
264272

265273
@Override
266274
protected void exitCollect(final Node node) {
267-
final NamedValuePipe collectPipe = stack.pop().getPipe();
275+
final StackFrame currentCollect = stack.pop();
276+
final Collect collector = (Collect) currentCollect.getHeadPipe();
277+
final NamedValuePipe tailPipe = currentCollect.getPipe();
268278

269279
final NamedValuePipe interceptor = interceptorFactory.createNamedValueInterceptor();
270280
final NamedValuePipe delegate;
271-
if (interceptor == null || collectPipe instanceof Entity) {
281+
if (interceptor == null || tailPipe instanceof Entity) {
272282
// The result of entity collectors cannot be intercepted
273283
// because they only use the receive/emit interface for
274284
// signalling while the actual data is transferred using
275285
// a custom mechanism. In order for this to work the Entity
276286
// class checks whether source and receiver are an
277287
// instances of Entity. If an interceptor is inserted between
278288
// entity elements this mechanism will break.
279-
delegate = collectPipe;
289+
delegate = tailPipe;
280290
} else {
281291
delegate = interceptor;
282-
delegate.addNamedValueSource(collectPipe);
292+
delegate.addNamedValueSource(tailPipe);
283293
}
284294

285295
final StackFrame parent = stack.peek();
@@ -296,11 +306,8 @@ protected void exitCollect(final Node node) {
296306
// must be set after recursive calls to flush descendants before parent
297307
final String flushWith = resolvedAttribute(node, AttributeName.FLUSH_WITH);
298308
if (null != flushWith) {
299-
assert collectPipe instanceof Collect :
300-
"Invokations of enterXXX and exitXXX are not properly balanced";
301-
302-
((Collect) collectPipe).setWaitForFlush(true);
303-
registerFlush(flushWith, ((Collect) collectPipe));
309+
collector.setWaitForFlush(true);
310+
registerFlush(flushWith, collector);
304311
}
305312
}
306313

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<metamorph-test version="1.0"
3+
xmlns="http://www.culturegraph.org/metamorph-test">
4+
5+
<test-case name="custom entity marker">
6+
<input type="text/x-formeta">
7+
1 { inLit: value }
8+
</input>
9+
10+
<transformation type="text/x-metamorph+xml">
11+
<metamorph version="1" entityMarker="."
12+
xmlns="http://www.culturegraph.org/metamorph">
13+
<rules>
14+
<combine name="outLit" value="${V}" flushWith="record">
15+
<data name="V" source="inLit" />
16+
<postprocess>
17+
<case to="upper"/>
18+
</postprocess>
19+
</combine>
20+
</rules>
21+
</metamorph>
22+
</transformation>
23+
24+
<result type="text/x-formeta">
25+
1 { outLit: VALUE }
26+
</result>
27+
</test-case>
28+
29+
</metamorph-test>

src/test/java/org/culturegraph/mf/morph/MetamorphTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@
2525
*
2626
*/
2727
@RunWith(TestSuite.class)
28-
@TestDefinitions({"MetamorphTest.xml", "MacroTest.xml"})
28+
@TestDefinitions({"MetamorphTest.xml", "MacroTest.xml", "CollectorTest.xml"})
2929
public final class MetamorphTest {/*bind to xml test*/}

0 commit comments

Comments
 (0)