24
24
import org .metafacture .framework .helpers .DefaultStreamReceiver ;
25
25
import org .metafacture .mangling .StreamFlattener ;
26
26
import org .metafacture .metafix .fix .Expression ;
27
- import org .metafacture .metafix .fix .Fix ;
28
27
import org .metafacture .metamorph .api .Maps ;
29
28
30
29
import org .slf4j .Logger ;
48
47
import java .util .function .BiConsumer ;
49
48
50
49
/**
51
- * Transforms a data stream sent via the {@link StreamReceiver} interface. Use
52
- * {@link RecordTransformer} to transform based on a Fix DSL description.
50
+ * Transforms a data stream sent via the {@link StreamReceiver} interface. Uses
51
+ * {@link RecordTransformer} to transform records based on a Fix DSL description.
53
52
*
54
53
* @author Markus Michael Geipel (Metamorph)
55
54
* @author Christoph Böhme (Metamorph)
@@ -73,12 +72,12 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
73
72
private final Deque <Integer > entityCountStack = new LinkedList <>();
74
73
private final List <Closeable > resources = new ArrayList <>();
75
74
private final List <Expression > expressions = new ArrayList <>();
75
+ private final Map <String , RecordTransformer > fixCache = new HashMap <>();
76
76
private final Map <String , Map <String , String >> maps = new HashMap <>();
77
77
private final Map <String , String > vars = new HashMap <>();
78
- private final RecordTransformer recordTransformer = new RecordTransformer ( this ) ;
78
+ private final RecordTransformer recordTransformer ;
79
79
private final StreamFlattener flattener = new StreamFlattener ();
80
80
81
- private Fix fix ;
82
81
private List <Value > entities = new ArrayList <>();
83
82
private Record currentRecord = new Record ();
84
83
private StreamReceiver outputStreamReceiver ;
@@ -88,37 +87,27 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
88
87
private int entityCount ;
89
88
90
89
public Metafix () {
91
- flattener .setReceiver (new DefaultStreamReceiver () {
92
-
93
- @ Override
94
- public void literal (final String name , final String value ) {
95
- final String [] split = Value .split (name );
96
- addValue (split [split .length - 1 ], new Value (value , name ));
97
- // TODO could this help with https://github.com/metafacture/metafacture-fix/issues/147?
98
- // TODO use full path here to insert only once?
99
- // new FixPath(name).insertInto(currentRecord, InsertMode.APPEND, new Value(value));
100
- }
101
- });
90
+ this (NO_VARS );
102
91
}
103
92
104
93
public Metafix (final Map <String , String > newVars ) {
105
- this ( );
106
- vars . putAll ( newVars ) ;
94
+ init ( newVars );
95
+ recordTransformer = null ;
107
96
}
108
97
109
98
public Metafix (final String fixDef ) throws FileNotFoundException {
110
99
this (fixDef , NO_VARS );
111
100
}
112
101
113
102
public Metafix (final String fixDef , final Map <String , String > vars ) throws FileNotFoundException {
114
- this (vars );
103
+ init (vars );
115
104
116
105
if (isFixFile (fixDef )) {
117
106
fixFile = fixDef ;
118
- fix = FixStandaloneSetup . parseFix (fixDef );
107
+ recordTransformer = getRecordTransformer (fixDef );
119
108
}
120
109
else {
121
- fix = FixStandaloneSetup . parseFix (new StringReader (fixDef ));
110
+ recordTransformer = getRecordTransformer (new StringReader (fixDef ));
122
111
}
123
112
}
124
113
@@ -127,8 +116,25 @@ public Metafix(final Reader fixDef) {
127
116
}
128
117
129
118
public Metafix (final Reader fixDef , final Map <String , String > vars ) {
130
- this (vars );
131
- fix = FixStandaloneSetup .parseFix (fixDef );
119
+ init (vars );
120
+ recordTransformer = getRecordTransformer (fixDef );
121
+ }
122
+
123
+ private void init (final Map <String , String > newVars ) {
124
+ flattener .setReceiver (new DefaultStreamReceiver () {
125
+
126
+ @ Override
127
+ public void literal (final String name , final String value ) {
128
+ final String [] split = Value .split (name );
129
+ addValue (split [split .length - 1 ], new Value (value , name ));
130
+ // TODO could this help with https://github.com/metafacture/metafacture-fix/issues/147?
131
+ // TODO use full path here to insert only once?
132
+ // new FixPath(name).insertInto(currentRecord, InsertMode.APPEND, new Value(value));
133
+ }
134
+
135
+ });
136
+
137
+ vars .putAll (newVars );
132
138
}
133
139
134
140
/*package-private*/ static boolean isFixFile (final String fixDef ) {
@@ -149,8 +155,12 @@ public String resolvePath(final String path) {
149
155
}
150
156
}
151
157
152
- public RecordTransformer getRecordTransformer () {
153
- return recordTransformer ;
158
+ public RecordTransformer getRecordTransformer (final String fixDef ) {
159
+ return fixCache .computeIfAbsent (fixDef , k -> new RecordTransformer (this , FixStandaloneSetup .parseFix (k )));
160
+ }
161
+
162
+ private RecordTransformer getRecordTransformer (final Reader fixDef ) {
163
+ return new RecordTransformer (this , FixStandaloneSetup .parseFix (fixDef ));
154
164
}
155
165
156
166
public List <Expression > getExpressions () {
@@ -177,8 +187,8 @@ public void endRecord() {
177
187
throw new IllegalStateException (ENTITIES_NOT_BALANCED );
178
188
}
179
189
flattener .endRecord ();
180
- LOG .debug ("End record, walking fix : {}" , currentRecord );
181
- currentRecord = recordTransformer .transform (fix );
190
+ LOG .debug ("End record, walking Fix : {}" , currentRecord );
191
+ recordTransformer .transform (currentRecord );
182
192
if (!currentRecord .getReject ()) {
183
193
outputStreamReceiver .startRecord (recordIdentifier );
184
194
LOG .debug ("Sending results to {}" , outputStreamReceiver );
0 commit comments