Skip to content

Commit c868528

Browse files
Merge pull request #160 from OP-TED/TEDEFO-4778/additional-efx-functions
TEDEFO 4778/additional efx functions
2 parents f877884 + 6c12c4a commit c868528

4 files changed

Lines changed: 235 additions & 0 deletions

File tree

src/main/java/eu/europa/ted/efx/interfaces/ScriptGenerator.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,13 @@ public DateExpression composeSubtraction(final DateExpression date,
926926
*/
927927
public TimeExpression composeToTimeConversion(StringExpression pop);
928928

929+
/**
930+
* Returns the current time as a time expression in the target language.
931+
*
932+
* @return A time expression representing the current time.
933+
*/
934+
public TimeExpression getCurrentTime();
935+
929936
// #endregion Time Functions ------------------------------------------------
930937

931938
// #region Duration Functions -----------------------------------------------
@@ -1029,6 +1036,25 @@ public DurationExpression composeSubtraction(final DurationExpression left,
10291036
public <T extends SequenceExpression> T composeDistinctValuesFunction(
10301037
T list, Class<T> listType);
10311038

1039+
/**
1040+
* Returns the target language script that counts the number of duplicate values in a sequence.
1041+
*
1042+
* @param sequence The sequence to count duplicates in.
1043+
* @return A numeric expression representing the number of duplicate values.
1044+
*/
1045+
public NumericExpression composeCountDuplicatesFunction(SequenceExpression sequence);
1046+
1047+
/**
1048+
* Returns the target language script that extracts the duplicate values from a sequence.
1049+
*
1050+
* @param <T> The type of the sequence expression.
1051+
* @param list The sequence to extract duplicates from.
1052+
* @param listType The class of the sequence expression type.
1053+
* @return A sequence containing only the values that appear more than once.
1054+
*/
1055+
public <T extends SequenceExpression> T composeGetDuplicatesFunction(
1056+
T list, Class<T> listType);
1057+
10321058
/**
10331059
* Returns the target language script that computes the union of two sequences
10341060
* (all values from both, with duplicates removed).

src/main/java/eu/europa/ted/efx/sdk2/EfxExpressionTranslatorV2.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,6 +2816,42 @@ public void exitCountDurationsFunction(CountDurationsFunctionContext ctx) {
28162816
this.stack.push(this.script.composeCountOperation(this.stack.pop(DurationSequenceExpression.class)));
28172817
}
28182818

2819+
@Override
2820+
public void exitLateBoundCountDuplicatesFunction(LateBoundCountDuplicatesFunctionContext ctx) {
2821+
this.stack.push(this.script.composeCountDuplicatesFunction(
2822+
this.stack.pop(this.resolveSequenceType(this.stack.peekType()))));
2823+
}
2824+
2825+
@Override
2826+
public void exitCountDuplicatesStringsFunction(CountDuplicatesStringsFunctionContext ctx) {
2827+
this.stack.push(this.script.composeCountDuplicatesFunction(this.stack.pop(StringSequenceExpression.class)));
2828+
}
2829+
2830+
@Override
2831+
public void exitCountDuplicatesBooleansFunction(CountDuplicatesBooleansFunctionContext ctx) {
2832+
this.stack.push(this.script.composeCountDuplicatesFunction(this.stack.pop(BooleanSequenceExpression.class)));
2833+
}
2834+
2835+
@Override
2836+
public void exitCountDuplicatesNumbersFunction(CountDuplicatesNumbersFunctionContext ctx) {
2837+
this.stack.push(this.script.composeCountDuplicatesFunction(this.stack.pop(NumericSequenceExpression.class)));
2838+
}
2839+
2840+
@Override
2841+
public void exitCountDuplicatesDatesFunction(CountDuplicatesDatesFunctionContext ctx) {
2842+
this.stack.push(this.script.composeCountDuplicatesFunction(this.stack.pop(DateSequenceExpression.class)));
2843+
}
2844+
2845+
@Override
2846+
public void exitCountDuplicatesTimesFunction(CountDuplicatesTimesFunctionContext ctx) {
2847+
this.stack.push(this.script.composeCountDuplicatesFunction(this.stack.pop(TimeSequenceExpression.class)));
2848+
}
2849+
2850+
@Override
2851+
public void exitCountDuplicatesDurationsFunction(CountDuplicatesDurationsFunctionContext ctx) {
2852+
this.stack.push(this.script.composeCountDuplicatesFunction(this.stack.pop(DurationSequenceExpression.class)));
2853+
}
2854+
28192855
@Override
28202856
public void exitNumberFromStringFunction(NumberFromStringFunctionContext ctx) {
28212857
this.stack.push(this.script.composeToNumberConversion(this.stack.pop(StringExpression.class)));
@@ -3197,6 +3233,11 @@ public void exitDateMinusDurationFunction(DateMinusDurationFunctionContext ctx)
31973233
this.exitDateDurationSubtraction();
31983234
}
31993235

3236+
@Override
3237+
public void exitCurrentDateFunction(CurrentDateFunctionContext ctx) {
3238+
this.stack.push(this.script.getCurrentDate());
3239+
}
3240+
32003241
@Override
32013242
public void exitYearFromDateFunction(YearFromDateFunctionContext ctx) {
32023243
this.stack.push(this.script.composeYearFunction(this.stack.pop(DateExpression.class)));
@@ -3221,6 +3262,11 @@ public void exitTimeFromStringFunction(TimeFromStringFunctionContext ctx) {
32213262
this.stack.push(this.script.composeToTimeConversion(this.stack.pop(StringExpression.class)));
32223263
}
32233264

3265+
@Override
3266+
public void exitCurrentTimeFunction(CurrentTimeFunctionContext ctx) {
3267+
this.stack.push(this.script.getCurrentTime());
3268+
}
3269+
32243270
@Override
32253271
public void exitHoursFromTimeFunction(HoursFromTimeFunctionContext ctx) {
32263272
this.stack.push(this.script.composeHoursFunction(this.stack.pop(TimeExpression.class)));
@@ -3316,6 +3362,50 @@ private <T extends SequenceExpression> void exitDistinctValuesFunction(Class<T>
33163362

33173363
// #endregion Distinct-values ------------------------------------------------
33183364

3365+
// #region Get-duplicates ---------------------------------------------------
3366+
3367+
@Override
3368+
public void exitStringGetDuplicatesFunction(StringGetDuplicatesFunctionContext ctx) {
3369+
this.exitGetDuplicatesFunction(StringSequenceExpression.class);
3370+
}
3371+
3372+
@Override
3373+
public void exitBooleanGetDuplicatesFunction(BooleanGetDuplicatesFunctionContext ctx) {
3374+
this.exitGetDuplicatesFunction(BooleanSequenceExpression.class);
3375+
}
3376+
3377+
@Override
3378+
public void exitNumericGetDuplicatesFunction(NumericGetDuplicatesFunctionContext ctx) {
3379+
this.exitGetDuplicatesFunction(NumericSequenceExpression.class);
3380+
}
3381+
3382+
@Override
3383+
public void exitDateGetDuplicatesFunction(DateGetDuplicatesFunctionContext ctx) {
3384+
this.exitGetDuplicatesFunction(DateSequenceExpression.class);
3385+
}
3386+
3387+
@Override
3388+
public void exitTimeGetDuplicatesFunction(TimeGetDuplicatesFunctionContext ctx) {
3389+
this.exitGetDuplicatesFunction(TimeSequenceExpression.class);
3390+
}
3391+
3392+
@Override
3393+
public void exitDurationGetDuplicatesFunction(DurationGetDuplicatesFunctionContext ctx) {
3394+
this.exitGetDuplicatesFunction(DurationSequenceExpression.class);
3395+
}
3396+
3397+
@Override
3398+
public void exitLateBoundGetDuplicatesFunction(LateBoundGetDuplicatesFunctionContext ctx) {
3399+
this.exitGetDuplicatesFunction(this.resolveSequenceType(this.stack.peekType()));
3400+
}
3401+
3402+
private <T extends SequenceExpression> void exitGetDuplicatesFunction(final Class<T> listType) {
3403+
final T list = this.stack.pop(listType);
3404+
this.stack.push(this.script.composeGetDuplicatesFunction(list, listType));
3405+
}
3406+
3407+
// #endregion Get-duplicates ------------------------------------------------
3408+
33193409
// #region Union ------------------------------------------------------------
33203410

33213411
@Override

src/main/java/eu/europa/ted/efx/xpath/XPathScriptGenerator.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ public BooleanExpression composeIsDistinctCondition(SequenceExpression sequence)
458458

459459
//#region Numeric functions -------------------------------------------------
460460

461+
@Override
462+
public NumericExpression composeCountDuplicatesFunction(final SequenceExpression sequence) {
463+
return new NumericExpression(
464+
"count(" + sequence.getScript() + ") - count(distinct-values(" + sequence.getScript() + "))");
465+
}
466+
461467
@Override
462468
public NumericExpression composeCountOperation(SequenceExpression list) {
463469
return new NumericExpression("count(" + list.getScript() + ")");
@@ -821,6 +827,11 @@ public TimeExpression composeToTimeConversion(StringExpression time) {
821827
return new TimeExpression("xs:time(" + time.getScript() + ")");
822828
}
823829

830+
@Override
831+
public TimeExpression getCurrentTime() {
832+
return new TimeExpression("current-time()");
833+
}
834+
824835
//#endregion Time functions -------------------------------------------------
825836

826837
//#region Duration functions ------------------------------------------------
@@ -864,6 +875,15 @@ public <T extends SequenceExpression> T composeDistinctValuesFunction(
864875
return Expression.instantiate("distinct-values(" + list.getScript() + ")", listType);
865876
}
866877

878+
@Override
879+
public <T extends SequenceExpression> T composeGetDuplicatesFunction(
880+
final T list, final Class<T> listType) {
881+
final String seq = list.getScript();
882+
return Expression.instantiate(
883+
"for $v in distinct-values(" + seq + ") return if (count(" + seq + "[. = $v]) > 1) then $v else ()",
884+
listType);
885+
}
886+
867887
@Override
868888
public <T extends SequenceExpression> T composeUnionFunction(T listOne,
869889
T listTwo, Class<T> listType) {

src/test/java/eu/europa/ted/efx/sdk2/EfxExpressionTranslatorV2Test.java

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,37 @@ void testDateFromStringFunction() {
24762476
"ND-Root", "date(BT-00-Text)");
24772477
}
24782478

2479+
@Test
2480+
void testCurrentDateFunction() {
2481+
testExpressionTranslationWithContext("current-date()", "ND-Root", "current-date()");
2482+
}
2483+
2484+
@Test
2485+
void testCurrentDateComparedToField() {
2486+
testExpressionTranslationWithContext(
2487+
"current-date() > PathNode/StartDateField/xs:date(text())",
2488+
"ND-Root", "current-date() > BT-00-StartDate");
2489+
}
2490+
2491+
@Test
2492+
void testCurrentDatePlusDuration() {
2493+
testExpressionTranslationWithContext(
2494+
"(current-date() + xs:dayTimeDuration('P30D'))",
2495+
"ND-Root", "add-duration(current-date(), P30D)");
2496+
}
2497+
2498+
@Test
2499+
void testYearFromCurrentDate() {
2500+
testExpressionTranslationWithContext("year-from-date(current-date())",
2501+
"ND-Root", "year(current-date())");
2502+
}
2503+
2504+
@Test
2505+
void testMonthFromCurrentDate() {
2506+
testExpressionTranslationWithContext("month-from-date(current-date())",
2507+
"ND-Root", "month(current-date())");
2508+
}
2509+
24792510
// #endregion: Date functions
24802511

24812512
// #region: Time functions --------------------------------------------------
@@ -2486,6 +2517,24 @@ void testTimeFromStringFunction() {
24862517
"ND-Root", "time(BT-00-Text)");
24872518
}
24882519

2520+
@Test
2521+
void testCurrentTimeFunction() {
2522+
testExpressionTranslationWithContext("current-time()", "ND-Root", "current-time()");
2523+
}
2524+
2525+
@Test
2526+
void testCurrentTimeComparedToField() {
2527+
testExpressionTranslationWithContext(
2528+
"current-time() > PathNode/StartTimeField/xs:time(text())",
2529+
"ND-Root", "current-time() > BT-00-StartTime");
2530+
}
2531+
2532+
@Test
2533+
void testHoursFromCurrentTime() {
2534+
testExpressionTranslationWithContext("hours-from-time(current-time())",
2535+
"ND-Root", "hours(current-time())");
2536+
}
2537+
24892538
// #endregion: Time functions
24902539

24912540
// #region Duration functions
@@ -2550,6 +2599,56 @@ void testDistinctValuesFunction_WithFieldReferences() {
25502599
"distinct-values(BT-00-Text)");
25512600
}
25522601

2602+
// #region: Count-duplicates
2603+
2604+
@Test
2605+
void testCountDuplicatesFunction_WithStringSequences() {
2606+
testExpressionTranslationWithContext(
2607+
"count(('one','two','one')) - count(distinct-values(('one','two','one')))", "ND-Root",
2608+
"count-duplicates(['one', 'two', 'one'])");
2609+
}
2610+
2611+
@Test
2612+
void testCountDuplicatesFunction_WithNumberSequences() {
2613+
testExpressionTranslationWithContext(
2614+
"count((1,2,3,2,3,4)) - count(distinct-values((1,2,3,2,3,4)))", "ND-Root",
2615+
"count-duplicates([1, 2, 3, 2, 3, 4])");
2616+
}
2617+
2618+
@Test
2619+
void testCountDuplicatesFunction_WithFieldReferences() {
2620+
testExpressionTranslationWithContext(
2621+
"count(PathNode/TextField/normalize-space(text())) - count(distinct-values(PathNode/TextField/normalize-space(text())))",
2622+
"ND-Root", "count-duplicates(BT-00-Text)");
2623+
}
2624+
2625+
// #endregion: Count-duplicates
2626+
2627+
// #region: Get-duplicates
2628+
2629+
@Test
2630+
void testGetDuplicatesFunction_WithStringSequences() {
2631+
testExpressionTranslationWithContext(
2632+
"for $v in distinct-values(('one','two','one')) return if (count(('one','two','one')[. = $v]) > 1) then $v else ()",
2633+
"ND-Root", "get-duplicates(['one', 'two', 'one'])");
2634+
}
2635+
2636+
@Test
2637+
void testGetDuplicatesFunction_WithNumberSequences() {
2638+
testExpressionTranslationWithContext(
2639+
"for $v in distinct-values((1,2,3,2,3,4)) return if (count((1,2,3,2,3,4)[. = $v]) > 1) then $v else ()",
2640+
"ND-Root", "get-duplicates([1, 2, 3, 2, 3, 4])");
2641+
}
2642+
2643+
@Test
2644+
void testGetDuplicatesFunction_WithFieldReferences() {
2645+
testExpressionTranslationWithContext(
2646+
"for $v in distinct-values(PathNode/TextField/normalize-space(text())) return if (count(PathNode/TextField/normalize-space(text())[. = $v]) > 1) then $v else ()",
2647+
"ND-Root", "get-duplicates(BT-00-Text)");
2648+
}
2649+
2650+
// #endregion: Get-duplicates
2651+
25532652
// #region: Union
25542653

25552654
@Test

0 commit comments

Comments
 (0)