Skip to content

Commit

Permalink
Fix #205: Exception during Metamorph build
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cboehme committed Nov 25, 2014
1 parent cece564 commit 3a509d9
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
31 changes: 19 additions & 12 deletions src/main/java/org/culturegraph/mf/morph/MorphBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,19 @@ public final class MorphBuilder extends AbstractMetamorphDomWalker {

private static final class StackFrame {

private final NamedValuePipe headPipe;

private NamedValuePipe pipe;
private boolean inEntityName;
private boolean inCondition;

public StackFrame(final NamedValuePipe pipe) {
this.pipe = pipe;
public StackFrame(final NamedValuePipe headPipe) {
this.headPipe = headPipe;
this.pipe = headPipe;
}

public NamedValuePipe getHeadPipe() {
return headPipe;
}

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

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

@Override
protected void exitCollect(final Node node) {
final NamedValuePipe collectPipe = stack.pop().getPipe();
final StackFrame currentCollect = stack.pop();
final Collect collector = (Collect) currentCollect.getHeadPipe();
final NamedValuePipe tailPipe = currentCollect.getPipe();

final NamedValuePipe interceptor = interceptorFactory.createNamedValueInterceptor();
final NamedValuePipe delegate;
if (interceptor == null || collectPipe instanceof Entity) {
if (interceptor == null || tailPipe instanceof Entity) {
// The result of entity collectors cannot be intercepted
// because they only use the receive/emit interface for
// signalling while the actual data is transferred using
// a custom mechanism. In order for this to work the Entity
// class checks whether source and receiver are an
// instances of Entity. If an interceptor is inserted between
// entity elements this mechanism will break.
delegate = collectPipe;
delegate = tailPipe;
} else {
delegate = interceptor;
delegate.addNamedValueSource(collectPipe);
delegate.addNamedValueSource(tailPipe);
}

final StackFrame parent = stack.peek();
Expand All @@ -296,11 +306,8 @@ protected void exitCollect(final Node node) {
// must be set after recursive calls to flush descendants before parent
final String flushWith = resolvedAttribute(node, AttributeName.FLUSH_WITH);
if (null != flushWith) {
assert collectPipe instanceof Collect :
"Invokations of enterXXX and exitXXX are not properly balanced";

((Collect) collectPipe).setWaitForFlush(true);
registerFlush(flushWith, ((Collect) collectPipe));
collector.setWaitForFlush(true);
registerFlush(flushWith, collector);
}
}

Expand Down
29 changes: 29 additions & 0 deletions src/test/java/org/culturegraph/mf/morph/CollectorTest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<metamorph-test version="1.0"
xmlns="http://www.culturegraph.org/metamorph-test">

<test-case name="custom entity marker">
<input type="text/x-formeta">
1 { inLit: value }
</input>

<transformation type="text/x-metamorph+xml">
<metamorph version="1" entityMarker="."
xmlns="http://www.culturegraph.org/metamorph">
<rules>
<combine name="outLit" value="${V}" flushWith="record">
<data name="V" source="inLit" />
<postprocess>
<case to="upper"/>
</postprocess>
</combine>
</rules>
</metamorph>
</transformation>

<result type="text/x-formeta">
1 { outLit: VALUE }
</result>
</test-case>

</metamorph-test>
2 changes: 1 addition & 1 deletion src/test/java/org/culturegraph/mf/morph/MetamorphTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
*
*/
@RunWith(TestSuite.class)
@TestDefinitions({"MetamorphTest.xml", "MacroTest.xml"})
@TestDefinitions({"MetamorphTest.xml", "MacroTest.xml", "CollectorTest.xml"})
public final class MetamorphTest {/*bind to xml test*/}

0 comments on commit 3a509d9

Please sign in to comment.