Skip to content
This repository has been archived by the owner on Jan 27, 2025. It is now read-only.

Commit

Permalink
Merge branch 'master' into 14-addJavaIntegration
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwinter committed Jan 26, 2022
2 parents 01cac68 + 1159022 commit 79ef8e6
Show file tree
Hide file tree
Showing 11 changed files with 859 additions and 333 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ subprojects {
'mockito': '2.27.0',
'requirejs': '2.3.6',
'slf4j': '1.7.21',
'xtext': '2.17.0',
'xtext': '2.26.0.M2',
'guava': '29.0-jre'
]
}
Expand Down
146 changes: 78 additions & 68 deletions metafix/src/main/java/org/metafacture/metafix/FixMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public enum FixMethod implements FixFunction {

Expand Down Expand Up @@ -122,7 +121,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>

record.getList(field, a -> record.put(field, Value.newHash(h -> {
for (int i = 1; i < a.size(); i = i + 2) {
h.put(a.get(i - 1).toString(), a.get(i));
h.put(a.get(i - 1).asString(), a.get(i));
}
})));
}
Expand All @@ -141,7 +140,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>

record.getList(field, a -> a.forEach(v -> {
final Pattern p = Pattern.compile(params.get(1));
final Matcher m = p.matcher(v.toString());
final Matcher m = p.matcher(v.asString());
if (m.matches()) {
record.remove(field);

Expand Down Expand Up @@ -179,7 +178,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
record.replace(params.get(0), params.subList(1, params.size()).stream()
.filter(f -> literalString(f) || record.find(f) != null)
.map(f -> literalString(f) ? new Value(f.substring(1)) : record.findList(f, null).asArray().get(0))
.map(Value::toString).collect(Collectors.joining(joinChar != null ? joinChar : " ")));
.map(Value::asString).collect(Collectors.joining(joinChar != null ? joinChar : " ")));
}

private boolean literalString(final String s) {
Expand All @@ -192,7 +191,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
final String field = params.get(0);
final int max = getInteger(params, 1);

record.append(field, String.valueOf(RANDOM.nextInt(max)));
record.replace(field, String.valueOf(RANDOM.nextInt(max)));
}
},
reject {
Expand All @@ -210,14 +209,32 @@ public void apply(final Metafix metafix, final Record record, final List<String>
rename {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> {
final String search = params.get(1);
final String replace = params.get(2);
final String search = params.get(1);
final String replace = params.get(2);

// TODO: recurse into arrays/values
return v.isHash() ? Value.newHash(h ->
v.asHash().forEach((f, w) -> h.put(f.replaceAll(search, replace), w))) : null;
});
final UnaryOperator<String> operator = s -> s.replaceAll(search, replace);

record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(renameArray(a, operator)))
.ifHash(h -> c.accept(renameHash(h, operator)))
.orElseThrow()
);
}

private Value renameArray(final Value.Array array, final UnaryOperator<String> operator) {
return Value.newArray(a -> array.forEach(v -> a.add(renameValue(v, operator))));
}

private Value renameHash(final Value.Hash hash, final UnaryOperator<String> operator) {
return Value.newHash(h -> hash.forEach((f, v) -> h.put(operator.apply(f), renameValue(v, operator))));
}

