38
38
import org .slf4j .LoggerFactory ;
39
39
40
40
import java .util .ArrayList ;
41
+ import java .util .HashMap ;
41
42
import java .util .LinkedHashMap ;
42
43
import java .util .LinkedList ;
43
44
import java .util .List ;
47
48
import java .util .function .Supplier ;
48
49
import java .util .stream .Collectors ;
49
50
51
+ // TODO: Utilize org.metafacture.commons.types.ScopedHashMap for vars instead?
52
+
50
53
/**
51
54
* Transform a record using a {@link Fix}.
52
55
*
@@ -58,22 +61,24 @@ public class RecordTransformer { // checkstyle-disable-line ClassFanOutComplexit
58
61
private static final Logger LOG = LoggerFactory .getLogger (RecordTransformer .class );
59
62
60
63
private final List <Consumer <Record >> consumers = new LinkedList <>();
61
- private final Map <String , String > vars ;
64
+ private final List < Map <String , String >> vars = new ArrayList <>() ;
62
65
private final Metafix metafix ;
66
+ private final RecordTransformer parent ;
63
67
64
68
private Supplier <String > currentMessageSupplier ;
65
69
66
70
/*package-private*/ RecordTransformer (final Metafix metafix , final Fix fix ) {
67
- this (metafix , fix .getElements ());
71
+ this (metafix , fix .getElements (), null );
72
+ addVars (metafix .getVars ());
68
73
}
69
74
70
- private RecordTransformer (final Metafix metafix , final List <Expression > expressions ) {
75
+ private RecordTransformer (final Metafix metafix , final List <Expression > expressions , final RecordTransformer parent ) {
71
76
this .metafix = metafix ;
72
- vars = metafix . getVars () ;
77
+ this . parent = parent ;
73
78
74
79
expressions .forEach (e -> {
75
- final Params params = new Params (e .getParams (), vars );
76
- final Options options = new Options (e .getOptions (), vars );
80
+ final Params params = new Params (e .getParams (), this );
81
+ final Options options = new Options (e .getOptions (), this );
77
82
78
83
if (e instanceof Do ) {
79
84
processDo ((Do ) e , params , options );
@@ -93,6 +98,26 @@ else if (e instanceof MethodCall) {
93
98
});
94
99
}
95
100
101
+ private RecordTransformer childTransformer (final List <Expression > expressions ) {
102
+ return new RecordTransformer (metafix , expressions , this );
103
+ }
104
+
105
+ public void addVars (final Map <String , String > additionalVars ) {
106
+ vars .add (additionalVars );
107
+ }
108
+
109
+ public void transform (final Record record , final Map <String , String > additionalVars ) {
110
+ final int index = vars .size ();
111
+ addVars (additionalVars );
112
+
113
+ try {
114
+ transform (record );
115
+ }
116
+ finally {
117
+ vars .remove (index );
118
+ }
119
+ }
120
+
96
121
public void transform (final Record record ) {
97
122
consumers .forEach (consumer -> {
98
123
final FixExecutionException exception = tryRun (() -> consumer .accept (record ));
@@ -106,7 +131,7 @@ public void transform(final Record record) {
106
131
private void processDo (final Do expression , final Params params , final Options options ) {
107
132
processFix (() -> executionExceptionMessage (expression ), () -> {
108
133
final FixContext context = getInstance (expression .getName (), FixContext .class , FixBind ::valueOf );
109
- final RecordTransformer recordTransformer = new RecordTransformer ( metafix , expression .getElements ());
134
+ final RecordTransformer recordTransformer = childTransformer ( expression .getElements ());
110
135
111
136
return record -> context .execute (metafix , record , params .resolve (), options .resolve (), recordTransformer );
112
137
});
@@ -121,14 +146,14 @@ private void processIf(final If ifExpression, final Params ifParams, final Optio
121
146
122
147
processFix (() -> executionExceptionMessage (ifExpression , ifExpression .eResource ()), () -> {
123
148
final FixPredicate ifPredicate = getInstance (ifExpression .getName (), FixPredicate .class , FixConditional ::valueOf );
124
- final RecordTransformer ifTransformer = new RecordTransformer ( metafix , ifExpression .getElements ());
149
+ final RecordTransformer ifTransformer = childTransformer ( ifExpression .getElements ());
125
150
126
151
final List <FixPredicate > elseIfPredicates = mapList (elseIfExpressions , e -> getInstance (e .getName (), FixPredicate .class , FixConditional ::valueOf ));
127
- final List <Params > elseIfParamsList = mapList (elseIfExpressions , e -> new Params (e .getParams (), vars ));
128
- final List <Options > elseIfOptionsList = mapList (elseIfExpressions , e -> new Options (e .getOptions (), vars ));
129
- final List <RecordTransformer > elseIfTransformers = mapList (elseIfExpressions , e -> new RecordTransformer ( metafix , e .getElements ()));
152
+ final List <Params > elseIfParamsList = mapList (elseIfExpressions , e -> new Params (e .getParams (), this ));
153
+ final List <Options > elseIfOptionsList = mapList (elseIfExpressions , e -> new Options (e .getOptions (), this ));
154
+ final List <RecordTransformer > elseIfTransformers = mapList (elseIfExpressions , e -> childTransformer ( e .getElements ()));
130
155
131
- final RecordTransformer elseTransformer = elseExpression != null ? new RecordTransformer ( metafix , elseExpression .getElements ()) : null ;
156
+ final RecordTransformer elseTransformer = elseExpression != null ? childTransformer ( elseExpression .getElements ()) : null ;
132
157
133
158
return record -> {
134
159
if (ifPredicate .test (metafix , record , ifParams .resolve (), ifOptions .resolve ())) {
@@ -163,7 +188,7 @@ private void processIf(final If ifExpression, final Params ifParams, final Optio
163
188
private void processUnless (final Unless expression , final Params params , final Options options ) {
164
189
processFix (() -> executionExceptionMessage (expression , expression .eResource ()), () -> {
165
190
final FixPredicate predicate = getInstance (expression .getName (), FixPredicate .class , FixConditional ::valueOf );
166
- final RecordTransformer recordTransformer = new RecordTransformer ( metafix , expression .getElements ());
191
+ final RecordTransformer recordTransformer = childTransformer ( expression .getElements ());
167
192
168
193
return record -> {
169
194
if (!predicate .test (metafix , record , params .resolve (), options .resolve ())) {
@@ -236,6 +261,12 @@ private String executionExceptionMessage(final EObject object, final Resource re
236
261
resource .getURI (), node .getStartLine (), NodeModelUtils .getTokenText (node ));
237
262
}
238
263
264
+ private Map <String , String > getVars () {
265
+ final Map <String , String > mergedVars = parent != null ? parent .getVars () : new HashMap <>();
266
+ vars .forEach (mergedVars ::putAll );
267
+ return mergedVars ;
268
+ }
269
+
239
270
private abstract static class AbstractResolvable <T > {
240
271
241
272
protected boolean isResolvable (final String value ) {
@@ -253,12 +284,12 @@ protected String resolveVars(final String value, final Map<String, String> vars)
253
284
private static class Params extends AbstractResolvable <List <String >> {
254
285
255
286
private final List <String > list ;
256
- private final Map < String , String > vars ;
287
+ private final RecordTransformer recordTransformer ;
257
288
private final boolean resolve ;
258
289
259
- private Params (final List <String > list , final Map < String , String > vars ) {
290
+ private Params (final List <String > list , final RecordTransformer recordTransformer ) {
260
291
this .list = list ;
261
- this .vars = vars ;
292
+ this .recordTransformer = recordTransformer ;
262
293
263
294
resolve = list .stream ().anyMatch (this ::isResolvable );
264
295
}
@@ -267,6 +298,7 @@ private Params(final List<String> list, final Map<String, String> vars) {
267
298
protected List <String > resolve () {
268
299
if (resolve ) {
269
300
final List <String > resolvedList = new ArrayList <>(list .size ());
301
+ final Map <String , String > vars = recordTransformer .getVars ();
270
302
271
303
for (final String entry : list ) {
272
304
resolvedList .add (resolveVars (entry , vars ));
@@ -284,11 +316,11 @@ protected List<String> resolve() {
284
316
private static class Options extends AbstractResolvable <Map <String , String >> {
285
317
286
318
private final Map <String , String > map = new LinkedHashMap <>();
287
- private final Map < String , String > vars ;
319
+ private final RecordTransformer recordTransformer ;
288
320
private final boolean resolve ;
289
321
290
- private Options (final org .metafacture .metafix .fix .Options options , final Map < String , String > vars ) {
291
- this .vars = vars ;
322
+ private Options (final org .metafacture .metafix .fix .Options options , final RecordTransformer recordTransformer ) {
323
+ this .recordTransformer = recordTransformer ;
292
324
293
325
boolean resolveTemp = false ;
294
326
@@ -315,6 +347,7 @@ private Options(final org.metafacture.metafix.fix.Options options, final Map<Str
315
347
protected Map <String , String > resolve () {
316
348
if (resolve ) {
317
349
final Map <String , String > resolvedMap = new LinkedHashMap <>(map .size ());
350
+ final Map <String , String > vars = recordTransformer .getVars ();
318
351
319
352
for (final Map .Entry <String , String > entry : map .entrySet ()) {
320
353
resolvedMap .put (resolveVars (entry .getKey (), vars ), resolveVars (entry .getValue (), vars ));
0 commit comments