From eadf425e03318cb7e7a4f0da7b0de442f466ebcf Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Tue, 6 May 2025 14:27:17 +0200 Subject: [PATCH 01/11] Extended ValueMapDecorator --- .../vml/es/aem/acm/core/code/Arguments.java | 3 +- .../es/aem/acm/core/code/CodeRepository.java | 3 +- .../core/code/ValueMapDecoratorExtended.java | 41 +++++++++++++++++++ .../aem/acm/core/repo/RepoResourceState.java | 4 +- .../vml/es/aem/acm/core/util/DateUtils.java | 28 +++++++++++++ 5 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java b/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java index 32564dd5..01f5d194 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java @@ -10,7 +10,6 @@ import java.util.LinkedHashMap; import java.util.Map; import org.apache.sling.api.resource.ValueMap; -import org.apache.sling.api.wrappers.ValueMapDecorator; public class Arguments implements Serializable { @@ -39,7 +38,7 @@ public ValueMap getValues() { for (Argument argument : definitions.values()) { props.put(argument.getName(), argument.getValue()); } - return new ValueMapDecorator(props); + return new ValueMapDecoratorExtended(props); } public T getValue(String name, Class type) { diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/CodeRepository.java b/core/src/main/java/com/vml/es/aem/acm/core/code/CodeRepository.java index 4831a082..cc7ddcf1 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/CodeRepository.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/CodeRepository.java @@ -20,7 +20,8 @@ public class CodeRepository { public @interface Config { @AttributeDefinition( name = "Class Links", - description = "Mapping of class prefixes to their corresponding documentation URLs in the format 'package=url'.") + description = + "Mapping of class prefixes to their corresponding documentation URLs in the format 'package=url'.") String[] classLinks() default { "com.vml.es.aem.acm.core=https://github.com/wttech/acm/blob/main/core/src/main/java", "org.apache.sling.api=https://github.com/apache/sling-org-apache-sling-api/tree/master/src/main/java" diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java new file mode 100644 index 00000000..88522c28 --- /dev/null +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java @@ -0,0 +1,41 @@ +package com.vml.es.aem.acm.core.code; + +import com.vml.es.aem.acm.core.util.DateUtils; +import java.time.LocalDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.Map; +import org.apache.sling.api.wrappers.ValueMapDecorator; + +public class ValueMapDecoratorExtended extends ValueMapDecorator { + /** + * Creates a new wrapper around a given map. + * + * @param base wrapped object + */ + public ValueMapDecoratorExtended(Map base) { + super(base); + } + + /** + * {@inheritDoc} + */ + public T get(String name, Class type) { + Object obj = get(name); + if (obj instanceof Date && type == LocalDateTime.class) { + // Convert Date to LocalDateTime + return (T) DateUtils.toLocalDateTime((Date) obj); + } else if (obj instanceof Calendar && type == LocalDateTime.class) { + // Convert Calendar to LocalDateTime + return (T) DateUtils.toLocalDateTime((Calendar) obj); + } else if (obj instanceof LocalDateTime && type == Date.class) { + // Convert LocalDateTime to Date + return (T) DateUtils.toDate((LocalDateTime) obj); + } else if (obj instanceof LocalDateTime && type == Calendar.class) { + // Convert LocalDateTime to Calendar + return (T) DateUtils.toCalendar((LocalDateTime) obj); + } else { + return super.get(name, type); + } + } +} diff --git a/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java b/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java index 0e49de9c..9f627217 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java @@ -1,5 +1,6 @@ package com.vml.es.aem.acm.core.repo; +import com.vml.es.aem.acm.core.code.ValueMapDecoratorExtended; import com.vml.es.aem.acm.core.util.StringUtil; import java.io.Serializable; import java.util.Map; @@ -8,7 +9,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.sling.api.resource.ValueMap; -import org.apache.sling.api.wrappers.ValueMapDecorator; /** * Immutable snapshot of a repository resource state (even not existing). @@ -25,7 +25,7 @@ public class RepoResourceState implements Serializable { public RepoResourceState(String path, boolean exists, Map properties) { this.path = path; this.exists = exists; - this.properties = new ValueMapDecorator(properties); + this.properties = new ValueMapDecoratorExtended(properties); } public String getPath() { diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java index 6bb21b58..ddbbdaac 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java @@ -84,8 +84,36 @@ public static Date toDate(Calendar calendar) { return Optional.ofNullable(calendar).map(Calendar::getTime).orElse(null); } + public static Date toDate(LocalDateTime localDateTime) { + return Optional.ofNullable(localDateTime) + .map(ldt -> Date.from(ldt.atZone(ZONE_ID).toInstant())) + .orElse(null); + } + + public static Calendar toCalendar(LocalDateTime localDateTime) { + return Optional.ofNullable(localDateTime) + .map(ldt -> { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(Date.from(ldt.atZone(ZONE_ID).toInstant())); + return calendar; + }) + .orElse(null); + } + public static boolean isInRange(LocalDateTime from, LocalDateTime now, long offsetMillis) { LocalDateTime to = from.plus(offsetMillis, ChronoUnit.MILLIS); return !now.isBefore(from) && !now.isAfter(to); } + + public static LocalDateTime toLocalDateTime(Date date) { + return Optional.ofNullable(date) + .map(d -> d.toInstant().atZone(ZONE_ID).toLocalDateTime()) + .orElse(null); + } + + public static LocalDateTime toLocalDateTime(Calendar calendar) { + return Optional.ofNullable(calendar) + .map(c -> c.toInstant().atZone(ZONE_ID).toLocalDateTime()) + .orElse(null); + } } From aeddab159697f73f8d9c21ef8d652d3740045ef0 Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Tue, 6 May 2025 15:26:08 +0200 Subject: [PATCH 02/11] string to localdatetime --- .../com/vml/es/aem/acm/core/code/Condition.java | 2 +- .../acm/core/code/ValueMapDecoratorExtended.java | 3 +++ .../com/vml/es/aem/acm/core/util/DateUtils.java | 14 +++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/Condition.java b/core/src/main/java/com/vml/es/aem/acm/core/code/Condition.java index b5a832b1..998a94f3 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/Condition.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/Condition.java @@ -308,7 +308,7 @@ public LocalTime dayEndTime() { // Date-based (predetermined/static) public boolean isDate(String dateString) { - ZonedDateTime localDateTime = DateUtils.localDateTimeFromString(dateString); + ZonedDateTime localDateTime = DateUtils.zonedDateTimeFromString(dateString); return isDate(localDateTime); } diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java index 88522c28..e19d072d 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java @@ -34,6 +34,9 @@ public T get(String name, Class type) { } else if (obj instanceof LocalDateTime && type == Calendar.class) { // Convert LocalDateTime to Calendar return (T) DateUtils.toCalendar((LocalDateTime) obj); + } else if (obj instanceof String && type == LocalDateTime.class) { + // Convert String to LocalDateTime + return (T) DateUtils.localDateTimeFromString((String) obj); } else { return super.get(name, type); } diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java index ddbbdaac..95156036 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java @@ -58,7 +58,7 @@ public static Date fromString(String text) { return Optional.ofNullable(text).map(DateUtils::fromStringInternal).orElse(null); } - public static ZonedDateTime localDateTimeFromString(String text) { + public static ZonedDateTime zonedDateTimeFromString(String text) { for (String format : LOCAL_DATE_TIME_FORMATS) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(TIMEZONE_ID)); try { @@ -70,6 +70,18 @@ public static ZonedDateTime localDateTimeFromString(String text) { throw new IllegalArgumentException(String.format("Cannot parse date '%s'!", text)); } + public static LocalDateTime localDateTimeFromString(String text) { + for (String format : LOCAL_DATE_TIME_FORMATS) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(TIMEZONE_ID)); + try { + return LocalDateTime.parse(text, formatter); + } catch (DateTimeParseException ignored) { + // ignore + } + } + throw new IllegalArgumentException(String.format("Cannot parse date '%s'!", text)); + } + public static Calendar toCalendar(Date date) { return Optional.ofNullable(date).map(DateUtils::toCalendarInternal).orElse(null); } From 1404b8735f4853199bc7a40636b80c901a15ad23 Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 09:42:12 +0200 Subject: [PATCH 03/11] left only important class casts --- .../core/code/ValueMapDecoratorExtended.java | 28 +++++++++---------- .../vml/es/aem/acm/core/util/DateUtils.java | 24 ++++++++++++---- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java index e19d072d..019202ae 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java @@ -1,6 +1,7 @@ package com.vml.es.aem.acm.core.code; import com.vml.es.aem.acm.core.util.DateUtils; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Calendar; import java.util.Date; @@ -20,23 +21,20 @@ public ValueMapDecoratorExtended(Map base) { /** * {@inheritDoc} */ + @SuppressWarnings("unchecked") public T get(String name, Class type) { - Object obj = get(name); - if (obj instanceof Date && type == LocalDateTime.class) { - // Convert Date to LocalDateTime - return (T) DateUtils.toLocalDateTime((Date) obj); - } else if (obj instanceof Calendar && type == LocalDateTime.class) { - // Convert Calendar to LocalDateTime - return (T) DateUtils.toLocalDateTime((Calendar) obj); - } else if (obj instanceof LocalDateTime && type == Date.class) { - // Convert LocalDateTime to Date - return (T) DateUtils.toDate((LocalDateTime) obj); - } else if (obj instanceof LocalDateTime && type == Calendar.class) { - // Convert LocalDateTime to Calendar - return (T) DateUtils.toCalendar((LocalDateTime) obj); - } else if (obj instanceof String && type == LocalDateTime.class) { + Object obj = get(name);if (obj instanceof String && type == LocalDateTime.class) { // Convert String to LocalDateTime - return (T) DateUtils.localDateTimeFromString((String) obj); + return (T) DateUtils.toLocalDateTime((String) obj); + } else if (obj instanceof String && type == Date.class) { + // Convert String to Date + return (T) DateUtils.fromString((String) obj); + } else if (obj instanceof String && type == Calendar.class) { + // Convert String to Calendar + return (T) DateUtils.toCalendar((String) obj); + } else if (obj instanceof String && type == LocalDate.class) { + // Convert String to LocalDate + return (T) DateUtils.toLocalDate((String) obj); } else { return super.get(name, type); } diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java index 95156036..04c91390 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java @@ -2,6 +2,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -70,7 +71,7 @@ public static ZonedDateTime zonedDateTimeFromString(String text) { throw new IllegalArgumentException(String.format("Cannot parse date '%s'!", text)); } - public static LocalDateTime localDateTimeFromString(String text) { + public static LocalDateTime toLocalDateTime(String text) { for (String format : LOCAL_DATE_TIME_FORMATS) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(TIMEZONE_ID)); try { @@ -102,11 +103,12 @@ public static Date toDate(LocalDateTime localDateTime) { .orElse(null); } - public static Calendar toCalendar(LocalDateTime localDateTime) { - return Optional.ofNullable(localDateTime) - .map(ldt -> { + public static Calendar toCalendar(String date) { + return Optional.ofNullable(date) + .map(d -> { + Date parsedDate = fromString(d); Calendar calendar = Calendar.getInstance(); - calendar.setTime(Date.from(ldt.atZone(ZONE_ID).toInstant())); + calendar.setTime(parsedDate); return calendar; }) .orElse(null); @@ -128,4 +130,16 @@ public static LocalDateTime toLocalDateTime(Calendar calendar) { .map(c -> c.toInstant().atZone(ZONE_ID).toLocalDateTime()) .orElse(null); } + + public static LocalDate toLocalDate(String obj) { + for (String format : LOCAL_DATE_TIME_FORMATS) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(TIMEZONE_ID)); + try { + return LocalDate.parse(obj, formatter); + } catch (DateTimeParseException ignored) { + // ignore + } + } + throw new IllegalArgumentException(String.format("Cannot parse date '%s'!", obj)); + } } From a28ed9d545d4bbd36d5e955705cd0c5e31cc0dbe Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 09:42:57 +0200 Subject: [PATCH 04/11] left only important class casts --- .../java/com/vml/es/aem/acm/core/util/DateUtils.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java index 04c91390..4bf221d2 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java @@ -119,18 +119,6 @@ public static boolean isInRange(LocalDateTime from, LocalDateTime now, long offs return !now.isBefore(from) && !now.isAfter(to); } - public static LocalDateTime toLocalDateTime(Date date) { - return Optional.ofNullable(date) - .map(d -> d.toInstant().atZone(ZONE_ID).toLocalDateTime()) - .orElse(null); - } - - public static LocalDateTime toLocalDateTime(Calendar calendar) { - return Optional.ofNullable(calendar) - .map(c -> c.toInstant().atZone(ZONE_ID).toLocalDateTime()) - .orElse(null); - } - public static LocalDate toLocalDate(String obj) { for (String format : LOCAL_DATE_TIME_FORMATS) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(TIMEZONE_ID)); From 2c872ef6f7f4008209d2a6e9c03c37b728eece1e Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 09:44:08 +0200 Subject: [PATCH 05/11] left only important class casts --- .../main/java/com/vml/es/aem/acm/core/util/DateUtils.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java index 4bf221d2..3ee81c40 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java @@ -97,12 +97,6 @@ public static Date toDate(Calendar calendar) { return Optional.ofNullable(calendar).map(Calendar::getTime).orElse(null); } - public static Date toDate(LocalDateTime localDateTime) { - return Optional.ofNullable(localDateTime) - .map(ldt -> Date.from(ldt.atZone(ZONE_ID).toInstant())) - .orElse(null); - } - public static Calendar toCalendar(String date) { return Optional.ofNullable(date) .map(d -> { From bbef0a43ea0e1f27ab5baea08ff615101806c73a Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 09:53:12 +0200 Subject: [PATCH 06/11] left only important class casts --- .../vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java index 019202ae..2f3e9ef8 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java @@ -23,7 +23,8 @@ public ValueMapDecoratorExtended(Map base) { */ @SuppressWarnings("unchecked") public T get(String name, Class type) { - Object obj = get(name);if (obj instanceof String && type == LocalDateTime.class) { + Object obj = get(name); + if (obj instanceof String && type == LocalDateTime.class) { // Convert String to LocalDateTime return (T) DateUtils.toLocalDateTime((String) obj); } else if (obj instanceof String && type == Date.class) { From 73f2e5dd7480b05882f7565669df7dd9fb16d4da Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 11:11:06 +0200 Subject: [PATCH 07/11] more conversions --- .../core/code/ValueMapDecoratorExtended.java | 42 ++++++++++++++++++- .../vml/es/aem/acm/core/util/DateUtils.java | 28 +++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java index 2f3e9ef8..d5abf188 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java @@ -3,6 +3,7 @@ import com.vml.es.aem.acm.core.util.DateUtils; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.Calendar; import java.util.Date; import java.util.Map; @@ -24,6 +25,43 @@ public ValueMapDecoratorExtended(Map base) { @SuppressWarnings("unchecked") public T get(String name, Class type) { Object obj = get(name); + // LocalDateTime conversion + if (obj instanceof Date && type == LocalDateTime.class) { + // Convert Date to LocalDateTime + return (T) DateUtils.toLocalDateTime((Date) obj); + } else if (obj instanceof Calendar && type == LocalDateTime.class) { + // Convert Calendar to LocalDateTime + return (T) DateUtils.toLocalDateTime((Calendar) obj); + } else if (obj instanceof LocalDateTime && type == Date.class) { + // Convert LocalDateTime to Date + return (T) DateUtils.toDate((LocalDateTime) obj); + } else if (obj instanceof LocalDateTime && type == Calendar.class) { + // Convert LocalDateTime to Calendar + return (T) DateUtils.toCalendar((LocalDateTime) obj); + } else if (obj instanceof LocalDateTime && type == LocalDate.class) { + // Convert LocalDateTime to LocalDate + return (T) ((LocalDateTime) obj).toLocalDate(); + } + + // LocalDate conversion + if (obj instanceof Date && type == LocalDate.class) { + // Convert Date to LocalDate + return (T) DateUtils.toLocalDateTime((Date) obj).toLocalDate(); + } else if (obj instanceof Calendar && type == LocalDate.class) { + // Convert Calendar to LocalDate + return (T) DateUtils.toLocalDateTime((Calendar) obj).toLocalDate(); + } else if (obj instanceof LocalDate && type == Date.class) { + // Convert LocalDate to Date + return (T) DateUtils.toDate(((LocalDate) obj).atTime(LocalTime.MIN)); + } else if (obj instanceof LocalDate && type == Calendar.class) { + // Convert LocalDate to Calendar + return (T) DateUtils.toCalendar(((LocalDate) obj).atTime(LocalTime.MIN)); + } else if (obj instanceof LocalDate && type == LocalDateTime.class) { + // Convert LocalDate to LocalDateTime + return (T) ((LocalDate) obj).atTime(LocalTime.MIN); + } + + // String conversion if (obj instanceof String && type == LocalDateTime.class) { // Convert String to LocalDateTime return (T) DateUtils.toLocalDateTime((String) obj); @@ -36,8 +74,8 @@ public T get(String name, Class type) { } else if (obj instanceof String && type == LocalDate.class) { // Convert String to LocalDate return (T) DateUtils.toLocalDate((String) obj); - } else { - return super.get(name, type); } + + return super.get(name, type); } } diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java index 3ee81c40..2b700ef4 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java @@ -97,6 +97,22 @@ public static Date toDate(Calendar calendar) { return Optional.ofNullable(calendar).map(Calendar::getTime).orElse(null); } + public static Date toDate(LocalDateTime localDateTime) { + return Optional.ofNullable(localDateTime) + .map(ldt -> Date.from(ldt.atZone(ZONE_ID).toInstant())) + .orElse(null); + } + + public static Calendar toCalendar(LocalDateTime localDateTime) { + return Optional.ofNullable(localDateTime) + .map(ldt -> { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(Date.from(ldt.atZone(ZONE_ID).toInstant())); + return calendar; + }) + .orElse(null); + } + public static Calendar toCalendar(String date) { return Optional.ofNullable(date) .map(d -> { @@ -113,6 +129,18 @@ public static boolean isInRange(LocalDateTime from, LocalDateTime now, long offs return !now.isBefore(from) && !now.isAfter(to); } + public static LocalDateTime toLocalDateTime(Date date) { + return Optional.ofNullable(date) + .map(d -> d.toInstant().atZone(ZONE_ID).toLocalDateTime()) + .orElse(null); + } + + public static LocalDateTime toLocalDateTime(Calendar calendar) { + return Optional.ofNullable(calendar) + .map(c -> c.toInstant().atZone(ZONE_ID).toLocalDateTime()) + .orElse(null); + } + public static LocalDate toLocalDate(String obj) { for (String format : LOCAL_DATE_TIME_FORMATS) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.of(TIMEZONE_ID)); From a3fd1aadde17f83fe179ebd8f45c0b18ac6fd928 Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 11:29:20 +0200 Subject: [PATCH 08/11] DateTime snippet --- .../available/core/argument/datetime.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml diff --git a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml new file mode 100644 index 00000000..758e1e2a --- /dev/null +++ b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml @@ -0,0 +1,19 @@ +group: Argument +name: argument_datetime +content: | + args.dateTime("${1:name}") { label = "${2:label}"; value = LocalDateTime.of(${3:value}); min = LocalDateTime.of(${4:min}); max = LocalDateTime.of(${5:max}); dateTime() } +documentation: | + An argument that represents a date and time.
+ The value parameter is the default value, while min and max define the range of acceptable values.
+ + The `dateTime()` method is used to specify the display mode for the argument.
+ Alternatively You can use `date()` method to display only the date
+ `dateTime()` is default display mode.
+ + For example: + ```groovy + args.dateTime("someDateTime") {label = "some date time"; value = LocalDateTime.of(2025,5,7,9,50,0); min = LocalDateTime.of(2025,5,7,9,40,0); max = LocalDateTime.of(2025,5,7,10,50,0); dateTime()} + args.dateTime("someDate") {label = "some date"; value = LocalDate.of(2025,5,3); min = LocalDate.of(2025,5,7); max = LocalDate.of(2025,5,12); date()} + args.dateTime("someDateTime") {label = "some date time"; value = LocalDateTime.of(2025,5,7,9,50,0)} + args.dateTime("someDateTime") {label = "some date time"} + ``` From bfe9adde0b2416559fc0580176413f9ba816447f Mon Sep 17 00:00:00 2001 From: "kamil.orwat" Date: Wed, 7 May 2025 11:44:00 +0200 Subject: [PATCH 09/11] renamed to ArgumentsValueMap --- .../src/main/java/com/vml/es/aem/acm/core/code/Arguments.java | 2 +- ...{ValueMapDecoratorExtended.java => ArgumentsValueMap.java} | 4 ++-- .../java/com/vml/es/aem/acm/core/repo/RepoResourceState.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename core/src/main/java/com/vml/es/aem/acm/core/code/{ValueMapDecoratorExtended.java => ArgumentsValueMap.java} (96%) diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java b/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java index 01f5d194..5da9e8ce 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java @@ -38,7 +38,7 @@ public ValueMap getValues() { for (Argument argument : definitions.values()) { props.put(argument.getName(), argument.getValue()); } - return new ValueMapDecoratorExtended(props); + return new ArgumentsValueMap(props); } public T getValue(String name, Class type) { diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentsValueMap.java similarity index 96% rename from core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java rename to core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentsValueMap.java index d5abf188..747e5699 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/ValueMapDecoratorExtended.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentsValueMap.java @@ -9,13 +9,13 @@ import java.util.Map; import org.apache.sling.api.wrappers.ValueMapDecorator; -public class ValueMapDecoratorExtended extends ValueMapDecorator { +public class ArgumentsValueMap extends ValueMapDecorator { /** * Creates a new wrapper around a given map. * * @param base wrapped object */ - public ValueMapDecoratorExtended(Map base) { + public ArgumentsValueMap(Map base) { super(base); } diff --git a/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java b/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java index 9f627217..c8e7f05c 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/repo/RepoResourceState.java @@ -1,6 +1,6 @@ package com.vml.es.aem.acm.core.repo; -import com.vml.es.aem.acm.core.code.ValueMapDecoratorExtended; +import com.vml.es.aem.acm.core.code.ArgumentsValueMap; import com.vml.es.aem.acm.core.util.StringUtil; import java.io.Serializable; import java.util.Map; @@ -25,7 +25,7 @@ public class RepoResourceState implements Serializable { public RepoResourceState(String path, boolean exists, Map properties) { this.path = path; this.exists = exists; - this.properties = new ValueMapDecoratorExtended(properties); + this.properties = new ArgumentsValueMap(properties); } public String getPath() { From bd8dbe5069248043f5fe2f0d587bdaf0421a80f1 Mon Sep 17 00:00:00 2001 From: Krystian Panek Date: Thu, 8 May 2025 11:21:25 +0200 Subject: [PATCH 10/11] Snippets imprs --- .../acm/core/code/arg/DateTimeArgument.java | 51 ++++++++++++++++++- .../available/core/argument/datetime.yml | 19 ++++--- .../available/core/general/script_can_run.yml | 10 ++++ .../core/general/script_describe_run.yml | 11 ++++ .../available/core/general/script_do_run.yml | 10 ++++ 5 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_can_run.yml create mode 100644 ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_describe_run.yml create mode 100644 ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_do_run.yml diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java b/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java index 8f497575..decb2857 100644 --- a/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java +++ b/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java @@ -2,11 +2,13 @@ import com.vml.es.aem.acm.core.code.Argument; import com.vml.es.aem.acm.core.code.ArgumentType; +import com.vml.es.aem.acm.core.util.DateUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Arrays; public class DateTimeArgument extends Argument { + private DateTimeArgument.Variant variant = DateTimeArgument.Variant.DATETIME; private LocalDateTime min; @@ -29,6 +31,18 @@ public void setMin(LocalDate min) { this.min = min.atStartOfDay(); } + public void setMin(int year, int month, int day) { + this.min = LocalDateTime.of(year, month, day, 0, 0, 0); + } + + public void setMin(int year, int month, int day, int hour, int minute, int second) { + this.min = LocalDateTime.of(year, month, day, hour, minute, second); + } + + public void setMin(String min) { + this.min = DateUtils.toLocalDateTime(min); + } + public LocalDateTime getMax() { return max; } @@ -41,6 +55,18 @@ public void setMax(LocalDate max) { this.max = max.atStartOfDay(); } + public void setMax(int year, int month, int day) { + this.max = LocalDateTime.of(year, month, day, 23, 59, 59); + } + + public void setMax(int year, int month, int day, int hour, int minute, int second) { + this.max = LocalDateTime.of(year, month, day, hour, minute, second); + } + + public void setMax(String max) { + this.max = DateUtils.toLocalDateTime(max); + } + public DateTimeArgument.Variant getVariant() { return variant; } @@ -53,11 +79,22 @@ public void setVariant(DateTimeArgument.Variant render) { this.variant = render; } - // Cast LocalDate to LocalDateTime in case of DATE variant public void setValue(LocalDate value) { setValue(value.atStartOfDay()); } + public void setValue(int year, int month, int day) { + setValue(LocalDate.of(year, month, day)); + } + + public void setValue(int year, int month, int day, int hour, int minute, int second) { + setValue(LocalDateTime.of(year, month, day, hour, minute, second)); + } + + public void setValue(String value) { + setValue(DateUtils.toLocalDateTime(value)); + } + public void date() { this.variant = DateTimeArgument.Variant.DATE; } @@ -78,4 +115,16 @@ public static DateTimeArgument.Variant of(String name) { String.format("Datetime variant '%s' is not supported!", name))); } } + + public LocalDateTime now() { + return LocalDateTime.now(); + } + + public LocalDateTime startOfToday() { + return LocalDate.now().atStartOfDay(); + } + + public LocalDateTime endOfToday() { + return LocalDate.now().atTime(23, 59, 59); + } } diff --git a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml index 758e1e2a..276f0d2b 100644 --- a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml +++ b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml @@ -1,19 +1,22 @@ group: Argument name: argument_datetime content: | - args.dateTime("${1:name}") { label = "${2:label}"; value = LocalDateTime.of(${3:value}); min = LocalDateTime.of(${4:min}); max = LocalDateTime.of(${5:max}); dateTime() } + args.dateTime("${1:name}") { label = "${2:label}"; value(${3:value}); min(${4:min}); max(${5:max}) } documentation: | An argument that represents a date and time.
The value parameter is the default value, while min and max define the range of acceptable values.
- The `dateTime()` method is used to specify the display mode for the argument.
- Alternatively You can use `date()` method to display only the date
- `dateTime()` is default display mode.
+ Display mode can be enforced by using `datetime()` (default) or `date()` methods. For example: ```groovy - args.dateTime("someDateTime") {label = "some date time"; value = LocalDateTime.of(2025,5,7,9,50,0); min = LocalDateTime.of(2025,5,7,9,40,0); max = LocalDateTime.of(2025,5,7,10,50,0); dateTime()} - args.dateTime("someDate") {label = "some date"; value = LocalDate.of(2025,5,3); min = LocalDate.of(2025,5,7); max = LocalDate.of(2025,5,12); date()} - args.dateTime("someDateTime") {label = "some date time"; value = LocalDateTime.of(2025,5,7,9,50,0)} - args.dateTime("someDateTime") {label = "some date time"} + args.dateTime("publicationTime") { label = "Publication Time"; value = now() } + args.dateTime("releaseDate") { label = "Release Date"; date(); value = "2023-01-01" } + args.dateTime("birthTime") { value = "2023-01-01T12:00:00" } + args.dateTime("eventStart") { date(); setValue(2023, 10, 1) } + args.dateTime("eventEnd") { date(); value = now(); min = startOfToday().minusDays(7); max = endOfToday().plusDays(7) } + args.dateTime("raceStart") { date(); setValue(2025, 6, 1, 9, 0, 0) } + args.dateTime("holidayStart") { date(); min = "2025-07-01"; max = "2023-08-31"} } ``` + + diff --git a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_can_run.yml b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_can_run.yml new file mode 100644 index 00000000..e35c44c3 --- /dev/null +++ b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_can_run.yml @@ -0,0 +1,10 @@ +group: General +name: general_script_can_run +content: | + boolean canRun() { + // condition + } +documentation: | + Checks if the script can be executed. + + This method is executed after `describeRun()` and before `doRun()` methods. \ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_describe_run.yml b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_describe_run.yml new file mode 100644 index 00000000..3113b524 --- /dev/null +++ b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_describe_run.yml @@ -0,0 +1,11 @@ +group: General +name: general_script_describe_run +content: | + void describeRun() { + // args + } +documentation: | + Describes the script characteristics. + + This method is executed before the script is run and is used to define the script's input arguments.
+ The arguments must be defined using the `args.xxx(name) { ... }` methods which could be later on used in the script by calling `args.value(name)` method.
\ No newline at end of file diff --git a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_do_run.yml b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_do_run.yml new file mode 100644 index 00000000..1d06d076 --- /dev/null +++ b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/general/script_do_run.yml @@ -0,0 +1,10 @@ +group: General +name: general_script_do_run +content: | + void doRun() { + // logic + } +documentation: | + Executes the script logic. + + This method is executed only when `canRun()` returns true. \ No newline at end of file From bc07bce691f4642d96ec9ffa3a4639fe4ac42217 Mon Sep 17 00:00:00 2001 From: Krystian Panek Date: Thu, 8 May 2025 11:44:24 +0200 Subject: [PATCH 11/11] Datetime snippet --- .../snippet/available/core/argument/datetime.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml index 276f0d2b..c4da8741 100644 --- a/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml +++ b/ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/argument/datetime.yml @@ -1,12 +1,12 @@ group: Argument name: argument_datetime content: | - args.dateTime("${1:name}") { label = "${2:label}"; value(${3:value}); min(${4:min}); max(${5:max}) } + args.dateTime("${1:name}") { label = "${2:label}"; value = "${3:value}" } documentation: | - An argument that represents a date and time.
- The value parameter is the default value, while min and max define the range of acceptable values.
+ An argument that represents a date and time. - Display mode can be enforced by using `datetime()` (default) or `date()` methods. + Display mode can be enforced by using `datetime()` (default) or `date()` methods.
+ Optionally `min` and `max` values can be set to restrict the date and time range in picker.
For example: ```groovy @@ -15,8 +15,8 @@ documentation: | args.dateTime("birthTime") { value = "2023-01-01T12:00:00" } args.dateTime("eventStart") { date(); setValue(2023, 10, 1) } args.dateTime("eventEnd") { date(); value = now(); min = startOfToday().minusDays(7); max = endOfToday().plusDays(7) } - args.dateTime("raceStart") { date(); setValue(2025, 6, 1, 9, 0, 0) } args.dateTime("holidayStart") { date(); min = "2025-07-01"; max = "2023-08-31"} } + args.dateTime("raceStart") { setValue(2025, 6, 1, 9, 0, 0) } ```