@@ -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