Skip to content

Commit 78d0f72

Browse files
author
mgeipel
committed
fixed #30
includes refactoring the morph core classes
1 parent 3077498 commit 78d0f72

File tree

15 files changed

+504
-543
lines changed

15 files changed

+504
-543
lines changed

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

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,44 +13,33 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.culturegraph.mf.morph;
17-
18-
import org.culturegraph.mf.util.StringUtil;
19-
20-
21-
/**
22-
* Implementation of the <code>&lt;data&gt;</code> tag.
23-
*
24-
* @author Markus Michael Geipel
25-
*/
26-
final class Data extends AbstractNamedValuePipeHead{
27-
28-
private String name;
29-
//private String value;
30-
private final String source;
31-
32-
public Data(final String source) {
33-
super();
34-
this.source = source;
35-
}
36-
37-
public String getSource(){
38-
return source;
39-
}
40-
41-
@Override
42-
public void receive(final String recName, final String recValue, final NamedValueSource source, final int recordCount, final int entityCount) {
43-
getNamedValueReceiver().receive(StringUtil.fallback(name, recName), recValue, this, recordCount, entityCount);
44-
}
45-
46-
47-
/**
48-
* @param name
49-
* the defaultName to set
50-
*/
51-
52-
public void setName(final String name) {
53-
this.name = name;
54-
}
55-
56-
}
16+
package org.culturegraph.mf.morph;
17+
18+
import org.culturegraph.mf.util.StringUtil;
19+
20+
21+
/**
22+
* Implementation of the <code>&lt;data&gt;</code> tag.
23+
*
24+
* @author Markus Michael Geipel
25+
*/
26+
final class Data extends AbstractNamedValuePipeHead{
27+
28+
private String name;
29+
30+
31+
@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+
}
35+
36+
/**
37+
* @param name
38+
* the defaultName to set
39+
*/
40+
41+
public void setName(final String name) {
42+
this.name = name;
43+
}
44+
45+
}

src/main/java/org/culturegraph/mf/morph/EntityEndIndicator.java renamed to src/main/java/org/culturegraph/mf/morph/Flush.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,27 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.culturegraph.mf.morph;
17-
18-
/**
19-
* Interface for classes which signal entity end events
20-
*
21-
* @author Markus Michael Geipel
22-
*
23-
*/
24-
public interface EntityEndIndicator {
25-
String RECORD_KEYWORD = "record";
26-
27-
void addEntityEndListener(EntityEndListener entityEndListener, String entityName) ;
28-
}
16+
17+
package org.culturegraph.mf.morph;
18+
19+
20+
/**
21+
* flushes a {@link FlushListener}
22+
*
23+
* @author markus geipel
24+
*
25+
*/
26+
public final class Flush implements NamedValueReceiver {
27+
28+
private final FlushListener listener;
29+
30+
public Flush(final FlushListener listener) {
31+
this.listener = listener;
32+
}
33+
34+
@Override
35+
public void receive(final String name, final String value, final NamedValueSource source, final int recordCount, final int entityCount) {
36+
listener.flush(recordCount, entityCount);
37+
}
38+
39+
}

src/main/java/org/culturegraph/mf/morph/EntityEndListener.java renamed to src/main/java/org/culturegraph/mf/morph/FlushListener.java

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

