8000 Value map decorator extended by kamil-orwat-vmltech · Pull Request #93 · wttech/acm · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Value map decorator extended #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -39,7 +38,7 @@ public ValueMap getValues() {
for (Argument<?> argument : definitions.values()) {
props.put(argument.getName(), argument.getValue());
}
return new ValueMapDecorator(props);
return new ArgumentsValueMap(props);
}

public <T> T getValue(String name, Class<T> type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
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.time.LocalTime;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import org.apache.sling.api.wrappers.ValueMapDecorator;

public class ArgumentsValueMap extends ValueMapDecorator {
/**
* Creates a new wrapper around a given map.
*
* @param base wrapped object
*/
public ArgumentsValueMap(Map<String, Object> base) {
super(base);
}

/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public <T> T get(String name, Class<T> 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);
} 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);
}

return super.get(name, type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<LocalDateTime> {

private DateTimeArgument.Variant variant = DateTimeArgument.Variant.DATETIME;

private LocalDateTime min;
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.vml.es.aem.acm.core.repo;

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;
Expand All @@ -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).
Expand All @@ -25,7 +25,7 @@ public class RepoResourceState implements Serializable {
public RepoResourceState(String path, boolean exists, Map<String, Object> properties) {
this.path = path;
this.exists = exists;
this.properties = new ValueMapDecorator(properties);
this.properties = new ArgumentsValueMap(properties);
}

public String getPath() {
Expand Down
66 changes: 65 additions & 1 deletion core/src/main/java/com/vml/es/aem/acm/core/util/DateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -58,7 +59,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 {
Expand All @@ -70,6 +71,18 @@ public static ZonedDateTime localDateTimeFromString(String text) {
throw new IllegalArgumentException(String.format("Cannot parse date '%s'!", 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 {
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);
}
Expand All @@ -84,8 +97,59 @@ 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 -> {
Date parsedDate = fromString(d);
Calendar calendar = Calendar.getInstance();
calendar.setTime(parsedDate);
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);
}

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));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
group: Argument
name: argument_datetime
content: |
args.dateTime("${1:name}") { label = "${2:label}"; value = "${3:value}" }
documentation: |
An argument that represents a date and time.

Display mode can be enforced by using `datetime()` (default) or `date()` methods.<br>
Optionally `min` and `max` values can be set to restrict the date and time range in picker.<br>

For example:
```groovy
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("holidayStart") { date(); min = "2025-07-01"; max = "2023-08-31"} }
args.dateTime("raceStart") { setValue(2025, 6, 1, 9, 0, 0) }
```


Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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.<br>
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.<br>
Original file line number Diff line number Diff line change
@@ -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.
0