Skip to content

Commit ab2bfff

Browse files
committed
Merge branch 'issue-338-else-nested-preserve-same-entity'
Preserve same entity in nested pass-through (_elseNested)
2 parents fd457de + 89a3b26 commit ab2bfff

File tree

2 files changed

+430
-54
lines changed

2 files changed

+430
-54
lines changed

metamorph/src/main/java/org/metafacture/metamorph/Metamorph.java

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValuePi
8282
private static final InterceptorFactory NULL_INTERCEPTOR_FACTORY = new NullInterceptorFactory();
8383
private static final Map<String, String> NO_VARS = Collections.emptyMap();
8484

85-
private final Registry<NamedValueReceiver> dataRegistry =
86-
new WildcardRegistry<>();
85+
private final Registry<NamedValueReceiver> dataRegistry = new WildcardRegistry<>();
8786
private final List<NamedValueReceiver> elseSources = new ArrayList<>();
8887

8988
private final Map<String, Map<String, String>> maps = new HashMap<>();
@@ -100,7 +99,8 @@ public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValuePi
10099
private int recordCount;
101100
private final List<FlushListener> recordEndListener = new ArrayList<>();
102101
private boolean elseNested;
103-
final private Pattern literalPatternOfEntityMarker = Pattern.compile(flattener.getEntityMarker(), Pattern.LITERAL);
102+
private boolean elseNestedEntityStarted;
103+
private String currentLiteralName;
104104
private static final Logger LOG = LoggerFactory.getLogger(Metamorph.class);
105105

