39
39
/**
40
40
* Transforms a data stream send via the {@link StreamReceiver} interface. Use
41
41
* {@link MorphBuilder} to create an instance based on an xml description
42
- *
42
+ *
43
43
* @author Markus Michael Geipel
44
44
*/
45
45
@ Description ("applies a metamorph transformation to the event stream. Metamorph definition is given in brackets." )
@@ -49,6 +49,7 @@ public final class Metamorph implements StreamPipe<StreamReceiver>, NamedValueRe
49
49
50
50
public static final String ELSE_KEYWORD = "_else" ;
51
51
public static final char FEEDBACK_CHAR = '@' ;
52
+ public static final char ESCAPE_CHAR = '\\' ;
52
53
public static final String METADATA = "__meta" ;
53
54
public static final String VAR_START = "$[" ;
54
55
public static final String VAR_END = "]" ;
@@ -82,19 +83,19 @@ public Metamorph(final Reader morphDefReader) {
82
83
builder .walk (morphDefReader );
83
84
init ();
84
85
}
85
-
86
+
86
87
public Metamorph (final Reader morphDefReader , final Map <String , String > vars ) {
87
88
final MorphBuilder builder = new MorphBuilder (this );
88
89
builder .walk (morphDefReader , vars );
89
90
init ();
90
91
}
91
-
92
+
92
93
public Metamorph (final InputStream inputStream , final Map <String , String > vars ) {
93
94
final MorphBuilder builder = new MorphBuilder (this );
94
95
builder .walk (inputStream , vars );
95
96
init ();
96
97
}
97
-
98
+
98
99
public Metamorph (final InputStream inputStream ) {
99
100
final MorphBuilder builder = new MorphBuilder (this );
100
101
builder .walk (inputStream );
@@ -106,7 +107,7 @@ public Metamorph(final String morphDef) {
106
107
builder .walk (morphDef );
107
108
init ();
108
109
}
109
-
110
+
110
111
public Metamorph (final String morphDef , final Map <String , String > vars ) {
111
112
final MorphBuilder builder = new MorphBuilder (this );
112
113
builder .walk (morphDef , vars );
@@ -164,10 +165,10 @@ public void startRecord(final String identifier) {
164
165
@ Override
165
166
public void endRecord () {
166
167
167
- for (FlushListener listener : recordEndListener ){
168
+ for (final FlushListener listener : recordEndListener ){
168
169
listener .flush (recordCount , currentEntityCount );
169
170
}
170
-
171
+
171
172
outputStreamReceiver .endRecord ();
172
173
entityCountStack .removeLast ();
173
174
if (!entityCountStack .isEmpty ()) {
@@ -189,7 +190,7 @@ public void startEntity(final String name) {
189
190
190
191
flattener .startEntity (name );
191
192
192
-
193
+
193
194
194
195
}
195
196
@@ -216,10 +217,10 @@ public void resetStream() {
216
217
217
218
@ Override
218
219
public void closeStream () {
219
- for (Closeable closeable : resources ) {
220
+ for (final Closeable closeable : resources ) {
220
221
try {
221
222
closeable .close ();
222
- } catch (IOException e ) {
223
+ } catch (final IOException e ) {
223
224
errorHandler .error (e );
224
225
}
225
226
}
@@ -248,10 +249,10 @@ private List<NamedValueReceiver> findMatchingData(final String path, final List<
248
249
* destination
249
250
*/
250
251
private void send (final String key , final String value , final List <NamedValueReceiver > dataList ) {
251
- for (NamedValueReceiver data : dataList ) {
252
+ for (final NamedValueReceiver data : dataList ) {
252
253
try {
253
254
data .receive (key , value , null , recordCount , currentEntityCount );
254
- } catch (RuntimeException e ) {
255
+ } catch (final RuntimeException e ) {
255
256
errorHandler .error (e );
256
257
}
257
258
}
@@ -287,10 +288,15 @@ public void receive(final String name, final String value, final NamedValueSourc
287
288
288
289
if (name .length () != 0 && name .charAt (0 ) == FEEDBACK_CHAR ) {
289
290
dispatch (name , value , null );
290
- } else {
291
- outputStreamReceiver .literal (name , value );
291
+ return ;
292
292
}
293
293
294
+ String unescapedName = name ;
295
+ if (name .length () > 1 && name .charAt (0 ) == ESCAPE_CHAR
296
+ && (name .charAt (1 ) == FEEDBACK_CHAR || name .charAt (1 ) == ESCAPE_CHAR )) {
297
+ unescapedName = name .substring (1 );
298
+ }
299
+ outputStreamReceiver .literal (unescapedName , value );
294
300
}
295
301
296
302
@ Override
0 commit comments