Skip to content

Commit f631e84

Browse files
committed
Transform records in-place.
1 parent 90cbde4 commit f631e84

File tree

6 files changed

+59
-63
lines changed

6 files changed

+59
-63
lines changed

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.metafacture.metafix;
1818

1919
import org.metafacture.metafix.api.FixContext;
20-
import org.metafacture.metafix.fix.Expression;
2120

2221
import java.util.List;
2322
import java.util.Map;
@@ -26,8 +25,7 @@ public enum FixBind implements FixContext {
2625

2726
list {
2827
@Override
29-
public void execute(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options, final List<Expression> expressions) {
30-
final RecordTransformer recordTransformer = metafix.getRecordTransformer();
28+
public void execute(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options, final RecordTransformer recordTransformer) {
3129
final String scopeVariable = options.get("var");
3230
Value.asList(record.get(options.get("path")), a -> {
3331
for (int i = 0; i < a.size(); ++i) {
@@ -36,7 +34,7 @@ public void execute(final Metafix metafix, final Record record, final List<Strin
3634
// with var -> keep full record in scope, add the var:
3735
if (scopeVariable != null) {
3836
record.put(scopeVariable, value);
39-
recordTransformer.process(expressions);
37+
recordTransformer.transform(record);
4038
record.remove(scopeVariable);
4139
}
4240
// w/o var -> use the currently bound value as the record:
@@ -48,10 +46,7 @@ public void execute(final Metafix metafix, final Record record, final List<Strin
4846
final Record scopeRecord = new Record();
4947
scopeRecord.addAll(h);
5048

51-
recordTransformer.setRecord(scopeRecord);
52-
recordTransformer.process(expressions);
53-
recordTransformer.setRecord(record);
54-
49+
recordTransformer.transform(scopeRecord);
5550
a.set(index, new Value(scopeRecord));
5651
})
5752
// TODO: bind to arrays (if that makes sense) and strings (access with '.')

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@
1717
package org.metafacture.metafix;
1818

1919
import org.metafacture.metafix.api.FixFunction;
20-
import org.metafacture.metafix.fix.Fix;
2120
import org.metafacture.metamorph.api.Maps;
2221
import org.metafacture.metamorph.maps.FileMap;
2322

2423
import java.io.File;
2524
import java.util.Arrays;
2625
import java.util.Collections;
2726
import java.util.Comparator;
28-
import java.util.HashMap;
2927
import java.util.List;
3028
import java.util.Map;
3129
import java.util.Random;
@@ -52,9 +50,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
5250
// TODO: Catmandu load path
5351
final String includePath = metafix.resolvePath(includeFile);
5452

55-
final RecordTransformer recordTransformer = metafix.getRecordTransformer();
56-
recordTransformer.setRecord(recordTransformer.transformRecord(
57-
INCLUDE_FIX.computeIfAbsent(includePath, FixStandaloneSetup::parseFix)));
53+
metafix.getRecordTransformer(includePath).transform(record);
5854
}
5955
},
6056
nothing {
@@ -499,6 +495,4 @@ public void apply(final Metafix metafix, final Record record, final List<String>
499495

500496
private static final Random RANDOM = new Random();
501497

502-
private static final Map<String, Fix> INCLUDE_FIX = new HashMap<>();
503-
504498
}

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

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.metafacture.framework.helpers.DefaultStreamReceiver;
2525
import org.metafacture.mangling.StreamFlattener;
2626
import org.metafacture.metafix.fix.Expression;
27-
import org.metafacture.metafix.fix.Fix;
2827
import org.metafacture.metamorph.api.Maps;
2928

3029
import org.slf4j.Logger;
@@ -48,8 +47,8 @@
4847
import java.util.function.BiConsumer;
4948

5049
/**
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.
5352
*
5453
* @author Markus Michael Geipel (Metamorph)
5554
* @author Christoph Böhme (Metamorph)
@@ -73,12 +72,12 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
7372
private final Deque<Integer> entityCountStack = new LinkedList<>();
7473
private final List<Closeable> resources = new ArrayList<>();
7574
private final List<Expression> expressions = new ArrayList<>();
75+
private final Map<String, RecordTransformer> fixCache = new HashMap<>();
7676
private final Map<String, Map<String, String>> maps = new HashMap<>();
7777
private final Map<String, String> vars = new HashMap<>();
78-
private final RecordTransformer recordTransformer = new RecordTransformer(this);
78+
private final RecordTransformer recordTransformer;
7979
private final StreamFlattener flattener = new StreamFlattener();
8080

81-
private Fix fix;
8281
private List<Value> entities = new ArrayList<>();
8382
private Record currentRecord = new Record();
8483
private StreamReceiver outputStreamReceiver;
@@ -88,37 +87,27 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
8887
private int entityCount;
8988

9089
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);
10291
}
10392

10493
public Metafix(final Map<String, String> newVars) {
105-
this();
106-
vars.putAll(newVars);
94+
init(newVars);
95+
recordTransformer = null;
10796
}
10897

10998
public Metafix(final String fixDef) throws FileNotFoundException {
11099
this(fixDef, NO_VARS);
111100
}
112101

113102
public Metafix(final String fixDef, final Map<String, String> vars) throws FileNotFoundException {
114-
this(vars);
103+
init(vars);
115104

116105
if (isFixFile(fixDef)) {
117106
fixFile = fixDef;
118-
fix = FixStandaloneSetup.parseFix(fixDef);
107+
recordTransformer = getRecordTransformer(fixDef);
119108
}
120109
else {
121-
fix = FixStandaloneSetup.parseFix(new StringReader(fixDef));
110+
recordTransformer = getRecordTransformer(new StringReader(fixDef));
122111
}
123112
}
124113

@@ -127,8 +116,25 @@ public Metafix(final Reader fixDef) {
127116
}
128117

129118
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);
132138
}
133139

134140
/*package-private*/ static boolean isFixFile(final String fixDef) {
@@ -149,8 +155,12 @@ public String resolvePath(final String path) {
149155
}
150156
}
151157

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));
154164
}
155165

156166
public List<Expression> getExpressions() {
@@ -177,8 +187,8 @@ public void endRecord() {
177187
throw new IllegalStateException(ENTITIES_NOT_BALANCED);
178188
}
179189
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);
182192
if (!currentRecord.getReject()) {
183193
outputStreamReceiver.startRecord(recordIdentifier);
184194
LOG.debug("Sending results to {}", outputStreamReceiver);

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

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,29 @@ public class RecordTransformer { // checkstyle-disable-line ClassFanOutComplexit
5757

5858
private static final Logger LOG = LoggerFactory.getLogger(RecordTransformer.class);
5959

60+
private final List<Expression> expressions;
6061
private final Map<String, String> vars;
6162
private final Metafix metafix;
6263

6364
private Record record;
6465

65-
/*package-private*/ RecordTransformer(final Metafix metafix) {
66-
this.metafix = metafix;
67-
vars = metafix.getVars();
68-
}
69-
70-
/*package-private*/ Record transform(final Fix fix) {
71-
setRecord(metafix.getCurrentRecord().shallowClone());
72-
return transformRecord(fix);
66+
/*package-private*/ RecordTransformer(final Metafix metafix, final Fix fix) {
67+
this(metafix, fix.getElements());
7368
}
7469

75-
public Record transformRecord(final Fix fix) {
76-
process(fix.getElements());
77-
return record;
70+
private RecordTransformer(final Metafix metafix, final List<Expression> expressions) {
71+
this.expressions = expressions;
72+
this.metafix = metafix;
73+
vars = metafix.getVars();
7874
}
7975

80-
public void setRecord(final Record record) {
81-
this.record = record;
76+
public void transform(final Record currentRecord) {
77+
this.record = currentRecord;
78+
process(expressions);
8279
}
8380

84-
public void process(final List<Expression> expressions) {
85-
expressions.forEach(e -> {
81+
private void process(final List<Expression> currentExpressions) {
82+
currentExpressions.forEach(e -> {
8683
final List<String> params = resolveParams(e.getParams());
8784

8885
if (e instanceof Do) {
@@ -106,7 +103,7 @@ else if (e instanceof MethodCall) {
106103
private void processDo(final Do expression, final List<String> params) {
107104
processExpression(expression, name -> {
108105
final FixContext context = getInstance(name, FixContext.class, FixBind::valueOf);
109-
context.execute(metafix, record, params, options(expression.getOptions()), expression.getElements());
106+
context.execute(metafix, record, params, options(expression.getOptions()), new RecordTransformer(metafix, expression.getElements()));
110107
});
111108

112109
// TODO, possibly: use morph collectors here

metafix/src/main/java/org/metafacture/metafix/api/FixContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
import org.metafacture.metafix.Metafix;
2020
import org.metafacture.metafix.Record;
21-
import org.metafacture.metafix.fix.Expression;
21+
import org.metafacture.metafix.RecordTransformer;
2222

2323
import java.util.List;
2424
import java.util.Map;
2525

2626
@FunctionalInterface
2727
public interface FixContext {
2828

29-
void execute(Metafix metafix, Record record, List<String> params, Map<String, String> options, List<Expression> expressions);
29+
void execute(Metafix metafix, Record record, List<String> params, Map<String, String> options, RecordTransformer recordTransformer);
3030

3131
}

metafix/src/test/java/org/metafacture/metafix/util/TestContext.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
import org.metafacture.metafix.Metafix;
2020
import org.metafacture.metafix.Record;
21+
import org.metafacture.metafix.RecordTransformer;
2122
import org.metafacture.metafix.Value;
2223
import org.metafacture.metafix.api.FixContext;
23-
import org.metafacture.metafix.fix.Expression;
2424

2525
import java.util.List;
2626
import java.util.Map;
@@ -31,9 +31,9 @@ public TestContext() {
3131
}
3232

3333
@Override
34-
public void execute(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options, final List<Expression> expressions) {
34+
public void execute(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options, final RecordTransformer recordTransformer) {
3535
record.add("BEFORE", new Value(params.get(0)));
36-
metafix.getRecordTransformer().process(expressions);
36+
recordTransformer.transform(record);
3737
record.add("AFTER", new Value(options.get("data")));
3838
}
3939

0 commit comments

Comments
 (0)