Skip to content

Commit

Permalink
[WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
vkhrystiuk-ks committed Dec 31, 2024
1 parent 37670fc commit d5f14b3
Show file tree
Hide file tree
Showing 21 changed files with 394 additions and 95 deletions.
2 changes: 1 addition & 1 deletion src/main/java/liqp/filters/date/BasicDateParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public abstract class BasicDateParser {
this.put("9th", "9");
this.put("0th", "0");
}};
protected String removeSequentialSuffixes(String input) {
public static String removeSequentialSuffixes(String input) {
for (Map.Entry<String, String> entry : toBeReplaced.entrySet()) {
input = input.replaceAll("(?i)"+entry.getKey(), entry.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

public class DatePatternRecognizingContext {

final Locale locale;
Boolean hasYear;
Boolean hasMonth;
Boolean hasDay;
Boolean weekDay;
Boolean hasTime;
public final Locale locale;
public Boolean hasYear;
public Boolean hasMonth;
public Boolean hasDate;
public Boolean weekDay;
public Boolean hasTime;

public DatePatternRecognizingContext(Locale locale) {
if (locale == null) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/liqp/filters/date/fuzzy/LookupResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ class LookupResult {
this.parts = parts;
this.found = found;
}

public String getName() {
return name;
}
}
17 changes: 16 additions & 1 deletion src/main/java/liqp/filters/date/fuzzy/Part.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public String toString() {
class RecognizedPart implements Part {
final int start;
final int end;
private final List<String> patterns;
protected final List<String> patterns;
public final String source;

RecognizedPart(int start, int end, List<String> patterns, String source) {
Expand Down Expand Up @@ -145,4 +145,19 @@ public String toString() {
'}';
}
}

class RecognizedMonthNamePart extends RecognizedPart {
RecognizedMonthNamePart(int start, int end, List<String> patterns, String source) {
super(start, end, patterns, source);
}

@Override
public String toString() {
return "RecognizedMonthNamePart{" +
"start=" + start +
", end=" + end +
", pattern='" + patterns + '\'' +
'}';
}
}
}
3 changes: 1 addition & 2 deletions src/main/java/liqp/filters/date/fuzzy/PartExtractor.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package liqp.filters.date.fuzzy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
Expand All @@ -9,7 +8,7 @@

public interface PartExtractor {

PartExtractorResult extract(String source);
PartExtractorResult extract(String source, List<Part> parts, int i);

default List<String> newList(String... el) {
return Arrays.asList(el);
Expand Down
45 changes: 21 additions & 24 deletions src/main/java/liqp/filters/date/fuzzy/PartRecognizer.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package liqp.filters.date.fuzzy;

import static liqp.filters.date.fuzzy.extractors.Extractors.allYMDPatternExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.fullMonthExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.fullWeekdaysExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.monthDateExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.monthExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.plainYearExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.regularTimeExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.shortMonthExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.shortWeekdaysExtractor;
import static liqp.filters.date.fuzzy.extractors.Extractors.yearWithEraExtractor;

Expand All @@ -14,6 +14,7 @@
import java.util.List;
import liqp.filters.date.fuzzy.Part.NewPart;
import liqp.filters.date.fuzzy.Part.PunctuationPart;
import liqp.filters.date.fuzzy.Part.RecognizedMonthNamePart;
import liqp.filters.date.fuzzy.Part.RecognizedPart;
import liqp.filters.date.fuzzy.Part.UnrecognizedPart;
import liqp.filters.date.fuzzy.extractors.PartExtractorResult;
Expand Down Expand Up @@ -58,7 +59,7 @@ List<Part> recognizePart(List<Part> parts, DatePatternRecognizingContext ctx) {
if (result.found) {
ctx.hasYear = true;
ctx.hasMonth = true;
ctx.hasDay = true;
ctx.hasDate = true;
return result.parts;
}
}
Expand All @@ -72,41 +73,32 @@ List<Part> recognizePart(List<Part> parts, DatePatternRecognizingContext ctx) {
// last "year check" and since we are here - there is no year
ctx.hasYear = false;
}
if (notSet(ctx.hasMonth)) {
LookupResult result = lookup(parts, fullMonthExtractor.get(ctx.locale));
if (result.found) {
ctx.hasMonth = true;
return result.parts;
}

result = lookup(parts, shortMonthExtractor.get(ctx.locale));
if (notSet(ctx.hasMonth)) {
LookupResult result = lookup(parts, monthExtractor.get(ctx.locale));
if (result.found) {
ctx.hasMonth = true;
return result.parts;
}

ctx.hasMonth = false;
}

if (notSet(ctx.hasDay)) {
LookupResult result = lookup(parts, fullMonthExtractor.get(ctx.locale));
if (isTrue(ctx.hasMonth) && notSet(ctx.hasDate)) {
LookupResult result = lookup(parts, monthDateExtractor.get(ctx.locale));
if (result.found) {
ctx.hasDay = true;
ctx.hasDate = true;
return result.parts;
}

result = lookup(parts, shortMonthExtractor.get(ctx.locale));
if (result.found) {
ctx.hasDay = true;
return result.parts;
}

ctx.hasDay = false;
ctx.hasDate = false;
}

return markAsUnrecognized(parts);
}

private boolean isTrue(Boolean hasMonth) {
return hasMonth != null && hasMonth;
}

private boolean notSet(Boolean val) {
return val == null;
}
Expand All @@ -116,7 +108,7 @@ private LookupResult lookup(List<Part> parts, PartExtractor partExtractor) {

if (part.state() == Part.PartState.NEW) {
String source = part.source();
PartExtractorResult per = partExtractor.extract(source);
PartExtractorResult per = partExtractor.extract(source, parts, i);
if (per.found) {
parts.remove(i);

Expand All @@ -125,7 +117,12 @@ private LookupResult lookup(List<Part> parts, PartExtractor partExtractor) {
parts.add(i, after);
}

RecognizedPart recognized = new RecognizedPart(part.start() + per.start, part.start() + per.end, per.formatterPatterns, source.substring(per.start, per.end));
RecognizedPart recognized;
if (per.isMonthName) {
recognized = new RecognizedMonthNamePart(part.start() + per.start, part.start() + per.end, per.formatterPatterns, source.substring(per.start, per.end));
} else {
recognized = new RecognizedPart(part.start() + per.start, part.start() + per.end, per.formatterPatterns, source.substring(per.start, per.end));
}
parts.add(i, recognized);

if (per.start != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.ArrayList;
import java.util.List;
import liqp.filters.date.fuzzy.Part;
import liqp.filters.date.fuzzy.PartExtractor;

public class AllYMDPatternExtractor implements PartExtractor {
Expand Down Expand Up @@ -51,9 +52,9 @@ public AllYMDPatternExtractor() {
}

@Override
public PartExtractorResult extract(String source) {
public PartExtractorResult extract(String source, List<Part> parts, int i) {
for (AnyYMDPatternExtractor extractor : extractors) {
PartExtractorResult result = extractor.extract(source);
PartExtractorResult result = extractor.extract(source, parts, i);
if (result.found) {
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import liqp.filters.date.fuzzy.Part;

class AnyYMDPatternExtractor extends RegexPartExtractor {

Expand Down Expand Up @@ -78,7 +79,7 @@ private static String reconstructPattern(RulePart[] partsInOrder) {
}

@Override
public PartExtractorResult extract(String source) {
public PartExtractorResult extract(String source, List<Part> parts, int i) {
Matcher matcher = pattern.matcher(source);
if (matcher.find()) {
PartExtractorResult result = new PartExtractorResult(name);
Expand Down
25 changes: 20 additions & 5 deletions src/main/java/liqp/filters/date/fuzzy/extractors/Extractors.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,35 @@ public PartExtractor get(Locale locale) {
return partExtractor;
}
},
fullMonthExtractor {
monthExtractor {
private final Map<Locale, PartExtractor> extractors = new HashMap<>();

@Override
public PartExtractor get(Locale locale) {
return extractors.computeIfAbsent(locale, l -> new FullMonthExtractor(locale));
return extractors.computeIfAbsent(locale, l -> new MonthExtractor(locale));
}
},
shortMonthExtractor {
private final Map<Locale, PartExtractor> extractors = new HashMap<>();
monthDateExtractor {
private final PartExtractor partExtractor = new MonthDateExtractor();
@Override
public PartExtractor get(Locale locale) {
return extractors.computeIfAbsent(locale, l -> new ShortMonthExtractor(locale));
return partExtractor;
}
},
// fullMonthExtractor {
// private final Map<Locale, PartExtractor> extractors = new HashMap<>();
// @Override
// public PartExtractor get(Locale locale) {
// return extractors.computeIfAbsent(locale, l -> new FullMonthExtractor(locale));
// }
// },
// shortMonthExtractor {
// private final Map<Locale, PartExtractor> extractors = new HashMap<>();
// @Override
// public PartExtractor get(Locale locale) {
// return extractors.computeIfAbsent(locale, l -> new ShortMonthExtractor(locale));
// }
// },
/**
* 2011-12-03
*
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package liqp.filters.date.fuzzy.extractors;

import java.util.List;
import java.util.regex.Matcher;
import liqp.filters.date.fuzzy.Part;
import liqp.filters.date.fuzzy.Part.RecognizedMonthNamePart;
import liqp.filters.date.fuzzy.Part.RecognizedPart;
import liqp.filters.date.fuzzy.PartExtractor;

public class MonthDateExtractor implements PartExtractor {

@Override
public PartExtractorResult extract(String source, List<Part> parts, int i) {
// closest right or closest left should be a month
if (rightIsMonth(parts, i)) {
return leftDateExtractor.extract(source, parts, i);
}
if (leftIsMonth(parts, i)) {
return rightDateExtractor.extract(source, parts, i);
}
return new PartExtractorResult("MonthDateExtractor");
}

private boolean leftIsMonth(List<Part> parts, int i) {
int left = i - 1;
while (left >= 0) {
Part part = parts.get(left);
if (part instanceof RecognizedMonthNamePart) {
return true;
}
if (part instanceof RecognizedPart) {
return false;
}
left--;
}
return false;
}

private boolean rightIsMonth(List<Part> parts, int i) {
int right = i + 1;
while (right < parts.size()) {
Part part = parts.get(right);
if (part instanceof RecognizedMonthNamePart) {
return true;
}
if (part instanceof RecognizedPart) {
return false;
}
right++;
}
return false;
}


private static final RegexPartExtractor leftDateExtractor = new MonthDatePartExtractor("MonthDayExtractor.left", "(?:^|.*?\\D)(?<day>0?[1-9]|[12][0-9]|3[01])\\D+?$");
private static final RegexPartExtractor rightDateExtractor = new MonthDatePartExtractor("MonthDayExtractor.right", "^\\D+?(?<day>0?[1-9]|[12][0-9]|3[01])(?:$|\\D.*?)");
private static class MonthDatePartExtractor extends RegexPartExtractor {

public MonthDatePartExtractor(String name, String regex) {
super(name, regex, null);
}

@Override
public PartExtractorResult extract(String source, List<Part> parts, int i) {
Matcher matcher = pattern.matcher(source);
if (matcher.find()) {
PartExtractorResult result = new PartExtractorResult(name);
result.found = true;
result.start = matcher.start("day");
result.end = matcher.end("day");
if (matcher.group("day").length() == 1) {
result.formatterPatterns = newList("d", "dd");
} else {
result.formatterPatterns = newList("dd", "d");
}
return result;
}
return new PartExtractorResult(name);
}
}
}
Loading

0 comments on commit d5f14b3

Please sign in to comment.