Skip to content

Commit 85db657

Browse files
committed
Optimize resolution of variables in parameters and options. (#207)
Only resolve vars if actually needed.
1 parent 56e59e6 commit 85db657

File tree

1 file changed

+90
-37
lines changed

1 file changed

+90
-37
lines changed

metafix/src/main/java/org/metafacture/metafix/RecordTransformer.java

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.metafacture.metafix.fix.Fix;
2929
import org.metafacture.metafix.fix.If;
3030
import org.metafacture.metafix.fix.MethodCall;
31-
import org.metafacture.metafix.fix.Options;
3231
import org.metafacture.metafix.fix.Unless;
3332

3433
import org.eclipse.emf.ecore.EObject;
@@ -72,8 +71,8 @@ private RecordTransformer(final Metafix metafix, final List<Expression> expressi
7271
vars = metafix.getVars();
7372

7473
expressions.forEach(e -> {
75-
final List<String> params = e.getParams();
76-
final Map<String, String> options = options(e.getOptions());
74+
final Params params = new Params(e.getParams(), vars);
75+
final Options options = new Options(e.getOptions(), vars);
7776

7877
if (e instanceof Do) {
7978
processDo((Do) e, params, options);
@@ -103,16 +102,16 @@ public void transform(final Record record) {
103102
});
104103
}
105104

106-
private void processDo(final Do expression, final List<String> params, final Map<String, String> options) {
105+
private void processDo(final Do expression, final Params params, final Options options) {
107106
processFix(() -> executionExceptionMessage(expression), () -> {
108107
final FixContext context = getInstance(expression.getName(), FixContext.class, FixBind::valueOf);
109108
final RecordTransformer recordTransformer = new RecordTransformer(metafix, expression.getElements());
110109

111-
return record -> context.execute(metafix, record, resolveParams(params), resolveOptions(options), recordTransformer);
110+
return record -> context.execute(metafix, record, params.resolve(), options.resolve(), recordTransformer);
112111
});
113112
}
114113

115-
private void processIf(final If ifExpression, final List<String> ifParams, final Map<String, String> ifOptions) {
114+
private void processIf(final If ifExpression, final Params ifParams, final Options ifOptions) {
116115
final ElsIf elseIfExpression = ifExpression.getElseIf();
117116
final Else elseExpression = ifExpression.getElse();
118117

@@ -124,14 +123,14 @@ private void processIf(final If ifExpression, final List<String> ifParams, final
124123
final RecordTransformer ifTransformer = new RecordTransformer(metafix, ifExpression.getElements());
125124

126125
final FixPredicate elseIfPredicate;
127-
final List<String> elseIfParams;
128-
final Map<String, String> elseIfOptions;
126+
final Params elseIfParams;
127+
final Options elseIfOptions;
129128
final RecordTransformer elseIfTransformer;
130129

131130
if (elseIfExpression != null) {
132131
elseIfPredicate = getInstance(elseIfExpression.getName(), FixPredicate.class, FixConditional::valueOf);
133-
elseIfParams = elseIfExpression.getParams();
134-
elseIfOptions = options(elseIfExpression.getOptions());
132+
elseIfParams = new Params(elseIfExpression.getParams(), vars);
133+
elseIfOptions = new Options(elseIfExpression.getOptions(), vars);
135134
elseIfTransformer = new RecordTransformer(metafix, elseIfExpression.getElements());
136135
}
137136
else {
@@ -144,14 +143,14 @@ private void processIf(final If ifExpression, final List<String> ifParams, final
144143
final RecordTransformer elseTransformer = elseExpression != null ? new RecordTransformer(metafix, elseExpression.getElements()) : null;
145144

146145
return record -> {
147-
if (ifPredicate.test(metafix, record, resolveParams(ifParams), resolveOptions(ifOptions))) {
146+
if (ifPredicate.test(metafix, record, ifParams.resolve(), ifOptions.resolve())) {
148147
ifTransformer.transform(record);
149148
}
150149
else {
151150
if (elseIfExpression != null) {
152151
currentMessageSupplier = elseIfMessageSupplier;
153152

154-
if (elseIfPredicate.test(metafix, record, resolveParams(elseIfParams), resolveOptions(elseIfOptions))) {
153+
if (elseIfPredicate.test(metafix, record, elseIfParams.resolve(), elseIfOptions.resolve())) {
155154
elseIfTransformer.transform(record);
156155
return;
157156
}
@@ -166,23 +165,23 @@ private void processIf(final If ifExpression, final List<String> ifParams, final
166165
});
167166
}
168167

169-
private void processUnless(final Unless expression, final List<String> params, final Map<String, String> options) {
168+
private void processUnless(final Unless expression, final Params params, final Options options) {
170169
processFix(() -> executionExceptionMessage(expression, expression.eResource()), () -> {
171170
final FixPredicate predicate = getInstance(expression.getName(), FixPredicate.class, FixConditional::valueOf);
172171
final RecordTransformer recordTransformer = new RecordTransformer(metafix, expression.getElements());
173172

174173
return record -> {
175-
if (!predicate.test(metafix, record, resolveParams(params), resolveOptions(options))) {
174+
if (!predicate.test(metafix, record, params.resolve(), options.resolve())) {
176175
recordTransformer.transform(record);
177176
}
178177
};
179178
});
180179
}
181180

182-
private void processFunction(final MethodCall expression, final List<String> params, final Map<String, String> options) {
181+
private void processFunction(final MethodCall expression, final Params params, final Options options) {
183182
processFix(() -> executionExceptionMessage(expression), () -> {
184183
final FixFunction function = getInstance(expression.getName(), FixFunction.class, FixMethod::valueOf);
185-
return record -> function.apply(metafix, record, resolveParams(params), resolveOptions(options));
184+
return record -> function.apply(metafix, record, params.resolve(), options.resolve());
186185
});
187186
}
188187

@@ -238,43 +237,97 @@ private String executionExceptionMessage(final EObject object, final Resource re
238237
resource.getURI(), node.getStartLine(), NodeModelUtils.getTokenText(node));
239238
}
240239

241-
private String resolveVars(final String value) {
242-
return value == null ? null : StringUtil.format(value, Metafix.VAR_START, Metafix.VAR_END, false, vars);
243-
}
240+
private abstract static class AbstractResolvable<T> {
244241

245-
private List<String> resolveParams(final List<String> params) {
246-
final List<String> list = new ArrayList<>(params.size());
242+
protected boolean isResolvable(final String value) {
243+
return value != null && value.contains(Metafix.VAR_START);
244+
}
247245

248-
for (final String entry : params) {
249-
list.add(resolveVars(entry));
246+
protected String resolveVars(final String value, final Map<String, String> vars) {
247+
return value == null ? null : StringUtil.format(value, Metafix.VAR_START, Metafix.VAR_END, false, vars);
250248
}
251249

252-
return list;
250+
protected abstract T resolve();
251+
253252
}
254253

255-
private Map<String, String> options(final Options options) {
256-
final Map<String, String> map = new LinkedHashMap<>();
254+
private static class Params extends AbstractResolvable<List<String>> {
255+
256+
private final List<String> list;
257+
private final Map<String, String> vars;
258+
private final boolean resolve;
257259

258-
if (options != null) {
259-
final List<String> keys = options.getKeys();
260-
final List<String> values = options.getValues();
260+
private Params(final List<String> list, final Map<String, String> vars) {
261+
this.list = list;
262+
this.vars = vars;
261263

262-
for (int i = 0; i < keys.size(); i += 1) {
263-
map.put(keys.get(i), values.get(i));
264+
resolve = list.stream().anyMatch(this::isResolvable);
265+
}
266+
267+
@Override
268+
protected List<String> resolve() {
269+
if (resolve) {
270+
final List<String> resolvedList = new ArrayList<>(list.size());
271+
272+
for (final String entry : list) {
273+
resolvedList.add(resolveVars(entry, vars));
274+
}
275+
276+
return resolvedList;
277+
}
278+
else {
279+
return list;
264280
}
265281
}
266282

267-
return map;
268283
}
269284

270-
private Map<String, String> resolveOptions(final Map<String, String> options) {
271-
final Map<String, String> map = new LinkedHashMap<>(options.size());
285+
private static class Options extends AbstractResolvable<Map<String, String>> {
286+
287+
private final Map<String, String> map = new LinkedHashMap<>();
288+
private final Map<String, String> vars;
289+
private final boolean resolve;
290+
291+
private Options(final org.metafacture.metafix.fix.Options options, final Map<String, String> vars) {
292+
this.vars = vars;
293+
294+
boolean resolveTemp = false;
295+
296+
if (options != null) {
297+
final List<String> keys = options.getKeys();
298+
final List<String> values = options.getValues();
272299

273-
for (final Map.Entry<String, String> entry : options.entrySet()) {
274-
map.put(resolveVars(entry.getKey()), resolveVars(entry.getValue()));
300+
for (int i = 0; i < keys.size(); ++i) {
301+
final String key = keys.get(i);
302+
final String value = values.get(i);
303+
304+
map.put(key, value);
305+
306+
if (!resolveTemp && (isResolvable(key) || isResolvable(value))) {
307+
resolveTemp = true;
308+
}
309+
}
310+
}
311+
312+
resolve = resolveTemp;
313+
}
314+
315+
@Override
316+
protected Map<String, String> resolve() {
317+
if (resolve) {
318+
final Map<String, String> resolvedMap = new LinkedHashMap<>(map.size());
319+
320+
for (final Map.Entry<String, String> entry : map.entrySet()) {
321+
resolvedMap.put(resolveVars(entry.getKey(), vars), resolveVars(entry.getValue(), vars));
322+
}
323+
324+
return resolvedMap;
325+
}
326+
else {
327+
return map;
328+
}
275329
}
276330

277-
return map;
278331
}
279332

280333
}

0 commit comments

Comments
 (0)