Skip to content

Commit

Permalink
enahncement/fix based on use elsewhere
Browse files Browse the repository at this point in the history
  • Loading branch information
JuicyDragon committed Aug 19, 2024
1 parent 89d5ed3 commit d02aa52
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,37 +1,81 @@
package com.nuix.superutilities.misc;

import com.google.common.collect.ImmutableList;
import lombok.Getter;
import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Getter
public class PrimitiveTypeParser {
public static final Function<String, Object> jodaTimeAutomaticParsing = new Function<>() {
private final List<Pattern> formatValidators = List.of(
// yyyy-MM-dd'T'HH:mm:ss'Z'
private final List<Pair<Pattern, DateTimeFormatter>> formats = List.of(
// 2017-12-11T15:51:24Z
// 2022-04-20T17:12:37Z
Pattern.compile("^\\d{4}-[01][0-9]-[0-3][0-9][tT][0-2][0-9]:[0-5][0-9]:\\d{2}Z$"),
Pair.of(
Pattern.compile("^\\d{4}-[01][0-9]-[0-3][0-9][tT][0-2][0-9]:[0-5][0-9]:\\d{2}Z$"),
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(DateTimeZone.UTC)
),

// yyyy-MM-dd'T'HH:mm:ss.SSSZZ
// 2017-12-11T15:51:24.000-07:00
Pattern.compile("^\\d{4}-[01][0-9]-[0-3][0-9][tT][0-2][0-9]:[0-5][0-9]:\\d{2}\\.\\d{3}[+\\-]\\d{2}:\\d{2}$")
Pair.of(
Pattern.compile("^\\d{4}-[01][0-9]-[0-3][0-9][tT][0-2][0-9]:[0-5][0-9]:\\d{2}\\.\\d{3}[+\\-]\\d{2}:\\d{2}$"),
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").withZone(DateTimeZone.UTC)
),

// 6/26/2024 1:50:33 PM
Pair.of(
Pattern.compile("\\d{1,2}/\\d{1,2}/\\d{4}\\s{2}\\d{1,2}:\\d{2}:\\d{2} [AP]M"),
DateTimeFormat.forPattern("M/d/yyyy h:m:s a").withZone(DateTimeZone.UTC)
),

// 26 Jun 2024 13:50:33
Pair.of(
Pattern.compile("\\d{1,2}\\s{2}[A-Z][a-z]{2} \\d{4} \\d{2}:\\d{2}:\\d{2}"),
DateTimeFormat.forPattern("dd MMM yyyy HH:mm:ss").withZone(DateTimeZone.UTC)
)
);

@Override
public Object apply(String s) {
if (formatValidators.stream()
.noneMatch(p -> p.matcher(s.trim()).matches())) {
return null;
} else {
return DateTime.parse(s.trim());
for (Pair<Pattern, DateTimeFormatter> format : formats) {
Matcher matcher = format.getLeft().matcher(s);
if (matcher.matches()) {
return format.getRight().parseDateTime(s);
}
}
return null;
}
};

public static final Function<String, Object> durationAutomaticParsing = new Function<>() {
private final List<Pattern> formatValidators = List.of(
Pattern.compile("(?<hours>[0-9]{2}):(?<minutes>[0-9]{2}):(?<seconds>[0-9]{2})")
);

@Override
public Object apply(String s) {
for (Pattern pattern : formatValidators) {
Matcher m = pattern.matcher(s);
if (m.matches()) {
long hours = Long.parseLong(m.group("hours"));
long minutes = Long.parseLong(m.group("minutes"));
long seconds = Long.parseLong(m.group("seconds"));
long millis = ((hours * 3600) + (minutes * 60) + seconds) * 1000;
return new Duration(millis);
}
}
return null;
}
};

Expand Down Expand Up @@ -74,6 +118,19 @@ public Object apply(String s) {
}
};

public static final Function<String, Object> yesNoBooleanParser = new Function<>() {
private final Pattern formatValidator = Pattern.compile("^(yes)|(no)$", Pattern.CASE_INSENSITIVE);

@Override
public Object apply(String s) {
if (!formatValidator.matcher(s.trim().toLowerCase()).matches()) {
return null;
} else {
return Boolean.parseBoolean(s.trim());
}
}
};

@Getter(lazy = true)
private static final PrimitiveTypeParser standard = buildImmutableStandard();

Expand All @@ -86,9 +143,11 @@ private static PrimitiveTypeParser buildImmutableStandard() {
public static PrimitiveTypeParser buildStandardCopy() {
PrimitiveTypeParser result = new PrimitiveTypeParser();
result.getTypeParsers().add(jodaTimeAutomaticParsing);
result.getTypeParsers().add(durationAutomaticParsing);
result.getTypeParsers().add(numericParser);
result.getTypeParsers().add(decimalParser);
result.getTypeParsers().add(booleanParser);
result.getTypeParsers().add(yesNoBooleanParser);
return result;
}

Expand Down Expand Up @@ -122,15 +181,43 @@ public Object parse(String input) {
return parseWithFallback(input, input);
}

public void enrichInPlace(Map<String,Object> input) {
for(Map.Entry<String,Object> entry : input.entrySet()) {
public void enrichInPlace(Map<String, Object> input) {
for (Map.Entry<String, Object> entry : input.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String) {
String stringValue = (String) value;
Object parsedValue = parse(stringValue);
input.put(key, parsedValue);
}
}
}

public Map<String, Object> parseAndCopy(Map<String, ?> input) {
Map<String, Object> result = new HashMap<>();
for (Map.Entry<String, ?> entry : input.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if(value instanceof String) {
if (value instanceof String) {
String stringValue = (String) value;
Object parsedValue = parse(stringValue);
input.put(key,parsedValue);
result.put(key, parsedValue);
}
}
return result;
}

public Map<String, Object> parseAndCopy(Map<String, ?> input, Function<String, String> keyMapper) {
Map<String, Object> result = new HashMap<>();
for (Map.Entry<String, ?> entry : input.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String) {
String stringValue = (String) value;
Object parsedValue = parse(stringValue);
result.put(keyMapper.apply(key), parsedValue);
}
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void testTypeParsing() throws Exception {
);

for (String dateToParse : additionalDates) {
Object parsedDate = standardTypeParser.parse("2022-04-20T17:12:37Z");
Object parsedDate = standardTypeParser.parse(dateToParse);
assertTrue(parsedDate instanceof DateTime, String.format("%s did not parse into a DateTime", dateToParse));
}

Expand Down

0 comments on commit d02aa52

Please sign in to comment.