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

Commit

Permalink
Add Fix functions from Catmandu Cheat Sheet.
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwinter committed Dec 23, 2021
1 parent 35e4e34 commit 00aca11
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 2 deletions.
165 changes: 163 additions & 2 deletions metafix/src/main/java/org/metafacture/metafix/FixMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,30 @@
import org.metafacture.metamorph.maps.FileMap;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

enum FixMethod {

// SCRIPT-LEVEL METHODS:

nothing {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
// do nothing
}
},
put_filemap {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String fileName = params.get(0);
Expand Down Expand Up @@ -160,6 +174,14 @@ private boolean literalString(final String s) {
return s.startsWith("~");
}
},
random {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String field = params.get(0);
final int max = getInteger(params, 1);

record.append(field, String.valueOf(RANDOM.nextInt(max)));
}
},
reject {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.setReject(true);
Expand All @@ -170,6 +192,18 @@ public void apply(final Metafix metafix, final Record record, final List<String>
params.forEach(record::removeNested);
}
},
rename {
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);

// TODO: recurse into arrays/values
return v.isHash() ? Value.newHash(h ->
v.asHash().forEach((f, w) -> h.put(f.replaceAll(search, replace), w))) : null;
});
}
},
retain {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.retainFields(params);
Expand All @@ -183,7 +217,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
record.addAll(field.replace(DOT_APPEND, EMPTY), toAdd);
}
else {
record.put(field, Value.newArray(a -> toAdd.forEach(s -> a.add(new Value(s)))));
record.put(field, newArray(toAdd.stream().map(Value::new)));
}
}
},
Expand Down Expand Up @@ -220,16 +254,46 @@ public void apply(final Metafix metafix, final Record record, final List<String>

// TODO SPEC: switch to morph-style named params in general?

append {
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.transformFields(params, s -> s + value);
}
},
capitalize {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformFields(params, s -> s.substring(0, 1).toUpperCase() + s.substring(1));
}
},
count {
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);
}
},
downcase {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformFields(params, String::toLowerCase);
}
},
filter {
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 boolean invert = getBoolean(options, "invert");

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

return v.isArray() ? newArray(v.asArray().stream().filter(invert ? predicate.negate() : predicate)) : null;
});
}
},
index {
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.transformFields(params, s -> String.valueOf(s.indexOf(search))); // TODO: multiple
}
},
lookup {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final Map<String, String> map;
Expand All @@ -251,16 +315,94 @@ public void apply(final Metafix metafix, final Record record, final List<String>
record.transformFields(params, k -> map.getOrDefault(k, defaultValue));
}
},
prepend {
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.transformFields(params, s -> value + s);
}
},
replace_all {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String search = params.get(1);
final String replace = params.get(2);

record.transformFields(params, s -> s.replaceAll(search, replace));
}
},
reverse {
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;
});
}
},
sort_field {
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 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);

return v.isArray() ? new Value((uniq ? unique(stream) : stream)
.sorted(reverse ? comparator.reversed() : comparator).collect(Collectors.toList())) : null;
});
}
},
split_field {
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 UnaryOperator<Value> splitOperator = s ->
newArray(Arrays.stream(splitPattern.split(s.asString())).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;
});
}
},
substring {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformFields(params, s -> s.substring(Integer.parseInt(params.get(1)), Integer.parseInt(params.get(2)) - 1));
record.transformFields(params, s -> s.substring(getInteger(params, 1), getInteger(params, 2) - 1));
}
},
sum {
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);
}
},
trim {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformFields(params, String::trim);
}
},
uniq {
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);
}
},
upcase {
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
record.transformFields(params, String::toUpperCase);
Expand All @@ -275,6 +417,25 @@ public void apply(final Metafix metafix, final Record record, final List<String>
private static final String FILEMAP_SEPARATOR_OPTION = "sep_char";
private static final String FILEMAP_DEFAULT_SEPARATOR = ",";

private static final Random RANDOM = new Random();

private static boolean getBoolean(final Map<String, String> options, final String key) {
return Boolean.parseBoolean(options.get(key));
}

private static int getInteger(final List<String> params, final int index) {
return Integer.parseInt(params.get(index));
}

private static Value newArray(final Stream<Value> stream) {
return Value.newArray(a -> stream.forEach(a::add));
}

private static Stream<Value> unique(final Stream<Value> stream) {
final Set<Value> set = new HashSet<>();
return stream.filter(set::add);
}

abstract void apply(Metafix metafix, Record record, List<String> params, Map<String, String> options);

}
16 changes: 16 additions & 0 deletions metafix/src/main/java/org/metafacture/metafix/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public Value(final String string) {
this.string = string;
}

public Value(final int integer) {
this(String.valueOf(integer));
}

public static Value newArray() {
return newArray(null);
}
Expand Down Expand Up @@ -819,6 +823,18 @@ private void appendValue(final String[] newName, final Value v) {
}
}

public void transformField(final String field, final UnaryOperator<Value> operator) {
final Value oldValue = find(field);

if (oldValue != null) {
final Value newValue = operator.apply(oldValue);

if (newValue != null) {
insert(InsertMode.REPLACE, split(field), newValue);
}
}
}

public void transformFields(final List<String> params, final UnaryOperator<String> operator) {
transformFields(split(params.get(0)), operator);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,4 +477,9 @@ public void characterClass() {
o.get().endRecord();
});
}

@Test
public void XXX() {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1743,4 +1743,8 @@ public void accessArrayOfObjectsByDoListBind() {
});
}

@Test
public void XXX() {
}

}

0 comments on commit 00aca11

Please sign in to comment.