Skip to content

Commit 7cd72ad

Browse files
committed
Merge branch 'metamorph-interception'
Modifies Metamorph so that interceptors can be added to a Metamorph pipeline. The primary motivation for adding this was to enable tools such as debuggers to inspect and interact with a running Metamorph script. To further support such applications the elements in the pipeline are annotated with their position in the XML source file. In order to prepare for the rather large changes on the implementation, work on the feature started with a clean-up of the Metafacture sources. This merge contains the following commits: - Removed old merge conflict in commit - Add a system for interception to Metamorph - Simplified from interface `NamedValueSource` - Added source location infos to the morph pipeline - Refactored code for loading morph scripts - Added source file location annotations to Metamorph DOM - Refactored the code for building pipelines in Metamorph - Improved code formatting and added documentation - Minor code improvements in `PicaDecoder`
2 parents e2c15af + b9663b7 commit 7cd72ad

File tree

101 files changed

+2263
-886
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2263
-886
lines changed

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

Lines changed: 66 additions & 97 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,8 +23,8 @@
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;
27+
import org.culturegraph.mf.util.xml.DomLoader;
3128
import org.w3c.dom.Document;
3229
import org.w3c.dom.Element;
3330
import org.w3c.dom.NamedNodeMap;
@@ -103,42 +100,13 @@ protected final MapFactory getMapFactory() {
103100
return mapFactory;
104101
}
105102

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

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

