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

Commit

Permalink
Extract find* and transform* methods from Value.Hash (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
fsteeg committed Feb 3, 2022
1 parent 4be871b commit 5cbe20a
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 130 deletions.
3 changes: 1 addition & 2 deletions metafix/src/main/java/org/metafacture/metafix/FixBind.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public enum FixBind implements FixContext {
public void execute(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options, final List<Expression> expressions) {
final RecordTransformer recordTransformer = metafix.getRecordTransformer();
final String scopeVariable = options.get("var");

record.findList(options.get("path"), a -> {
Value.asList(new Path(options.get("path")).findInHash(record), a -> {
for (int i = 0; i < a.size(); ++i) {
final Value value = a.get(i);

Expand Down
42 changes: 21 additions & 21 deletions metafix/src/main/java/org/metafacture/metafix/FixMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ public void apply(final Metafix metafix, final Record record, final List<String>
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String joinChar = options.get("join_char");
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))
.filter(f -> literalString(f) || new Path(f).findInHash(record) != null)
.map(f -> literalString(f) ? new Value(f.substring(1)) : Value.asList(new Path(f).findInHash(record), null).asArray().get(0))
.map(Value::asString).collect(Collectors.joining(joinChar != null ? joinChar : " ")));
}

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

final UnaryOperator<String> operator = s -> s.replaceAll(search, replace);

record.transformField(params.get(0), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(renameArray(a, operator)))
.ifHash(h -> c.accept(renameHash(h, operator)))
.orElseThrow()
Expand Down Expand Up @@ -334,19 +334,19 @@ public void apply(final Metafix metafix, final Record record, final List<String>
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String value = params.get(1);
record.transformField(params.get(0), s -> s + value);
new Path(params.get(0)).transformInHash(record, s -> s + value);
}
},
capitalize {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), s -> s.substring(0, 1).toUpperCase() + s.substring(1));
new Path(params.get(0)).transformInHash(record, s -> s.substring(0, 1).toUpperCase() + s.substring(1));
}
},
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), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(new Value(a.size())))
.ifHash(h -> c.accept(new Value(h.size())))
);
Expand All @@ -355,7 +355,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
downcase {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), s -> s.toLowerCase());
new Path(params.get(0)).transformInHash(record, s -> s.toLowerCase());
}
},
filter {
Expand All @@ -366,7 +366,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>

final Predicate<Value> predicate = s -> search.matcher(s.asString()).find();

record.transformField(params.get(0), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(newArray(a.stream().filter(invert ? predicate.negate() : predicate))))
);
}
Expand All @@ -375,14 +375,14 @@ public void apply(final Metafix metafix, final Record record, final List<String>
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String search = params.get(1);
record.transformField(params.get(0), s -> String.valueOf(s.indexOf(search))); // TODO: multiple
new Path(params.get(0)).transformInHash(record, s -> String.valueOf(s.indexOf(search))); // TODO: multiple
}
},
join_field {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String joinChar = params.size() > 1 ? params.get(1) : "";
record.transformField(params.get(0), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(new Value(a.stream().map(Value::asString).collect(Collectors.joining(joinChar)))))
);
}
Expand All @@ -406,14 +406,14 @@ public void apply(final Metafix metafix, final Record record, final List<String>
}

final String defaultValue = map.get(Maps.DEFAULT_MAP_KEY); // TODO: Catmandu uses 'default'
record.transformField(params.get(0), k -> map.getOrDefault(k, defaultValue));
new Path(params.get(0)).transformInHash(record, k -> map.getOrDefault(k, defaultValue));
}
},
prepend {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String value = params.get(1);
record.transformField(params.get(0), s -> value + s);
new Path(params.get(0)).transformInHash(record, s -> value + s);
}
},
replace_all {
Expand All @@ -422,13 +422,13 @@ public void apply(final Metafix metafix, final Record record, final List<String>
final String search = params.get(1);
final String replace = params.get(2);

record.transformField(params.get(0), s -> s.replaceAll(search, replace));
new Path(params.get(0)).transformInHash(record, s -> s.replaceAll(search, replace));
}
},
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), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> {
final List<Value> list = a.stream().collect(Collectors.toList());
Collections.reverse(list);
Expand All @@ -449,7 +449,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
final Comparator<Value> comparator = numeric ?
Comparator.comparing(function.andThen(Integer::parseInt)) : Comparator.comparing(function);

record.transformField(params.get(0), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(new Value((uniq ? unique(a.stream()) : a.stream())
.sorted(reverse ? comparator.reversed() : comparator).collect(Collectors.toList()))))
);
Expand All @@ -464,7 +464,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
final Function<String, Value> splitFunction = s ->
newArray(Arrays.stream(splitPattern.split(s)).map(Value::new));

