Skip to content

Commit 0ae9cf1

Browse files
authored
Merge pull request #242 from metafacture/addFromJsonToJsonFunctions
Add `from_json()`/`to_json()` Fix functions.
2 parents c20f3e6 + 709877a commit 0ae9cf1

File tree

7 files changed

+411
-41
lines changed

7 files changed

+411
-41
lines changed

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,18 @@ Flattens a nested array field.
497497
flatten("<sourceField>")
498498
```
499499

500+
##### `from_json`
501+
502+
Replaces the string with its JSON deserialization.
503+
504+
Options:
505+
506+
- `error_string`: Error message as a placeholder if the JSON couldn't be parsed. (Default: `null`)
507+
508+
```perl
509+
from_json("<sourceField>"[, error_string: "<errorValue>"])
510+
```
511+
500512
##### `index`
501513

502514
Returns the index position of a substring in a field and replaces the field value with this number.
@@ -513,7 +525,7 @@ Options:
513525

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

518530
```perl
519531
isbn("<sourceField>"[, to: "<isbnFormat>"][, verify_check_digit: "<boolean>"][, error_string: "<errorValue>"])
@@ -595,6 +607,19 @@ Sums numbers in an array and replaces the field value with this number.
595607
sum("<sourceField>")
596608
```
597609

610+
##### `to_json`
611+
612+
Replaces the value with its JSON serialization.
613+
614+
Options:
615+
616+
- `error_string`: Error message as a placeholder if the JSON couldn't be generated. (Default: `null`)
617+
- `pretty`: Whether to use pretty printing. (Default: `false`)
618+
619+
```perl
620+
to_json("<sourceField>"[, pretty: "<boolean>"][, error_string: "<errorValue>"])
621+
```
622+
598623
##### `trim`
599624

600625
Deletes whitespace at the beginning and the end of a field value.

metafix/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ def passSystemProperties = {
1010
}
1111

1212
dependencies {
13-
implementation "org.eclipse.xtext:org.eclipse.xtext:${versions.xtext}"
14-
implementation "org.eclipse.xtext:org.eclipse.xtext.xbase:${versions.xtext}"
1513
implementation "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
14+
implementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}"
1615
implementation "com.google.guava:guava:${versions.guava}"
16+
implementation "org.eclipse.xtext:org.eclipse.xtext.xbase:${versions.xtext}"
17+
implementation "org.eclipse.xtext:org.eclipse.xtext:${versions.xtext}"
1718
implementation "org.slf4j:slf4j-api:${versions.slf4j}"
1819

1920
testImplementation "org.junit.jupiter:junit-jupiter-api:${versions.junit_jupiter}"

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

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import java.util.regex.Pattern;
4242
import java.util.stream.Collectors;
4343

44-
public enum FixMethod implements FixFunction {
44+
public enum FixMethod implements FixFunction { // checkstyle-disable-line ClassDataAbstractionCoupling|ClassFanOutComplexity
4545

4646
// SCRIPT-LEVEL METHODS:
4747

@@ -422,6 +422,24 @@ public void apply(final Metafix metafix, final Record record, final List<String>
422422
);
423423
}
424424
},
425+
from_json {
426+
@Override
427+
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
428+
final String errorString = options.get(ERROR_STRING_OPTION);
429+
final JsonValue.Parser parser = new JsonValue.Parser();
430+
431+
record.transform(params.get(0), (m, c) -> m
432+
.ifString(s -> {
433+
try {
434+
c.accept(parser.parse(s));
435+
}
436+
catch (final IOException e) {
437+
c.accept(errorString != null ? new Value(errorString) : null);
438+
}
439+
})
440+
);
441+
}
442+
},
425443
index {
426444
@Override
427445
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
@@ -434,7 +452,7 @@ public void apply(final Metafix metafix, final Record record, final List<String>
434452
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
435453
final ISBN isbn = new ISBN();
436454

437-
withOption(options, "error_string", isbn::setErrorString);
455+
withOption(options, ERROR_STRING_OPTION, isbn::setErrorString);
438456
withOption(options, "to", isbn::setTo);
439457
withOption(options, "verify_check_digit", isbn::setVerifyCheckDigit);
440458

@@ -563,6 +581,24 @@ public void apply(final Metafix metafix, final Record record, final List<String>
563581
);
564582
}
565583
},
584+
to_json {
585+
@Override
586+
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
587+
final String errorString = options.get(ERROR_STRING_OPTION);
588+
final boolean pretty = getBoolean(options, "pretty");
589+
590+
record.transform(params.get(0), (m, c) -> m
591+
.orElse(v -> {
592+
try {
593+
c.accept(new Value(v.toJson(pretty)));
594+
}
595+
catch (final IOException e) {
596+
c.accept(errorString != null ? new Value(errorString) : null);
597+
}
598+
})
599+
);
600+
}
601+
},
566602
trim {
567603
@Override
568604
public void apply(final Metafix metafix, final Record record, final List<String> params, final Map<String, String> options) {
@@ -589,6 +625,8 @@ public void apply(final Metafix metafix, final Record record, final List<String>
589625
private static final String FILEMAP_SEPARATOR_OPTION = "sep_char";
590626
private static final String FILEMAP_DEFAULT_SEPARATOR = ",";
591627

628+
private static final String ERROR_STRING_OPTION = "error_string";
629+
592630
private static final Random RANDOM = new Random();
593631

594632
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2022 hbz NRW
3+
*
4+
* Licensed under the Apache License, Version 2.0 the "License";
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.metafacture.metafix;
18+
19+
import com.fasterxml.jackson.core.JsonFactory;
20+
import com.fasterxml.jackson.core.JsonGenerator;
21+
import com.fasterxml.jackson.core.SerializableString;
22+
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
23+
import com.fasterxml.jackson.databind.JsonNode;
24+
import com.fasterxml.jackson.databind.ObjectMapper;
25+
26+
import java.io.IOException;
27+
import java.io.StringWriter;
28+
import java.io.UncheckedIOException;
29+
30+
// TODO: Utilize JsonDecoder/JsonEncoder instead?
31+
32+
@FunctionalInterface
33+
public interface JsonValue {
34+
35+
void toJson(JsonGenerator jsonGenerator);
36+
37+
default String toJson() throws IOException {
38+
return toJson(false);
39+
}
40+
41+
default String toJson(final boolean prettyPrinting) throws IOException {
42+
final StringWriter writer = new StringWriter();
43+
final JsonGenerator jsonGenerator = new JsonFactory().createGenerator(writer);
44+
jsonGenerator.setPrettyPrinter(prettyPrinting ? new DefaultPrettyPrinter((SerializableString) null) : null);
45+
46+
try {
47+
toJson(jsonGenerator);
48+
}
49+
catch (final UncheckedIOException e) {
50+
throw e.getCause();
51+
}
52+
53+
jsonGenerator.flush();
54+
55+
return writer.toString();
56+
}
57+
58+
class Parser {
59+
60+
private static final ObjectMapper MAPPER = new ObjectMapper();
61+
62+
public Parser() {
63+
}
64+
65+
public Value parse(final String source) throws IOException {
66+
return parse(MAPPER.readTree(source));
67+
}
68+
69+
private Value parse(final JsonNode node) {
70+
final Value value;
71+
72+
if (node.isObject()) {
73+
value = Value.newHash(h -> node.fields().forEachRemaining(e -> h.put(e.getKey(), parse(e.getValue()))));
74+
}
75+
else if (node.isArray()) {
76+
value = Value.newArray(a -> node.elements().forEachRemaining(v -> a.add(parse(v))));
77+
}
78+
else {
79+
value = new Value(node.textValue());
80+
}
81+
82+
return value;
83+
}
84+
85+
}
86+
87+
}

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

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,6 @@
1919
import org.metafacture.metafix.FixPath.InsertMode;
2020
import org.metafacture.metafix.Value.TypeMatcher;
2121

22-
import com.fasterxml.jackson.core.JsonFactory;
23-
import com.fasterxml.jackson.core.JsonGenerator;
24-
import com.fasterxml.jackson.core.SerializableString;
25-
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
26-
27-
import java.io.IOException;
28-
import java.io.StringWriter;
29-
import java.io.UncheckedIOException;
3022
import java.util.Collection;
3123
import java.util.Deque;
3224
import java.util.LinkedHashMap;
@@ -118,27 +110,6 @@ public String toString() {
118110
return super.toString();
119111
}
120112

121-
public String toJson() throws IOException {
122-
return toJson(false);
123-
}
124-
125-
public String toJson(final boolean prettyPrinting) throws IOException {
126-
final StringWriter writer = new StringWriter();
127-
final JsonGenerator jsonGenerator = new JsonFactory().createGenerator(writer);
128-
jsonGenerator.setPrettyPrinter(prettyPrinting ? new DefaultPrettyPrinter((SerializableString) null) : null);
129-
130-
try {
131-
toJson(jsonGenerator);
132-
}
133-
catch (final UncheckedIOException e) {
134-
throw e.getCause();
135-
}
136-
137-
jsonGenerator.flush();
138-
139-
return writer.toString();
140-
}
141-
142113
/**
143114
* Retrieves the field value from this record. Falls back to retrieving the
144115
* <i>virtual</i> field if the field name is not already

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
* Represents a record value, i.e., either an {@link Array}, a {@link Hash},
4949
* or a {@link String}.
5050
*/
51-
public class Value { // checkstyle-disable-line ClassDataAbstractionCoupling
51+
public class Value implements JsonValue { // checkstyle-disable-line ClassDataAbstractionCoupling
5252

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

@@ -248,7 +248,8 @@ public String toString() {
248248
);
249249
}
250250

251-
private void toJson(final JsonGenerator jsonGenerator) {
251+
@Override
252+
public void toJson(final JsonGenerator jsonGenerator) {
252253
if (isNull()) {
253254
try {
254255
jsonGenerator.writeNull();
@@ -357,7 +358,7 @@ private <T> TypeMatcher match(final Type type, final Consumer<T> consumer, final
357358

358359
}
359360

360-
private abstract static class AbstractValueType {
361+
private abstract static class AbstractValueType implements JsonValue {
361362

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

386-
protected abstract void toJson(JsonGenerator jsonGenerator);
387+
@Override
388+
public abstract void toJson(JsonGenerator jsonGenerator);
387389

388390
}
389391

@@ -459,7 +461,7 @@ public String toString() {
459461
}
460462

461463
@Override
462-
protected void toJson(final JsonGenerator jsonGenerator) {
464+
public void toJson(final JsonGenerator jsonGenerator) {
463465
try {
464466
jsonGenerator.writeStartArray();
465467
forEach(v -> v.toJson(jsonGenerator));
@@ -737,7 +739,7 @@ public String toString() {
737739
}
738740

739741
@Override
740-
protected void toJson(final JsonGenerator jsonGenerator) {
742+
public void toJson(final JsonGenerator jsonGenerator) {
741743
try {
742744
jsonGenerator.writeStartObject();
743745

0 commit comments

Comments
 (0)