Skip to content

Commit a797c03

Browse files
committed
Merge pull request #65 from cboehme/entity-name
Added support for data-driven entity-names in Metamorph:
2 parents 79441b4 + dfd8aef commit a797c03

File tree

6 files changed

+247
-13
lines changed

6 files changed

+247
-13
lines changed

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,14 @@ public static enum MMTAG {
5353
* XML attributes
5454
*/
5555
public static enum ATTRITBUTE {
56-
VERSION("version"), SOURCE("source"), VALUE("value"), NAME("name"), CLASS("class"), DEFAULT("default"), ENTITY_MARKER(
57-
"entityMarker"), FLUSH_WITH("flushWith");
56+
VERSION("version"),
57+
SOURCE("source"),
58+
VALUE("value"),
59+
NAME("name"),
60+
CLASS("class"),
61+
DEFAULT("default"),
62+
ENTITY_MARKER("entityMarker"),
63+
FLUSH_WITH("flushWith");
5864

5965
private final String string;
6066

@@ -71,6 +77,7 @@ public String getString() {
7177
private static final String MAP = "map";
7278
private static final String MACRO = "call-macro";
7379
private static final String POSTPROCESS = "postprocess";
80+
private static final String ENTITY_NAME = "entity-name";
7481
private static final String SCHEMA_FILE = "schemata/metamorph.xsd";
7582
private static final int LOWEST_COMPATIBLE_VERSION = 1;
7683
private static final int CURRENT_VERSION = 1;
@@ -255,13 +262,17 @@ private void handleMacros(final Node node) {
255262

256263
protected abstract void handleFunctionDefinition(final Node functionDefNode);
257264

265+
protected abstract void enterData(Node node);
266+
258267
protected abstract void exitData(Node node);
259268

260-
protected abstract void enterData(Node node);
269+
protected abstract void enterCollect(Node node);
261270

262271
protected abstract void exitCollect(Node node);
263272

264-
protected abstract void enterCollect(Node node);
273+
protected abstract void enterName(Node node);
274+
275+
protected abstract void exitName(Node node);
265276

266277
protected abstract void handleFunction(Node functionNode);
267278

@@ -272,6 +283,10 @@ private void handleRule(final Node node) {
272283
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
273284
if (POSTPROCESS.equals(child.getLocalName())) {
274285
handlePostprocess(child);
286+
} else if (ENTITY_NAME.equals(child.getLocalName())) {
287+
enterName(child);
288+
handleRule(child.getFirstChild());
289+
exitName(child);
275290
} else {
276291
handleRule(child);
277292
}

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.culturegraph.mf.exceptions.MorphDefException;
2323
import org.culturegraph.mf.morph.collectors.Collect;
24+
import org.culturegraph.mf.morph.collectors.Entity;
2425
import org.culturegraph.mf.morph.functions.Function;
2526
import org.culturegraph.mf.types.MultiMap;
2627
import org.culturegraph.mf.util.reflection.ObjectFactory;
@@ -41,6 +42,7 @@ public final class MorphBuilder extends AbstractMetamorphDomWalker {
4142
private final Metamorph metamorph;
4243
private final Deque<Collect> collectStack;
4344
private Data data;
45+
private boolean setEntityName;
4446

4547
protected MorphBuilder(final Metamorph metamorph) {
4648
super();
@@ -133,6 +135,11 @@ protected void enterData(final Node dataNode) {
133135
data = new Data();
134136
data.setName(resolvedAttribute(dataNode, ATTRITBUTE.NAME));
135137
metamorph.registerNamedValueReceiver(source, data);
138+
139+
if (setEntityName) {
140+
((Entity) collectStack.peek()).setNameSource(data);
141+
setEntityName = false;
142+
}
136143
}
137144

138145
@Override
@@ -142,22 +149,37 @@ protected void exitData(final Node node) {
142149
} else {
143150
final Collect parent = collectStack.peek();
144151
data.endPipe(parent);
145-
parent.addNamedValueSource(data);
152+
parent.addNamedValueSource(data);
146153
}
147-
data = null;
154+
data = null;
155+
}
156+
157+
@Override
158+
protected void enterName(final Node nameNode) {
159+
setEntityName = true;
160+
}
161+
162+
@Override
163+
protected void exitName(final Node nameNode) {
164+
setEntityName = false;
148165
}
149166

150167
@Override
151168
protected void enterCollect(final Node node) {
152169
final Map<String, String> attributes = resolvedAttributeMap(node);
153-
// must be set after recursive calls to flush decendents before parent
170+
// must be set after recursive calls to flush descendants before parent
154171
attributes.remove(ATTRITBUTE.FLUSH_WITH.getString());
155172

156173
if (!getCollectFactory().containsKey(node.getLocalName())) {
157174
throw new IllegalArgumentException("Collector " + node.getLocalName() + NOT_FOUND);
158175
}
159176
final Collect collect = getCollectFactory().newInstance(node.getLocalName(), attributes, metamorph);
160177

178+
if (setEntityName) {
179+
((Entity) collectStack.peek()).setNameSource(collect);
180+
setEntityName = false;
181+
}
182+
161183
collectStack.push(collect);
162184
}
163185

@@ -171,7 +193,7 @@ protected void exitCollect(final Node node) {
171193
parent.addNamedValueSource(collect);
172194
collect.endPipe(parent);
173195
}
174-
// must be set after recursive calls to flush decendents before parent
196+
// must be set after recursive calls to flush descendants before parent
175197
final String flushWith = resolvedAttribute(node, ATTRITBUTE.FLUSH_WITH);
176198
if (null != flushWith) {
177199
collect.setWaitForFlush(true);

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Set;
2828

2929
import org.apache.commons.lang.StringEscapeUtils;
30+
import org.w3c.dom.Element;
3031
import org.w3c.dom.Node;
3132

3233
/**
@@ -229,6 +230,17 @@ protected void exitCollect(final Node node) {
229230

230231
}
231232

233+
@Override
234+
protected void enterName(final Node node) {
235+
((Element)node.getFirstChild()).setAttribute(ATTRITBUTE.NAME.getString(), "<entity-name>");
236+
}
237+
238+
@Override
239+
protected void exitName(final Node node) {
240+
// TODO Auto-generated method stub
241+
242+
}
243+
232244
private void exit(final Node node) {
233245
String name = resolvedAttribute(node, ATTRITBUTE.NAME);
234246
if (name == null) {

src/main/java/org/culturegraph/mf/morph/collectors/Entity.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
import org.culturegraph.mf.morph.NamedValueReceiver;
2626
import org.culturegraph.mf.morph.NamedValueSource;
2727
import org.culturegraph.mf.stream.pipe.StreamBuffer;
28+
import org.culturegraph.mf.util.StringUtil;
2829

2930

3031

3132
/**
32-
* Corresponds to the <code>&lt;collect-entity&gt;</code> tag.
33+
* Corresponds to the <code>&lt;entity&gt;</code> tag.
3334
*
3435
* @author Markus Michael Geipel
3536
*/
@@ -41,11 +42,18 @@ public final class Entity extends AbstractCollect {
4142
private final List<NamedValueSource> sourceList = new ArrayList<NamedValueSource>();
4243
private final Set<NamedValueSource> sourcesLeft = new HashSet<NamedValueSource>();
4344
private final StreamBuffer buffer = new StreamBuffer();
45+
46+
private NamedValueSource nameSource;
47+
private String currentName;
4448

4549
public Entity(final Metamorph metamorph) {
4650
super(metamorph);
4751
}
4852

53+
public void setNameSource(final NamedValueSource nameSource) {
54+
this.nameSource = nameSource;
55+
}
56+
4957
@Override
5058
protected void emit() {
5159
final NamedValueReceiver namedValueReceiver = getNamedValueReceiver();
@@ -60,7 +68,7 @@ protected void emit() {
6068
private void write(final StreamReceiver receiver) {
6169
if (!buffer.isEmpty()) {
6270

63-
receiver.startEntity(getName());
71+
receiver.startEntity(StringUtil.fallback(currentName, getName()));
6472
buffer.setReceiver(receiver);
6573
buffer.replay();
6674
receiver.endEntity();
@@ -72,7 +80,9 @@ private void write(final StreamReceiver receiver) {
7280

7381
@Override
7482
protected void receive(final String name, final String value, final NamedValueSource source) {
75-
if (source instanceof Entity) {
83+
if (source == nameSource) {
84+
currentName = value;
85+
} else if (source instanceof Entity) {
7686
final Entity child = (Entity) source;
7787
child.write(buffer);
7888
}else{
@@ -90,11 +100,13 @@ protected boolean isComplete() {
90100
protected void clear() {
91101
sourcesLeft.addAll(sourceList);
92102
buffer.clear();
103+
currentName = null;
93104
}
94105

95106
@Override
96107
public void onNamedValueSourceAdded(final NamedValueSource namedValueSource) {
97108
sourceList.add(namedValueSource);
98109
sourcesLeft.add(namedValueSource);
99110
}
111+
100112
}

src/main/resources/schemata/metamorph.xsd

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
</complexType>
5555
</element>
5656

57-
<element name="annotation" type="string" />
5857
<element name="name" type="string" />
58+
<element name="annotation" type="string" />
5959

6060
<element name="macros">
6161
<annotation><documentation>Holds macro definitions</documentation></annotation>
@@ -269,10 +269,13 @@
269269
<annotation><documentation>Create an entity</documentation></annotation>
270270
<complexType>
271271
<choice minOccurs="1" maxOccurs="unbounded">
272+
<element ref="tns:entity-name" minOccurs="0" maxOccurs="1" />
272273
<group ref="tns:literal-rule" minOccurs="0" maxOccurs="unbounded" />
273274
<element ref="tns:entity" />
274275
</choice>
275-
<attribute name="name" type="string" use="required" />
276+
<attribute name="name" type="string" use="optional">
277+
<annotation><documentation>Name of the entity. If not given the entity must have an entity-name element.</documentation></annotation>
278+
</attribute>
276279
<attribute name="reset" type="boolean" use="optional"
277280
default="false" />
278281
<attribute name="sameEntity" type="boolean" use="optional"
@@ -299,6 +302,20 @@
299302
</complexType>
300303
</element>
301304

305+
306+
307+
<element name="entity-name">
308+
<annotation><documentation>
309+
The literal defined here is used as the name of the entity.
310+
It overrides the value of the name-attribute of the entity element.
311+
</documentation></annotation>
312+
<complexType>
313+
<sequence>
314+
<group ref="tns:literal-rule" minOccurs="1" maxOccurs="1" />
315+
</sequence>
316+
</complexType>
317+
</element>
318+
302319

303320

304321
<element name="postprocess">

0 commit comments

Comments
 (0)