106106
protected Metamorph() {
@@ -122,7 +122,6 @@ public Metamorph(final String morphDef, final InterceptorFactory interceptorFact
122122

123123
public Metamorph(final String morphDef, final Map<String, String> vars,
124124
final InterceptorFactory interceptorFactory) {
125-
126125
this(getInputSource(morphDef), vars, interceptorFactory);
127126
}
128127

@@ -140,7 +139,6 @@ public Metamorph(final Reader morphDef, final InterceptorFactory interceptorFact
140139

141140
public Metamorph(final Reader morphDef, final Map<String, String> vars,
142141
final InterceptorFactory interceptorFactory) {
143-
144142
this(new InputSource(morphDef), vars, interceptorFactory);
145143
}
146144

@@ -158,7 +156,6 @@ public Metamorph(final InputStream morphDef, final InterceptorFactory intercepto
158156

159157
public Metamorph(final InputStream morphDef, final Map<String, String> vars,
160158
final InterceptorFactory interceptorFactory) {
161-
162159
this(new InputSource(morphDef), vars, interceptorFactory);
163160
}
164161

@@ -205,7 +202,7 @@ private void init() {
205202
flattener.setReceiver(new DefaultStreamReceiver() {
206203
@Override
207204
public void literal(final String name, final String value) {
208-
dispatch(name, value, getElseSources());
205+
dispatch(name, value, getElseSources(), false);
209206
}
210207
});
211208
}
@@ -224,14 +221,16 @@ public void setErrorHandler(final MorphErrorHandler errorHandler) {
224221

225222
protected void registerNamedValueReceiver(final String source, final NamedValueReceiver data) {
226223
if (ELSE_NESTED_KEYWORD.equals(source)) {
227-
this.elseNested = true;
224+
elseNested = true;
228225
}
226+
229227
if (ELSE_KEYWORD.equals(source) || ELSE_FLATTENED_KEYWORD.equals(source) || elseNested) {
230-
if (elseSources.isEmpty())
228+
if (elseSources.isEmpty()) {
231229
elseSources.add(data);
232-
else
233-
LOG.warn(
234-
"Only one of '_else', '_elseFlattened' and '_elseNested' is allowed. Ignoring the superflous ones.");
230+
}
231+
else {
232+
LOG.warn("Only one of '_else', '_elseFlattened' and '_elseNested' is allowed. Ignoring the superflous ones.");
233+
}
235234
} else {
236235
dataRegistry.register(source, data);
237236
}
@@ -253,12 +252,11 @@ public void startRecord(final String identifier) {
253252
final String identifierFinal = identifier;
254253

255254
outputStreamReceiver.startRecord(identifierFinal);
256-
dispatch(StandardEventNames.ID, identifierFinal, null);
255+
dispatch(StandardEventNames.ID, identifierFinal, null, false);
257256
}
258257

259258
@Override
260259
public void endRecord() {
261-
262260
for(final FlushListener listener: recordEndListener){
263261
listener.flush(recordCount, currentEntityCount);
264262
}
@@ -287,17 +285,16 @@ public void startEntity(final String name) {
287285

288286
@Override
289287
public void endEntity() {
290-
dispatch(flattener.getCurrentPath(), "", null);
288+
dispatch(flattener.getCurrentPath(), "", getElseSources(), true);
291289
currentEntityCount = entityCountStack.pop().intValue();
292290
flattener.endEntity();
293-
294291
}
295292

296293

297294
@Override
298295
public void literal(final String name, final String value) {
296+
currentLiteralName = name;
299297
flattener.literal(name, value);
300-
301298
}
302299

303300
@Override
@@ -318,38 +315,51 @@ public void closeStream() {
318315
outputStreamReceiver.closeStream();
319316
}
320317

321-
protected void dispatch(final String path, final String value, final List<NamedValueReceiver> fallbackReceiver) {
322-
List<NamedValueReceiver> matchingData = dataRegistry.get(path);
323-
boolean fallback = false;
324-
if (matchingData == null || matchingData.isEmpty()) {
325-
fallback = true;
326-
matchingData = fallbackReceiver;
318+
private void dispatch(final String path, final String value, final List<NamedValueReceiver> fallbackReceiver, final boolean endEntity) {
319+
final List<NamedValueReceiver> matchingData = getData(path);
320+
321+
if (matchingData != null) {
322+
send(path, value, matchingData);
327323
}
328-
if (null != matchingData) {
329-
send(path, value, matchingData, fallback);
324+
else if (fallbackReceiver != null) {
325+
if (endEntity) {
326+
if (elseNestedEntityStarted) {
327+
outputStreamReceiver.endEntity();
328+
elseNestedEntityStarted = false;
329+
}
330+
}
331+
else {
332+
final String entityName = elseNested ? flattener.getCurrentEntityName() : null;
333+
334+
if (entityName != null) {
335+
if (getData(entityName) == null) {
336+
if (!elseNestedEntityStarted) {
337+
outputStreamReceiver.startEntity(entityName);
338+
elseNestedEntityStarted = true;
339+
}
340+
341+
send(currentLiteralName, value, fallbackReceiver);
342+
}
343+
}
344+
else {
345+
send(path, value, fallbackReceiver);
346+
}
347+
}
330348
}
331349
}
332350

333-
private void send(final String path, final String value, final List<NamedValueReceiver> dataList,
334-
final boolean fallback) {
351+
private List<NamedValueReceiver> getData(final String path) {
352+
final List<NamedValueReceiver> matchingData = dataRegistry.get(path);
353+
return matchingData != null && !matchingData.isEmpty() ? matchingData : null;
354+
}
355+
356+
private void send(final String path, final String value, final List<NamedValueReceiver> dataList) {
335357
for (final NamedValueReceiver data : dataList) {
336-
String key = path;
337-
if (fallback && elseNested) {
338-
if (flattener.getCurrentEntityName() != null) {
339-
outputStreamReceiver.startEntity(flattener.getCurrentEntityName());
340-
key = literalPatternOfEntityMarker.split(path)[1];
341-
}
342-
}
343358
try {
344-
data.receive(key, value, null, recordCount, currentEntityCount);
359+
data.receive(path, value, null, recordCount, currentEntityCount);
345360
} catch (final RuntimeException e) {
346361
errorHandler.error(e);
347362
}
348-
if (fallback && elseNested) {
349-
if (flattener.getCurrentEntityName() != null) {
350-
outputStreamReceiver.endEntity();
351-
}
352-
}
353363
}
354364
}
355365

@@ -379,7 +389,7 @@ public void receive(final String name, final String value, final NamedValueSourc
379389
}
380390

381391
if (name.length() != 0 && name.charAt(0) == FEEDBACK_CHAR) {
382-
dispatch(name, value, null);
392+
dispatch(name, value, null, false);
383393
return;
384394
}
385395

0 commit comments

Comments
 (0)