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

Commit

Permalink
Add from_json()/to_json() Fix functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwinter committed Jul 8, 2022
1 parent bec6763 commit fc4fd5b
Show file tree
Hide file tree
Showing 7 changed files with 410 additions and 40 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,18 @@ Only keeps field values that match the regular expression pattern.
filter("<sourceField>", "<regexp>")
```

##### `from_json`

Replaces the string with its JSON deserialization.

Options:

- `error_string`: Error message as a placeholder if the JSON couldn't be parsed. (Default: `null`)

```perl
from_json("<sourceField>"[, error_string: "<errorValue>"])
```

##### `index`

Returns the index position of a substring in a field and replaces the field value with this number.
Expand All @@ -473,7 +485,7 @@ Options:

- `to`: ISBN format to convert to (either `ISBN10` or `ISBN13`). (Default: Only normalize ISBN)
- `verify_check_digit`: Whether the check digit should be verified. (Default: `false`)
- `error_string`: Error message as a placeholder if the ISBN couln't be validated. (Default: `null`)
- `error_string`: Error message as a placeholder if the ISBN couldn't be validated. (Default: `null`)

```perl
isbn("<sourceField>"[, to: "<isbnFormat>"][, verify_check_digit: "<boolean>"][, error_string: "<errorValue>"])
Expand Down Expand Up @@ -555,6 +567,19 @@ Sums numbers in an array and replaces the field value with this number.
sum("<sourceField>")
```

##### `to_json`

Replaces the value with its JSON serialization.

Options:

- `error_string`: Error message as a placeholder if the JSON couldn't be generated. (Default: `null`)
- `pretty`: Whether to use pretty printing. (Default: `false`)

```perl
to_json("<sourceField>"[, pretty: "<boolean>"][, error_string: "<errorValue>"])
```

##### `trim`

Deletes whitespace at the beginning and the end of a field value.
Expand Down
5 changes: 3 additions & 2 deletions metafix/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ def passSystemProperties = {
}

dependencies {
implementation "org.eclipse.xtext:org.eclipse.xtext:${versions.xtext}"
implementation "org.eclipse.xtext:org.eclipse.xtext.xbase:${versions.xtext}"
implementation "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
implementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}"
implementation "com.google.guava:guava:${versions.guava}"
implementation "org.eclipse.xtext:org.eclipse.xtext.xbase:${versions.xtext}"
implementation "org.eclipse.xtext:org.eclipse.xtext:${versions.xtext}"
implementation "org.slf4j:slf4j-api:${versions.slf4j}"

testImplementation "org.junit.jupiter:junit-jupiter-api:${versions.junit_jupiter}"
Expand Down
42 changes: 40 additions & 2 deletions metafix/src/main/java/org/metafacture/metafix/FixMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public enum FixMethod implements FixFunction {
public enum FixMethod implements FixFunction { // checkstyle-disable-line ClassDataAbstractionCoupling

// SCRIPT-LEVEL METHODS:

Expand Down Expand Up @@ -389,6 +389,24 @@ public void apply(final Metafix metafix, final Record record, final List<String>
);
}
},
from_json {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String errorString = options.get(ERROR_STRING_OPTION);
final JsonValue.Parser parser = new JsonValue.Parser();

record.transform(params.get(0), (m, c) -> m
.ifString(s -> {
try {
c.accept(parser.parse(s));
}
catch (final IOException e) {
c.accept(errorString != null ? new Value(errorString) : null);
}
})
);
}
},
index {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
Expand All @@ -401,7 +419,7 @@ 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 ISBN isbn = new ISBN();

withOption(options, "error_string", isbn::setErrorString);
withOption(options, ERROR_STRING_OPTION, isbn::setErrorString);
withOption(options, "to", isbn::setTo);
withOption(options, "verify_check_digit", isbn::setVerifyCheckDigit);

Expand Down Expand Up @@ -530,6 +548,24 @@ public void apply(final Metafix metafix, final Record record, final List<String>
);
}
},
to_json {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
final String errorString = options.get(ERROR_STRING_OPTION);
final boolean pretty = getBoolean(options, "pretty");

record.transform(params.get(0), (m, c) -> m
.orElse(v -> {
try {
c.accept(new Value(v.toJson(pretty)));
}
catch (final IOException e) {
c.accept(errorString != null ? new Value(errorString) : null);
}
})
);
}
},
trim {
@Override
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
Expand All @@ -556,6 +592,8 @@ 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 String ERROR_STRING_OPTION = "error_string";

private static final Random RANDOM = new Random();

}
87 changes: 87 additions & 0 deletions metafix/src/main/java/org/metafacture/metafix/JsonValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2022 hbz NRW
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.metafacture.metafix;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;

// TODO: Utilize JsonDecoder/JsonEncoder instead?

@FunctionalInterface
public interface JsonValue {

void toJson(JsonGenerator jsonGenerator);

default String toJson() throws IOException {
return toJson(false);
}

default String toJson(final boolean prettyPrinting) throws IOException {
final StringWriter writer = new StringWriter();
final JsonGenerator jsonGenerator = new JsonFactory().createGenerator(writer);
jsonGenerator.setPrettyPrinter(prettyPrinting ? new DefaultPrettyPrinter((SerializableString) null) : null);

try {
toJson(jsonGenerator);
}
catch (final UncheckedIOException e) {
throw e.getCause();
}

jsonGenerator.flush();

return writer.toString();
}

class Parser {

private static final ObjectMapper MAPPER = new ObjectMapper();

public Parser() {
}

public Value parse(final String source) throws IOException {
return parse(MAPPER.readTree(source));
}

private Value parse(final JsonNode node) {
final Value value;

if (node.isObject()) {
value = Value.newHash(h -> node.fields().forEachRemaining(e -> h.put(e.getKey(), parse(e.getValue()))));
}
else if (node.isArray()) {
value = Value.newArray(a -> node.elements().forEachRemaining(v -> a.add(parse(v))));
}
else {
value = new Value(node.textValue());
}

return value;
}

}

}
29 changes: 0 additions & 29 deletions metafix/src/main/java/org/metafacture/metafix/Record.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@
import org.metafacture.metafix.FixPath.InsertMode;
import org.metafacture.metafix.Value.TypeMatcher;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -118,27 +110,6 @@ public String toString() {
return super.toString();
}

public String toJson() throws IOException {
return toJson(false);
}

public String toJson(final boolean prettyPrinting) throws IOException {
final StringWriter writer = new StringWriter();
final JsonGenerator jsonGenerator = new JsonFactory().createGenerator(writer);
jsonGenerator.setPrettyPrinter(prettyPrinting ? new DefaultPrettyPrinter((SerializableString) null) : null);

try {
toJson(jsonGenerator);
}
catch (final UncheckedIOException e) {
throw e.getCause();
}

jsonGenerator.flush();

return writer.toString();
}

/**
* Retrieves the field value from this record. Falls back to retrieving the
* <i>virtual</i> field if the field name is not already
Expand Down
14 changes: 8 additions & 6 deletions metafix/src/main/java/org/metafacture/metafix/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
* Represents a record value, i.e., either an {@link Array}, a {@link Hash},
* or a {@link String}.
*/
public class Value { // checkstyle-disable-line ClassDataAbstractionCoupling
public class Value implements JsonValue { // checkstyle-disable-line ClassDataAbstractionCoupling

private static final String FIELD_PATH_SEPARATOR = "\\.";

Expand Down Expand Up @@ -248,7 +248,8 @@ public String toString() {
);
}

private void toJson(final JsonGenerator jsonGenerator) {
@Override
public void toJson(final JsonGenerator jsonGenerator) {
if (isNull()) {
try {
jsonGenerator.writeNull();
Expand Down Expand Up @@ -357,7 +358,7 @@ private <T> TypeMatcher match(final Type type, final Consumer<T> consumer, final

}

private abstract static class AbstractValueType {
private abstract static class AbstractValueType implements JsonValue {

protected static final Predicate<Value> REMOVE_EMPTY_VALUES = v ->
v.extractType((m, c) -> m
Expand All @@ -383,7 +384,8 @@ private abstract static class AbstractValueType {
@Override
public abstract String toString();

protected abstract void toJson(JsonGenerator jsonGenerator);
@Override
public abstract void toJson(JsonGenerator jsonGenerator);

}

Expand Down Expand Up @@ -459,7 +461,7 @@ public String toString() {
}

@Override
protected void toJson(final JsonGenerator jsonGenerator) {
public void toJson(final JsonGenerator jsonGenerator) {
try {
jsonGenerator.writeStartArray();
forEach(v -> v.toJson(jsonGenerator));
Expand Down Expand Up @@ -737,7 +739,7 @@ public String toString() {
}

@Override
protected void toJson(final JsonGenerator jsonGenerator) {
public void toJson(final JsonGenerator jsonGenerator) {
try {
jsonGenerator.writeStartObject();

Expand Down
Loading

0 comments on commit fc4fd5b

Please sign in to comment.