record.transformField(params.get(0), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (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)))
Expand All @@ -474,35 +474,35 @@ public void apply(final Metafix metafix, final Record record, final List<String>
substring {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), s -> s.substring(getInteger(params, 1), getInteger(params, 2) - 1));
new Path(params.get(0)).transformInHash(record, s -> s.substring(getInteger(params, 1), getInteger(params, 2) - 1));
}
},
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), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(new Value(a.stream().map(Value::asString).mapToInt(Integer::parseInt).sum())))
);
}
},
trim {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), String::trim);
new Path(params.get(0)).transformInHash(record, String::trim);
}
},
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), (m, c) -> m
new Path(params.get(0)).transformInHash(record, (m, c) -> m
.ifArray(a -> c.accept(newArray(unique(a.stream()))))
);
}
},
upcase {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformField(params.get(0), s -> s.toUpperCase());
new Path(params.get(0)).transformInHash(record, s -> s.toUpperCase());
}
};

Expand Down
77 changes: 75 additions & 2 deletions metafix/src/main/java/org/metafacture/metafix/Path.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@

package org.metafacture.metafix;

import org.metafacture.metafix.Value.AbstractValueType.InsertMode;
import org.metafacture.metafix.Value.Array;
import org.metafacture.metafix.Value.Hash;
import org.metafacture.metafix.Value.TypeMatcher;

import java.util.Arrays;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;

/**
Expand All @@ -35,6 +40,10 @@ public Path(final String[] path) {
this.path = path;
}

public Path(final String path) {
this(Value.split(path));
}

public Value findInArray(final Value.Array array) {
final Value result;
if (path.length > 0) {
Expand Down Expand Up @@ -66,7 +75,7 @@ private Value findInValue(final Value value, final String[] p) {
// TODO: move impl into enum elements, here call only value.find
return value == null ? null : value.extractType((m, c) -> m
.ifArray(a -> c.accept(new Path(p).findInArray(a)))
.ifHash(h -> c.accept(h.find(p)))
.ifHash(h -> c.accept(new Path(p).findInHash(h)))
.orElse(c)
);
}
Expand Down Expand Up @@ -107,8 +116,72 @@ private void transformValueAt(final Array array, final int index, final String[]
.ifString(s -> array.set(index, operator != null ? new Value(operator.apply(s)) : null))
.orElse(v -> new Value.TypeMatcher(v)
.ifArray(a -> new Path(p).transformInArray(a, operator))
.ifHash(h -> h.transformPath(p, operator))
.ifHash(h -> new Path(p).transformInHash(h, operator))
.orElseThrow());
}
}

public Value findInHash(final Hash hash) {
final String field = path[0];
if (field.equals(ASTERISK)) {
// TODO: search in all elements of value.asHash()?
return new Path(tail(path)).findInHash(hash);
}
return path.length == 1 || !hash.containsField(field) ? hash.get(field) :
findNested(hash, field, tail(path));
}

private Value findNested(final Hash hash, final String field, final String[] remainingFields) {
final Value value = hash.get(field);
return value == null ? null : value.extractType((m, c) -> m
.ifArray(a -> c.accept(new Path(remainingFields).findInArray(a)))
.ifHash(h -> c.accept(new Path(remainingFields).findInHash(h)))
.orElseThrow()
);
}

public void transformInHash(final Hash hash, final BiConsumer<TypeMatcher, Consumer<Value>> consumer) {
final Value oldValue = findInHash(hash);

if (oldValue != null) {
final Value newValue = oldValue.extractType(consumer);

if (newValue != null) {
hash.insert(InsertMode.REPLACE, path, newValue);
}
}
}

public void transformInHash(final Hash hash, final UnaryOperator<String> operator) {
final String currentSegment = path[0];
final String[] remainingPath = tail(path);

if (currentSegment.equals(ASTERISK)) {
// TODO: search in all elements of value.asHash()?
new Path(remainingPath).transformInHash(hash, operator);
return;
}

hash.modifyFields(currentSegment, f -> {
final Value value = hash.getMap().get(f);

if (value != null) {
if (remainingPath.length == 0) {
hash.getMap().remove(f);

if (operator != null) {
value.matchType()
.ifString(s -> hash.append(f, operator.apply(s)))
.orElseThrow();
}
}
else {
new TypeMatcher(value)
.ifArray(a -> new Path(remainingPath).transformInArray(a, operator))
.ifHash(h -> new Path(remainingPath).transformInHash(h, operator))
.orElseThrow();
}
}
});
}
}
Loading

0 comments on commit 5cbe20a

Please sign in to comment.