18+
import org.culturegraph.mf.morph.collectors.Collect;
19+
1820
/**
1921
* Used by {@link Metamorph} to flush collected data in {@link Collect}.
2022
* @author Markus Michael Geipel
2123
*/
22-
public interface EntityEndListener {
23-
void onEntityEnd(final String name, int recordCount, int entityCount);
24+
public interface FlushListener {
25+
void flush(final int recordCount, final int entityCount);
2426
}

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

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
@Description("applies a metamorph transformation to the event stream. Metamorph definition is given in brackets.")
4949
@In(StreamReceiver.class)
5050
@Out(StreamReceiver.class)
51-
public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValueReceiver, MultiMap,
52-
EntityEndIndicator {
51+
public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValueReceiver, MultiMap {
5352

5453
public static final String ELSE_KEYWORD = "_else";
5554
public static final char FEEDBACK_CHAR = '@';
@@ -59,9 +58,10 @@ public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValueRe
5958

6059
private static final String ENTITIES_NOT_BALANCED = "Entity starts and ends are not balanced";
6160

62-
private final Registry<Data> dataRegistry = new WildcardRegistry<Data>();
63-
private final List<Data> elseSources = new ArrayList<Data>();
64-
private final Registry<EntityEndListener> entityEndListenerRegistry = new WildcardRegistry<EntityEndListener>();
61+
private final Registry<NamedValueReceiver> dataRegistry = new WildcardRegistry<NamedValueReceiver>();
62+
private final List<NamedValueReceiver> elseSources = new ArrayList<NamedValueReceiver>();
63+
64+
//rivate final Registry<FlushListener> entityEndListenerRegistry = new WildcardRegistry<FlushListener>();
6565

6666
private final MultiMap multiMap = new MultiHashMap();
6767
private final List<Closeable> resources = new ArrayList<Closeable>();
@@ -75,6 +75,7 @@ public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValueRe
7575
private StreamReceiver outputStreamReceiver;
7676
private MorphErrorHandler errorHandler = new DefaultErrorHandler();
7777
private int recordCount;
78+
private final List<FlushListener> recordEndListener = new ArrayList<FlushListener>();
7879

7980
protected Metamorph() {
8081
// package private
@@ -126,7 +127,7 @@ public void literal(final String name, final String value) {
126127
});
127128
}
128129

129-
protected List<Data> getElseSources() {
130+
protected List<NamedValueReceiver> getElseSources() {
130131
return elseSources;
131132
}
132133

@@ -138,14 +139,14 @@ public void setErrorHandler(final MorphErrorHandler errorHandler) {
138139
this.errorHandler = errorHandler;
139140
}
140141

141-
protected void registerData(final Data data) {
142+
protected void registerNamedValueReceiver(final String source, final NamedValueReceiver data) {
142143

143-
final String path = data.getSource();
144+
//final String path = data.getSource();
144145

145-
if (ELSE_KEYWORD.equals(path)) {
146+
if (ELSE_KEYWORD.equals(source)) {
146147
elseSources.add(data);
147148
} else {
148-
dataRegistry.register(path, data);
149+
dataRegistry.register(source, data);
149150
}
150151
}
151152

@@ -171,8 +172,10 @@ public void startRecord(final String identifier) {
171172
@Override
172173
public void endRecord() {
173174

174-
notifyEntityEndListeners(RECORD_KEYWORD);
175-
175+
for(FlushListener listener: recordEndListener){
176+
listener.flush(recordCount, currentEntityCount);
177+
}
178+
176179
outputStreamReceiver.endRecord();
177180
entityCountStack.removeLast();
178181
if (!entityCountStack.isEmpty()) {
@@ -194,32 +197,18 @@ public void startEntity(final String name) {
194197

195198
flattener.startEntity(name);
196199

197-
dispatch(flattener.getCurrentPath(), "", null);
200+
198201

199202
}
200203

201204
@Override
202205
public void endEntity() {
203-
206+
dispatch(flattener.getCurrentPath(), "", null);
204207
currentEntityCount = entityCountStack.pop().intValue();
205-
206-
final String currentEntityName = flattener.getCurrentEntityName();
207-
if (currentEntityName != null) {
208-
notifyEntityEndListeners(currentEntityName);
209-
}
210-
211208
flattener.endEntity();
212209

213210
}
214211

215-
private void notifyEntityEndListeners(final String name) {
216-
final List<EntityEndListener> matchingListeners = entityEndListenerRegistry.get(name);
217-
218-
for (EntityEndListener listener : matchingListeners) {
219-
listener.onEntityEnd(name, recordCount, currentEntityCount);
220-
}
221-
222-
}
223212

224213
@Override
225214
public void literal(final String name, final String value) {
@@ -245,15 +234,15 @@ public void closeStream() {
245234
outputStreamReceiver.closeStream();
246235
}
247236

248-
protected void dispatch(final String path, final String value, final List<Data> fallback) {
249-
final List<Data> matchingData = findMatchingData(path, fallback);
237+
protected void dispatch(final String path, final String value, final List<NamedValueReceiver> fallback) {
238+
final List<NamedValueReceiver> matchingData = findMatchingData(path, fallback);
250239
if (null != matchingData) {
251240
send(path, value, matchingData);
252241
}
253242
}
254243

255-
private List<Data> findMatchingData(final String path, final List<Data> fallback) {
256-
final List<Data> matchingData = dataRegistry.get(path);
244+
private List<NamedValueReceiver> findMatchingData(final String path, final List<NamedValueReceiver> fallback) {
245+
final List<NamedValueReceiver> matchingData = dataRegistry.get(path);
257246
if (matchingData == null || matchingData.isEmpty()) {
258247
return fallback;
259248
}
@@ -266,8 +255,8 @@ private List<Data> findMatchingData(final String path, final List<Data> fallback
266255
* @param dataList
267256
* destination
268257
*/
269-
private void send(final String key, final String value, final List<Data> dataList) {
270-
for (Data data : dataList) {
258+
private void send(final String key, final String value, final List<NamedValueReceiver> dataList) {
259+
for (NamedValueReceiver data : dataList) {
271260
try {
272261
data.receive(key, value, null, recordCount, currentEntityCount);
273262
} catch (RuntimeException e) {
@@ -322,10 +311,10 @@ public void receive(final String name, final String value, final NamedValueSourc
322311
// //entityMap.put(from, toParam);
323312
// }
324313

325-
@Override
326-
public void addEntityEndListener(final EntityEndListener entityEndListener, final String entityName) {
327-
entityEndListenerRegistry.register(entityName, entityEndListener);
328-
}
314+
// @Override
315+
// public void addEntityEndListener(final FlushListener entityEndListener, final String entityName) {
316+
// entityEndListenerRegistry.register(entityName, entityEndListener);
317+
// }
329318

330319
@Override
331320
public Map<String, String> getMap(final String mapName) {
@@ -356,4 +345,8 @@ public Collection<String> getMapNames() {
356345
return multiMap.getMapNames();
357346
}
358347

348+
public void registerRecordEndFlush(final FlushListener flushListener) {
349+
recordEndListener.add(flushListener);
350+
}
351+
359352
}

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.culturegraph.mf.util.reflection.ObjectFactory;
2727
import org.w3c.dom.Node;
2828

29-
3029
/**
3130
* Builds a {@link Metamorph} from an xml description
3231
*
@@ -36,6 +35,7 @@ public final class MorphBuilder extends AbstractMetamorphDomWalker {
3635

3736
private static final String NOT_FOUND = " not found.";
3837
private static final String JAVA = "java";
38+
private static final String RECORD = "record";
3939
// private final String morphDef;
4040
private final Metamorph metamorph;
4141
private final Deque<Collect> collectStack;
@@ -121,10 +121,9 @@ protected void finish() {
121121
@Override
122122
protected void enterData(final Node dataNode) {
123123
final String source = resolvedAttribute(dataNode, ATTRITBUTE.SOURCE);
124-
data = new Data(source);
124+
data = new Data();
125125
data.setName(resolvedAttribute(dataNode, ATTRITBUTE.NAME));
126-
// data.setValue(getAttr(dataNode, ATTRITBUTE.VALUE));
127-
metamorph.registerData(data);
126+
metamorph.registerNamedValueReceiver(source, data);
128127
}
129128

130129
@Override
@@ -166,28 +165,43 @@ protected void exitCollect(final Node node) {
166165
// must be set after recursive calls to flush decendents before parent
167166
final String flushWith = resolvedAttribute(node, ATTRITBUTE.FLUSH_WITH);
168167
if (null != flushWith) {
169-
collect.setFlushWith(flushWith);
168+
collect.setWaitForFlush(true);
169+
registerFlush(flushWith, collect);
170+
}
171+
}
172+
173+
private void registerFlush(final String flushWith, final FlushListener flushListener) {
174+
175+
if (flushWith.equals(RECORD)) {
176+
metamorph.registerRecordEndFlush(flushListener);
177+
} else {
178+
metamorph.registerNamedValueReceiver(flushWith, new Flush(flushListener));
170179
}
180+
171181
}
172182

173183
@Override
174184
protected void handleFunction(final Node functionNode) {
175185
final Function function;
186+
final Map<String, String> attributes = resolvedAttributeMap(functionNode);
176187
if (functionNode.getLocalName().equals(JAVA)) {
177188
final String className = resolvedAttribute(functionNode, ATTRITBUTE.CLASS);
178189
function = ObjectFactory.newInstance(ObjectFactory.loadClass(className, Function.class));
179-
final Map<String, String> attributes = resolvedAttributeMap(functionNode);
190+
180191
attributes.remove(ATTRITBUTE.CLASS.getString());
181192
ObjectFactory.applySetters(function, attributes);
182193
} else if (getFunctionFactory().containsKey(functionNode.getLocalName())) {
183-
function = getFunctionFactory()
184-
.newInstance(functionNode.getLocalName(), resolvedAttributeMap(functionNode));
194+
final String flushWith = attributes.remove(ATTRITBUTE.FLUSH_WITH.getString());
195+
function = getFunctionFactory().newInstance(functionNode.getLocalName(), attributes);
196+
if (null != flushWith) {
197+
registerFlush(flushWith, function);
198+
}
185199
} else {
186200
throw new IllegalArgumentException(functionNode.getLocalName() + NOT_FOUND);
187201
}
188202

189203
function.setMultiMap(metamorph);
190-
function.setEntityEndIndicator(metamorph);
204+
// nction.setEntityEndIndicator(metamorph);
191205

192206
// add key value entries...
193207
for (Node mapEntryNode = functionNode.getFirstChild(); mapEntryNode != null; mapEntryNode = mapEntryNode

0 commit comments

Comments
 (0)