private Value renameValue(final Value value, final UnaryOperator<String> operator) {
return value.extractType((m, c) -> m
.ifArray(a -> c.accept(renameArray(a, operator)))
.ifHash(h -> c.accept(renameHash(h, operator)))
.orElse(c)
);
}
},
retain {
Expand All @@ -242,10 +259,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
set_field {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String field = params.get(0);

record.remove(field);
record.replace(field, params.get(1));
record.replace(params.get(0), params.get(1));
}
},
set_hash {
Expand Down Expand Up @@ -291,8 +305,10 @@ public void apply(final Metafix metafix, final Record record, final List<String>
count {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v ->
v.isArray() ? new Value(v.asArray().size()) : v.isHash() ? new Value(v.asHash().size()) : null);
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(new Value(a.size())))
.ifHash(h -> c.accept(new Value(h.size())))
);
}
},
downcase {
Expand All @@ -304,13 +320,14 @@ public void apply(final Metafix metafix, final Record record, final List<String>
filter {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> {
final Pattern search = Pattern.compile(params.get(1));
final boolean invert = getBoolean(options, "invert");
final Pattern search = Pattern.compile(params.get(1));
final boolean invert = getBoolean(options, "invert");

final Predicate<Value> predicate = s -> search.matcher(s.asString()).find();
return v.isArray() ? newArray(v.asArray().stream().filter(invert ? predicate.negate() : predicate)) : null;
});
final Predicate<Value> predicate = s -> search.matcher(s.asString()).find();

record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(newArray(a.stream().filter(invert ? predicate.negate() : predicate))))
);
}
},
index {
Expand All @@ -323,10 +340,10 @@ public void apply(final Metafix metafix, final Record record, final List<String>
join_field {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> {
final String joinChar = params.size() > 1 ? params.get(1) : "";
return v.isArray() ? new Value(v.asArray().stream().map(Value::toString).collect(Collectors.joining(joinChar))) : null;
});
final String joinChar = params.size() > 1 ? params.get(1) : "";
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(new Value(a.stream().map(Value::asString).collect(Collectors.joining(joinChar)))))
);
}
},
lookup {
Expand Down Expand Up @@ -370,57 +387,47 @@ public void apply(final Metafix metafix, final Record record, final List<String>
reverse {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> {
final Value result;

if (v.isString()) {
result = new Value(new StringBuilder(v.asString()).reverse().toString());
}
else if (v.isArray()) {
final List<Value> list = v.asArray().stream().collect(Collectors.toList());
Collections.reverse(list);
result = new Value(list);
}
else {
result = null;
}

return result;
});
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> {
final List<Value> list = a.stream().collect(Collectors.toList());
Collections.reverse(list);
c.accept(new Value(list));
})
.ifString(s -> c.accept(new Value(new StringBuilder(s).reverse().toString())))
);
}
},
sort_field {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> {
final boolean numeric = getBoolean(options, "numeric");
final boolean reverse = getBoolean(options, "reverse");
final boolean uniq = getBoolean(options, "uniq");
final boolean numeric = getBoolean(options, "numeric");
final boolean reverse = getBoolean(options, "reverse");
final boolean uniq = getBoolean(options, "uniq");

final Stream<Value> stream = v.asArray().stream();
final Function<Value, String> function = Value::asString;
final Comparator<Value> comparator = numeric ?
Comparator.comparing(function.andThen(Integer::parseInt)) : Comparator.comparing(function);
final Function<Value, String> function = Value::asString;
final Comparator<Value> comparator = numeric ?
Comparator.comparing(function.andThen(Integer::parseInt)) : Comparator.comparing(function);

return v.isArray() ? new Value((uniq ? unique(stream) : stream)
.sorted(reverse ? comparator.reversed() : comparator).collect(Collectors.toList())) : null;
});
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(new Value((uniq ? unique(a.stream()) : a.stream())
.sorted(reverse ? comparator.reversed() : comparator).collect(Collectors.toList()))))
);
}
},
split_field {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> {
final String splitChar = params.size() > 1 ? params.get(1) : "\\s+";
final Pattern splitPattern = Pattern.compile(splitChar);
final String splitChar = params.size() > 1 ? params.get(1) : "\\s+";
final Pattern splitPattern = Pattern.compile(splitChar);

final UnaryOperator<Value> splitOperator = s ->
newArray(Arrays.stream(splitPattern.split(s.asString())).map(Value::new));
final Function<String, Value> splitFunction = s ->
newArray(Arrays.stream(splitPattern.split(s)).map(Value::new));

return v.isString() ? splitOperator.apply(v) : v.isArray() ?
newArray(v.asArray().stream().map(splitOperator)) : v.isHash() ?
Value.newHash(h -> v.asHash().forEach((f, s) -> h.put(f, splitOperator.apply(s)))) : null;
});
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(newArray(a.stream().map(Value::asString).map(splitFunction))))
.ifHash(h -> c.accept(Value.newHash(n -> h.forEach((f, w) -> n.put(f, splitFunction.apply(w.asString()))))))
.ifString(s -> c.accept(splitFunction.apply(s)))
);
}
},
substring {
Expand All @@ -432,8 +439,9 @@ public void apply(final Metafix metafix, final Record record, final List<String>
sum {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v ->
v.isArray() ? new Value(v.asArray().stream().map(Value::asString).mapToInt(Integer::parseInt).sum()) : null);
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(new Value(a.stream().map(Value::asString).mapToInt(Integer::parseInt).sum())))
);
}
},
trim {
Expand All @@ -445,7 +453,9 @@ public void apply(final Metafix metafix, final Record record, final List<String>
uniq {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), v -> v.isArray() ? newArray(unique(v.asArray().stream())) : null);
record.transformField(params.get(0), (m, c) -> m
.ifArray(a -> c.accept(newArray(unique(a.stream()))))
);
}
},
upcase {
Expand Down
38 changes: 24 additions & 14 deletions metafix/src/main/java/org/metafacture/metafix/Metafix.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
private int entityCount;
private StreamReceiver outputStreamReceiver;
private String recordIdentifier;
private List<Value.Hash> entities = new ArrayList<>();
private List<Value> entities = new ArrayList<>();

public Metafix() {
flattener.setReceiver(new DefaultStreamReceiver() {
Expand Down Expand Up @@ -132,7 +132,7 @@ public void startRecord(final String identifier) {
public void endRecord() {
entityCountStack.removeLast();
if (!entityCountStack.isEmpty()) {
throw new IllegalStateException(ENTITIES_NOT_BALANCED);
throw new MetafactureException(new IllegalStateException(ENTITIES_NOT_BALANCED));
}
flattener.endRecord();
LOG.debug("End record, walking fix: {}", currentRecord);
Expand Down Expand Up @@ -172,20 +172,33 @@ private void emit(final String field, final Value value) {
});
}

private void addValue(final String name, final Value value) {
final int index = entityCountStack.peek() - 1;
if (index < 0 || entities.size() <= index) {
currentRecord.add(name, value);
}
else {
entities.get(index).matchType()
.ifArray(a -> a.add(value))
.ifHash(h -> h.add(name, value))
.orElseThrow();
}
}

@Override
public void startEntity(final String name) {
if (name == null) {
throw new IllegalArgumentException("Entity name must not be null.");
}
++entityCount;
final Integer currentEntityIndex = entityCountStack.peek() - 1;
final Value.Hash previousEntity = currentEntityIndex < 0 ||
entities.size() <= currentEntityIndex ? null : entities.get(currentEntityIndex);
entityCountStack.push(Integer.valueOf(entityCount));

final Value value = name.endsWith(ARRAY_MARKER) ? Value.newArray() : Value.newHash();
// TODO: Remove array marker? => name.substring(0, name.length() - ARRAY_MARKER.length());

addValue(name, value);
entities.add(value);

entityCountStack.push(Integer.valueOf(++entityCount));
flattener.startEntity(name);
final Value value = Value.newHash();
(previousEntity != null ? previousEntity : currentRecord).add(name, value);
entities.add(value.asHash());
}

@Override
Expand All @@ -197,10 +210,7 @@ public void endEntity() {
@Override
public void literal(final String name, final String value) {
LOG.debug("Putting '{}': '{}'", name, value);
final Integer currentEntityIndex = entityCountStack.peek() - 1;
final Value.Hash currentEntity = currentEntityIndex < 0 ||
entities.size() <= currentEntityIndex ? null : entities.get(currentEntityIndex);
(currentEntity != null ? currentEntity : currentRecord).add(name, new Value(value));
addValue(name, new Value(value));
// TODO: keep flattener as option?
// flattener.literal(name, value);
}
Expand Down
Loading

0 comments on commit 79ef8e6

Please sign in to comment.