144112
private static Tags tagOf(final Node child) {
@@ -172,7 +140,7 @@ protected final void setIgnoreMissingVars(final boolean ignoreMissingVars) {
172140
this.ignoreMissingVars = ignoreMissingVars;
173141
}
174142

175-
protected final String resolvedAttribute(final Node node, final AttributeName attr){
143+
protected final String resolvedAttribute(final Node node, final AttributeName attr) {
176144
final String value = attribute(node, attr);
177145
if(null==value){
178146
return null;
@@ -181,7 +149,7 @@ protected final String resolvedAttribute(final Node node, final AttributeName at
181149

182150
}
183151

184-
protected final Map<String, String> resolvedAttributeMap(final Node node){
152+
protected final Map<String, String> resolvedAttributeMap(final Node node) {
185153
final Map<String, String> attributes = new HashMap<String, String>();
186154
final NamedNodeMap attrNode = node.getAttributes();
187155

@@ -192,15 +160,6 @@ protected final Map<String, String> resolvedAttributeMap(final Node node){
192160
return attributes;
193161
}
194162

195-
private void handleVars(final Node varsNode) {
196-
for (Node varNode = varsNode.getFirstChild(); varNode != null; varNode = varNode.getNextSibling()) {
197-
final String varName = attribute(varNode, AttributeName.NAME);
198-
final String varValue = attribute(varNode, AttributeName.VALUE);
199-
vars.put(varName, varValue);
200-
}
201-
vars = new ScopedHashMap<String, String>(vars);
202-
}
203-
204163
protected final void walk(final Document doc) {
205164
functionFactory = new FunctionFactory();
206165
collectFactory = new CollectFactory();
@@ -242,44 +201,26 @@ protected final void walk(final Document doc) {
242201
finish();
243202
}
244203

245-
private void handleMacros(final Node node) {
246-
for (Node macroNode = node.getFirstChild(); macroNode != null; macroNode = macroNode.getNextSibling()) {
247-
final String name = attribute(macroNode, AttributeName.NAME);
248-
macros.put(name, macroNode);
204+
private void handleMeta(final Node node) {
205+
for (Node metaEntryNode = node.getFirstChild(); metaEntryNode != null; metaEntryNode = metaEntryNode
206+
.getNextSibling()) {
207+
208+
handleMetaEntry(metaEntryNode.getLocalName(), metaEntryNode.getTextContent());
249209
}
250210
}
251211

252-
protected abstract void init();
253-
254-
protected abstract void finish();
255-
256-
protected abstract void setEntityMarker(final String entityMarker);
257-
258-
protected abstract void handleInternalMap(final Node mapNode);
259-
260-
protected abstract void handleMapClass(final Node mapNode);
261-
262-
protected abstract void handleMetaEntry(final String name, final String value);
263-
264-
protected abstract void handleFunctionDefinition(final Node functionDefNode);
265-
266-
protected abstract void enterData(Node node);
267-
268-
protected abstract void exitData(Node node);
269-
270-
protected abstract void enterCollect(Node node);
271-
272-
protected abstract void exitCollect(Node node);
273-
274-
protected abstract void enterName(Node node);
275-
276-
protected abstract void exitName(Node node);
277-
278-
protected abstract void enterIf(Node node);
279-
280-
protected abstract void exitIf(Node node);
212+
private void handleFunctionDefinitions(final Node node) {
213+
for (Node functionDefNode = node.getFirstChild(); functionDefNode != null; functionDefNode = functionDefNode
214+
.getNextSibling()) {
215+
handleFunctionDefinition(functionDefNode);
216+
}
217+
}
281218

282-
protected abstract void handleFunction(Node functionNode);
219+
private void handleRules(final Node node) {
220+
for (Node ruleNode = node.getFirstChild(); ruleNode != null; ruleNode = ruleNode.getNextSibling()) {
221+
handleRule(ruleNode);
222+
}
223+
}
283224

284225
private void handleRule(final Node node) {
285226
final String nodeName = node.getLocalName();
@@ -337,9 +278,19 @@ private void handleMaps(final Node node) {
337278
}
338279
}
339280

340-
private void handleRules(final Node node) {
341-
for (Node ruleNode = node.getFirstChild(); ruleNode != null; ruleNode = ruleNode.getNextSibling()) {
342-
handleRule(ruleNode);
281+
private void handleVars(final Node varsNode) {
282+
for (Node varNode = varsNode.getFirstChild(); varNode != null; varNode = varNode.getNextSibling()) {
283+
final String varName = attribute(varNode, AttributeName.NAME);
284+
final String varValue = attribute(varNode, AttributeName.VALUE);
285+
vars.put(varName, varValue);
286+
}
287+
vars = new ScopedHashMap<String, String>(vars);
288+
}
289+
290+
private void handleMacros(final Node node) {
291+
for (Node macroNode = node.getFirstChild(); macroNode != null; macroNode = macroNode.getNextSibling()) {
292+
final String name = attribute(macroNode, AttributeName.NAME);
293+
macros.put(name, macroNode);
343294
}
344295
}
345296

@@ -355,18 +306,36 @@ protected final void illegalChild(final Node child) {
355306
+ child.getParentNode().getLocalName());
356307
}
357308

358-
private void handleFunctionDefinitions(final Node node) {
359-
for (Node functionDefNode = node.getFirstChild(); functionDefNode != null; functionDefNode = functionDefNode
360-
.getNextSibling()) {
361-
handleFunctionDefinition(functionDefNode);
362-
}
363-
}
309+
protected abstract void init();
364310

365-
private void handleMeta(final Node node) {
366-
for (Node metaEntryNode = node.getFirstChild(); metaEntryNode != null; metaEntryNode = metaEntryNode
367-
.getNextSibling()) {
311+
protected abstract void finish();
312+
313+
protected abstract void setEntityMarker(final String entityMarker);
314+
315+
protected abstract void handleInternalMap(final Node mapNode);
316+
317+
protected abstract void handleMapClass(final Node mapNode);
318+
319+
protected abstract void handleMetaEntry(final String name, final String value);
320+
321+
protected abstract void handleFunctionDefinition(final Node functionDefNode);
322+
323+
protected abstract void enterData(Node node);
324+
325+
protected abstract void exitData(Node node);
326+
327+
protected abstract void enterCollect(Node node);
328+
329+
protected abstract void exitCollect(Node node);
330+
331+
protected abstract void enterName(Node node);
332+
333+
protected abstract void exitName(Node node);
334+
335+
protected abstract void enterIf(Node node);
336+
337+
protected abstract void exitIf(Node node);
338+
339+
protected abstract void handleFunction(Node functionNode);
368340

369-
handleMetaEntry(metaEntryNode.getLocalName(), metaEntryNode.getTextContent());
370-
}
371-
}
372341
}

src/main/java/org/culturegraph/mf/morph/AbstractNamedValuePipeHead.java renamed to src/main/java/org/culturegraph/mf/morph/AbstractNamedValuePipe.java

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,49 @@
1515
*/
1616
package org.culturegraph.mf.morph;
1717

18+
import org.culturegraph.mf.util.xml.Location;
19+
1820
/**
19-
* Base class for {@link NamedValuePipe}s
21+
* Base class for {@link NamedValuePipe}s.
22+
*
2023
* @author Markus Michael Geipel
24+
* @author Chistoph Böhme
2125
*
2226
*/
23-
public abstract class AbstractNamedValuePipeHead implements NamedValuePipeHead{
27+
public abstract class AbstractNamedValuePipe implements NamedValuePipe {
28+
2429
private NamedValueReceiver namedValueReceiver;
25-
private NamedValuePipe last = this;
26-
27-
protected final NamedValueReceiver getNamedValueReceiver() {
28-
return namedValueReceiver;
30+
31+
private Location sourceLocation;
32+
33+
@Override
34+
public final void setNamedValueReceiver(final NamedValueReceiver receiver) {
35+
namedValueReceiver = receiver;
2936
}
3037

3138
@Override
32-
public final <R extends NamedValueReceiver> R setNamedValueReceiver(final R receiver) {
33-
this.namedValueReceiver = receiver;
34-
return receiver;
39+
public final void addNamedValueSource(final NamedValueSource namedValueSource) {
40+
namedValueSource.setNamedValueReceiver(this);
41+
42+
onNamedValueSourceAdded(namedValueSource);
3543
}
36-
44+
3745
@Override
38-
public final void appendPipe(final NamedValuePipe namedValuePipe) {
39-
if(last==null){
40-
throw new IllegalStateException("NamedValuePipe already finalyzed.");
41-
}
42-
last = last.setNamedValueReceiver(namedValuePipe);
46+
public void setSourceLocation(final Location sourceLocation) {
47+
this.sourceLocation = sourceLocation;
4348
}
44-
49+
4550
@Override
46-
public final void endPipe(final NamedValueReceiver lastReceiver) {
47-
last.setNamedValueReceiver(lastReceiver);
48-
last = null;
51+
public Location getSourceLocation() {
52+
return sourceLocation;
4953
}
54+
55+
protected void onNamedValueSourceAdded(final NamedValueSource namedValueSource) {
56+
// Default implementation does nothing
57+
}
58+
59+
protected final NamedValueReceiver getNamedValueReceiver() {
60+
return namedValueReceiver;
61+
}
62+
5063
}

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

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,23 @@
1717

1818
import org.culturegraph.mf.util.StringUtil;
1919

20-
2120
/**
2221
* Implementation of the <code>&lt;data&gt;</code> tag.
23-
*
22+
*
2423
* @author Markus Michael Geipel
2524
*/
26-
final class Data extends AbstractNamedValuePipeHead{
25+
final class Data extends AbstractNamedValuePipe {
2726

2827
private String name;
2928

30-
3129
@Override
32-
public void receive(final String recName, final String recValue, final NamedValueSource source, final int recordCount, final int entityCount) {
33-
getNamedValueReceiver().receive(StringUtil.fallback(name, recName), recValue, this, recordCount, entityCount);
34-
}
30+
public void receive(final String recName, final String recValue,
31+
final NamedValueSource source, final int recordCount,
32+
final int entityCount) {
3533

36-
/**
37-
* @param name
38-
* the defaultName to set
39-
*/
34+
getNamedValueReceiver().receive(StringUtil.fallback(name, recName),
35+
recValue, this, recordCount, entityCount);
36+
}
4037

4138
public void setName(final String name) {
4239
this.name = name;
@@ -46,4 +43,5 @@ public void setName(final String name) {
4643
public String toString() {
4744
return name;
4845
}
46+
4947
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020

2121
/**
22-
* Default error handler used by {@link Metamorph}. Just repackages
23-
* exceptions as {@link MorphException}s.
22+
* Default error handler used by {@link Metamorph}. Just
23+
* repackages exceptions as {@link MorphException}s.
2424
*
2525
* @author Markus Michael Geipel
2626
*

0 commit comments

Comments
 (0)