diff --git a/jollyday-core/src/main/java/module-info.java b/jollyday-core/src/main/java/module-info.java index 349e83b0d..6a59dbf9c 100644 --- a/jollyday-core/src/main/java/module-info.java +++ b/jollyday-core/src/main/java/module-info.java @@ -16,8 +16,10 @@ de.focus_shift.jollyday.jaxb, de.focus_shift.jollyday.jackson, de.focus_shift.jollyday.jackson.test, - de.focus_shift.jollyday.jaxb.test; + de.focus_shift.jollyday.jaxb.test, + de.focus_shift.jollyday.java.test; exports de.focus_shift.jollyday.core.parser.impl to de.focus_shift.jollyday.jackson.test, - de.focus_shift.jollyday.jaxb.test; + de.focus_shift.jollyday.jaxb.test, + de.focus_shift.jollyday.java.test; } diff --git a/jollyday-jackson/src/main/java/module-info.java b/jollyday-jackson/src/main/java/module-info.java index fd9b2b091..5ca33ab60 100644 --- a/jollyday-jackson/src/main/java/module-info.java +++ b/jollyday-jackson/src/main/java/module-info.java @@ -20,8 +20,10 @@ exports de.focus_shift.jollyday.jackson to de.focus_shift.jollyday.core, - de.focus_shift.jollyday.jackson.test; + de.focus_shift.jollyday.jackson.test, + de.focus_shift.jollyday.pojo.test; exports de.focus_shift.jollyday.jackson.mapping to com.fasterxml.jackson.databind, - de.focus_shift.jollyday.jackson.test; + de.focus_shift.jollyday.jackson.test, + de.focus_shift.jollyday.pojo.test; } diff --git a/jollyday-pojo-generator/pom.xml b/jollyday-pojo-generator/pom.xml new file mode 100644 index 000000000..f0fdd668e --- /dev/null +++ b/jollyday-pojo-generator/pom.xml @@ -0,0 +1,90 @@ + + 4.0.0 + + + de.focus-shift + jollyday + 1.5.0-SNAPSHOT + ../pom.xml + + + jollyday-pojo-generator + + Jollyday with Plain Old Java Objects Maven Plugin Generator + Maven Plugin that generates Plain Old Java Objects from xml holiday configuration + + maven-plugin + + + ${maven.version} + + + + 3.9.6 + + + + + + de.focus-shift + jollyday-core + ${project.version} + + + + de.focus-shift + jollyday-jackson + ${project.version} + + + + org.apache.maven + maven-plugin-api + ${maven.version} + provided + + + org.apache.maven + maven-core + ${maven.version} + provided + + + org.apache.maven + maven-artifact + ${maven.version} + provided + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.11.0 + provided + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.11.0 + + pojo-generator + true + + + + mojo-descriptor + package + + descriptor + + + + + + + diff --git a/jollyday-pojo-generator/src/main/java/de/focus_shift/jollyday/pojo/generator/PojoGenerator.java b/jollyday-pojo-generator/src/main/java/de/focus_shift/jollyday/pojo/generator/PojoGenerator.java new file mode 100644 index 000000000..eecafce67 --- /dev/null +++ b/jollyday-pojo-generator/src/main/java/de/focus_shift/jollyday/pojo/generator/PojoGenerator.java @@ -0,0 +1,376 @@ +package de.focus_shift.jollyday.pojo.generator; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.time.DayOfWeek; +import java.time.Month; +import java.time.MonthDay; +import java.time.Year; +import java.time.chrono.Chronology; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.threeten.extra.Days; + +import de.focus_shift.jollyday.core.HolidayCalendar; +import de.focus_shift.jollyday.core.spi.ChristianHoliday; +import de.focus_shift.jollyday.core.spi.Configuration; +import de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday; +import de.focus_shift.jollyday.core.spi.Fixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth; +import de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed; +import de.focus_shift.jollyday.core.spi.Holidays; +import de.focus_shift.jollyday.core.spi.IslamicHoliday; +import de.focus_shift.jollyday.core.spi.Limited.YearCycle; +import de.focus_shift.jollyday.core.spi.Movable.MovingCondition; +import de.focus_shift.jollyday.core.spi.RelativeToEasterSunday; +import de.focus_shift.jollyday.core.spi.RelativeToFixed; +import de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth; +import de.focus_shift.jollyday.jackson.JacksonConfiguration; +import de.focus_shift.jollyday.jackson.JacksonXMLMapper; + +class PojoGenerator { + + private static final char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F' }; + + void generateHolidaySource(HolidayCalendar cal, Writer writer) throws IOException { + JacksonXMLMapper xmlUtil = new JacksonXMLMapper(); + + String calendarId = cal.getId().toLowerCase(); + String holidayFileName = "Holidays_" + calendarId + ".xml"; + + InputStream inputStream = PojoGenerator.class.getClassLoader().getResourceAsStream("holidays/" + holidayFileName); + if (inputStream == null) { + System.err.println("No input found for " + holidayFileName); + return; + } + JacksonConfiguration jacksonConfiguration = new JacksonConfiguration(xmlUtil.unmarshallConfiguration(inputStream)); + + writer.write("package de.focus_shift.jollyday.pojo.holidays;\n\n"); + writeImports(writer); + writer.write("import de.focus_shift.jollyday.pojo.*;\n\n"); + writer.write("public class Holiday_" + calendarId + " {\n\n"); + + writer.write(" public static PojoConfiguration configuration;\n\n"); + StringBuilder sb = new StringBuilder(); + sb.append(" static {\n"); + sb.append(" configuration = "); + sb.append(configuration(jacksonConfiguration)); + sb.append(";\n"); + sb.append(" }\n"); + sb.append("}\n"); + + writer.write(sb.toString()); + } + + private String unicodeEscape(String value) { + if (value == null || value.isBlank()) { + return value; + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + if ((c >> 7) > 0) { + sb.append("\\u"); + sb.append(hexChar[(c >> 12) & 0xF]); // append the hex character for the left-most 4-bits + sb.append(hexChar[(c >> 8) & 0xF]); // hex for the second group of 4-bits from the left + sb.append(hexChar[(c >> 4) & 0xF]); // hex for the third group + sb.append(hexChar[c & 0xF]); // hex for the last group, e.g., the right most 4-bits + } else { + sb.append(c); + } + } + return sb.toString(); + } + + void generateConfigurationSource(Writer writer) throws IOException { + + writeHeader(writer); + + writer.append(" static Map configurations = new HashMap<>();\n"); + + writer.append(" static {\n"); + for (HolidayCalendar cal : HolidayCalendar.values()) { + String calendarId = cal.getId().toLowerCase(); + writer.write(String.format(" configurations.put(\"%s\",Holiday_%s.configuration);\n", calendarId, calendarId)); + } + writer.write(" }\n"); + writeFooter(writer); + } + + private void writeImports(Writer writer) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append("import java.time.DayOfWeek;\n"); + sb.append("import java.time.Month;\n"); + sb.append("import java.time.MonthDay;\n"); + sb.append("import java.time.Year;\n"); + sb.append("import java.time.chrono.Chronology;\n"); + sb.append("import java.util.HashMap;\n"); + sb.append("import java.util.List;\n"); + sb.append("import java.util.Map;\n\n"); + + sb.append("import de.focus_shift.jollyday.core.HolidayType;\n"); + sb.append("import de.focus_shift.jollyday.core.ManagerParameter;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.ChristianHoliday.ChristianHolidayType;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.Configuration;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.ConfigurationService;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday.EthiopianOrthodoxHolidayType;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.IslamicHoliday.IslamicHolidayType;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.Occurrence;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.Relation;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.Movable.MovingCondition.With;\n"); + sb.append("import de.focus_shift.jollyday.core.spi.Limited.YearCycle;\n"); + + writer.write(sb.toString()); + } + + private void writeHeader(Writer writer) throws IOException { + writer.write("package de.focus_shift.jollyday.pojo;\n\n"); + + writer.write("import java.util.HashMap;\n"); + writer.write("import java.util.Map;\n\n"); + + writer.write("import de.focus_shift.jollyday.core.ManagerParameter;\n"); + writer.write("import de.focus_shift.jollyday.core.spi.Configuration;\n"); + writer.write("import de.focus_shift.jollyday.core.spi.ConfigurationService;\n"); + writer.write("import de.focus_shift.jollyday.pojo.holidays.*;\n\n"); + + writer.write("public class PojoConfigurationService implements ConfigurationService {\n\n"); + } + + private void writeFooter(Writer writer) throws IOException { + StringBuilder sb = new StringBuilder(); + + sb.append("\n"); + sb.append(" @Override\n"); + sb.append(" public Configuration getConfiguration(ManagerParameter parameter) {\n"); + sb.append(" final String cacheKey = parameter.createCacheKey();\n"); + sb.append("\n"); + sb.append(" PojoConfiguration configuration = configurations.get(cacheKey);\n"); + sb.append(" return configuration;\n"); + sb.append(" }\n"); + sb.append("}"); + + writer.write(sb.toString()); + } + + // public PojoConfiguration(PojoHolidays javaHolidays, List subConfigurations, String hierarchy, String description) + private String configuration(Configuration configuration) { + return constructor("PojoConfiguration", holidays(configuration.holidays()), configurations(configuration.subConfigurations()), string(configuration.hierarchy()), string(configuration.description())); + } + + private String configurations(Stream configurations) { + String result; + if (configurations != null) { + result = configurations.map(c -> configuration(c)).collect(Collectors.joining(",", "List.of(", ")")); + if ("List.of()".equals(result)) { + result = "null"; + } + } else { + result = "null"; + } + + return result; + } + + // public PojoHolidays(List christianHoliday, List islamicHoliday, List ethiopianOrthodoxHoliday, List fixed, List fixedWeekday, List fixedWeekdayBetweenFixed, List fixedWeekdayRelativeToFixed, List relativeToFixed, List relativeToWeekdayInMonth, List relativeToEasterSunday) + private String holidays(Holidays holidays) { + if (holidays == null) { + return "null"; + } + + StringBuilder sb = new StringBuilder(); + sb.append(String.format("new PojoHolidays()\n")); + for (de.focus_shift.jollyday.core.spi.Fixed fixed : holidays.fixed()) { + sb.append(String.format(" .addFixed(%s)\n", fixed(fixed))); + } + + for (ChristianHoliday christianHoliday : holidays.christianHolidays()) { + sb.append(String.format(" .addChristianHoliday(%s)\n", christianHoliday(christianHoliday))); + } + + for (EthiopianOrthodoxHoliday ethiopianOrthodoxHoliday : holidays.ethiopianOrthodoxHolidays()) { + sb.append(String.format(" .addEthiopianOrthodoxHoliday(%s)\n", ethiopianOrthodoxHoliday(ethiopianOrthodoxHoliday))); + } + + for (IslamicHoliday islamicHoliday : holidays.islamicHolidays()) { + sb.append(String.format(" .addIslamicHoliday(%s)\n", islamicHoliday(islamicHoliday))); + } + + for (FixedWeekdayBetweenFixed fixedWeekdayBetweenFixed : holidays.fixedWeekdayBetweenFixed()) { + sb.append(String.format(" .addFixedWeekdayBetweenFixed(%s)\n", fixedWeekdayBetweenFixed(fixedWeekdayBetweenFixed))); + } + + for (FixedWeekdayInMonth fixedWeekdayInMonth : holidays.fixedWeekdays()) { + sb.append(String.format(" .addFixedWeekday(%s)\n", fixedWeekdayInMonth(fixedWeekdayInMonth))); + } + + for (FixedWeekdayRelativeToFixed fixedWeekdayRelativeToFixed : holidays.fixedWeekdayRelativeToFixed()) { + sb.append(String.format(" .addFixedWeekdayRelativeToFixed(%s)\n", fixedWeekdayRelativeToFixed(fixedWeekdayRelativeToFixed))); + } + + for (RelativeToEasterSunday relativeToEasterSunday : holidays.relativeToEasterSunday()) { + sb.append(String.format(" .addRelativeToEasterSunday(%s)\n", relativeToEasterSunday(relativeToEasterSunday))); + } + + for (RelativeToFixed relativeToFixed : holidays.relativeToFixed()) { + sb.append(String.format(" .addRelativeToFixed(%s)\n", relativeToFixed(relativeToFixed))); + } + + for (RelativeToWeekdayInMonth relativeToWeekdayInMonth : holidays.relativeToWeekdayInMonth()) { + sb.append(String.format(" .addRelativeToWeekdayInMonth(%s)\n", relativeToWeekdayInMonth(relativeToWeekdayInMonth))); + } + + return sb.toString(); + } + + // public PojoFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions, MonthDay day) + private String fixed(Fixed fixed) { + return constructor("PojoFixed", string(fixed.descriptionPropertiesKey()), enums(fixed.holidayType()), year(fixed.validFrom()), year(fixed.validTo()), yearCycle(fixed.cycle()), movingConditions(fixed.conditions()), monthDay(fixed.day())); + } + + //public PojoChristianHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions, ChristianHolidayType type, Chronology chronology) + private String christianHoliday(ChristianHoliday christianHoliday) { + return constructor("PojoChristianHoliday", string(christianHoliday.descriptionPropertiesKey()), enums(christianHoliday.holidayType()), year(christianHoliday.validFrom()), year(christianHoliday.validTo()), yearCycle(christianHoliday.cycle()), movingConditions(christianHoliday.conditions()), enums(christianHoliday.type()), chronology(christianHoliday.chronology())); + } + + // public PojoEthiopianOrthodoxHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, EthiopianOrthodoxHolidayType type) + private String ethiopianOrthodoxHoliday(EthiopianOrthodoxHoliday hol) { + return constructor("PojoEthiopianOrthodoxHoliday", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), enums(hol.type())); + } + + // public PojoIslamicHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions, IslamicHolidayType type) + private String islamicHoliday(IslamicHoliday hol) { + return constructor("PojoIslamicHoliday", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), movingConditions(hol.conditions()), enums(hol.type())); + } + + // public PojoFixedWeekdayBetweenFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, Fixed from, Fixed to, DayOfWeek weekday) + private String fixedWeekdayBetweenFixed(FixedWeekdayBetweenFixed hol) { + return constructor("PojoFixedWeekdayBetweenFixed", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), fixed(hol.from()), fixed(hol.to()), dayOfWeek(hol.weekday())); + } + + // public PojoFixedWeekdayInMonth(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, DayOfWeek weekday, Month month, Occurrence which) + private String fixedWeekdayInMonth(FixedWeekdayInMonth hol) { + return constructor("PojoFixedWeekdayInMonth", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), dayOfWeek(hol.weekday()), month(hol.month()), enums(hol.which())); + } + + // public PojoFixedWeekdayRelativeToFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, DayOfWeek weekday, Relation when, Fixed day, Occurrence which) + private String fixedWeekdayRelativeToFixed(FixedWeekdayRelativeToFixed hol) { + return constructor("PojoFixedWeekdayRelativeToFixed", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), dayOfWeek(hol.weekday()), enums(hol.when()), fixed(hol.day()), enums(hol.which())); + } + + // public PojoRelativeToEasterSunday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, Chronology chronology, Days days) + private String relativeToEasterSunday(RelativeToEasterSunday hol) { + return constructor("PojoRelativeToEasterSunday", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), chronology(hol.chronology()), days(hol.days())); + } + + // public PojoRelativeToFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, Fixed date, DayOfWeek weekday, Relation when, Days days) { + private String relativeToFixed(RelativeToFixed hol) { + return constructor("PojoRelativeToFixed", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), fixed(hol.date()), dayOfWeek(hol.weekday()), enums(hol.when()), days(hol.days())); + } + + // public PojoRelativeToWeekdayInMonth(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, FixedWeekdayInMonth weekdayInMonth, DayOfWeek weekday, Relation when) + private String relativeToWeekdayInMonth(RelativeToWeekdayInMonth hol) { + return constructor("PojoRelativeToWeekdayInMonth", string(hol.descriptionPropertiesKey()), enums(hol.holidayType()), year(hol.validFrom()), year(hol.validTo()), yearCycle(hol.cycle()), fixedWeekdayInMonth(hol.weekdayInMonth()), dayOfWeek(hol.weekday()), enums(hol.when())); + } + + private String constructor(Object... arguments) { + StringBuilder sb = new StringBuilder(); + sb.append("new %s("); + for (int i = 0; i < arguments.length - 1; i++) { + sb.append("%s,"); + } + sb.setLength(sb.length() - 1); + sb.append(")"); + + return String.format(sb.toString(), arguments); + } + + private String string(String string) { + return String.format("\"%s\"", unicodeEscape(string)); + } + + private String year(Year year) { + if (year != null) { + return String.format("Year.of(%s)", year.getValue()); + } else { + return "null"; + } + } + + private String enums(Enum enumz) { + return enumz.getDeclaringClass().getSimpleName() + "." + enumz.name(); + } + + private String yearCycle(YearCycle yearCycle) { + return enums(yearCycle); + } + + private String days(Days days) { + if (days != null) { + return String.format("Days.of(%s)", days.getAmount()); + } else { + return "null"; + } + } + + private String monthDay(MonthDay monthDay) { + if (monthDay != null) { + return String.format("MonthDay.of(%s,%s)", monthDay.getMonthValue(), monthDay.getDayOfMonth()); + } else { + return "null"; + } + } + + private String month(Month monthDay) { + if (monthDay != null) { + return String.format("Month.of(%s)", monthDay.getValue()); + } else { + return "null"; + } + } + + private String dayOfWeek(DayOfWeek dayOfWeek) { + + if (dayOfWeek != null) { + return String.format("DayOfWeek.of(%s)", dayOfWeek.getValue()); + } else { + return "null"; + } + } + + private String chronology(Chronology chronology) { + if (chronology != null) { + return String.format("Chronology.of(\"%s\")", chronology.getId()); + } else { + return "null"; + } + } + + private String movingConditions(List movingConditions) { + if (movingConditions.isEmpty()) { + return "null"; + } else { + StringBuilder sb = new StringBuilder(); + sb.append("List.of("); + movingConditions.forEach(m -> sb.append(movingCondition(m)).append(",")); + sb.setLength(sb.length() - 1); + sb.append(")"); + return sb.toString(); + } + } + + // public PojoMovingCondition(DayOfWeek substitute, With with, DayOfWeek weekday) { + private String movingCondition(MovingCondition movingCondition) { + if (movingCondition == null) { + return "null"; + } else { + return constructor("PojoMovingCondition", dayOfWeek(movingCondition.substitute()), enums(movingCondition.with()), dayOfWeek(movingCondition.weekday())); + } + } +} diff --git a/jollyday-pojo-generator/src/main/java/de/focus_shift/jollyday/pojo/generator/PojoGeneratorMojo.java b/jollyday-pojo-generator/src/main/java/de/focus_shift/jollyday/pojo/generator/PojoGeneratorMojo.java new file mode 100644 index 000000000..b5d2a434f --- /dev/null +++ b/jollyday-pojo-generator/src/main/java/de/focus_shift/jollyday/pojo/generator/PojoGeneratorMojo.java @@ -0,0 +1,58 @@ +package de.focus_shift.jollyday.pojo.generator; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Locale; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import de.focus_shift.jollyday.core.HolidayCalendar; + +/** + * Generate PojoConfiguration + */ +@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class PojoGeneratorMojo extends AbstractMojo { + + /** + * The directory where the pojos will be generated to + */ + @Parameter(defaultValue = "${project.build.directory}/generated-sources/pojo", property = "outputDir", required = true) + private File outputDirectory; + + public void execute() throws MojoExecutionException { + final Log log = getLog(); + + final File genDir = Paths.get(outputDirectory.getAbsolutePath(), "de/focus_shift/jollyday/pojo/holidays").toFile(); + if (!genDir.exists() && !genDir.mkdirs()) { + throw new MojoExecutionException("Target directory doesn't exist or cannot be generated: "+ genDir.getAbsolutePath()); + } + + final File configurationService = Paths.get(outputDirectory.getAbsolutePath(), "de/focus_shift/jollyday/pojo/PojoConfigurationService.java").toFile(); + + try (FileWriter fileWriter = new FileWriter(configurationService, false)) { + PojoGenerator generator = new PojoGenerator(); + generator.generateConfigurationSource(fileWriter); + + for (HolidayCalendar cal : HolidayCalendar.values()) { + String calendarId = cal.getId().toLowerCase(Locale.ROOT); + + final File holidayFile = Paths.get(outputDirectory.getAbsolutePath(), "de/focus_shift/jollyday/pojo/holidays/Holiday_" + calendarId + ".java").toFile(); + try (FileWriter holidayFileWriter = new FileWriter(holidayFile, false)) { + generator.generateHolidaySource(cal, holidayFileWriter); + } + } + } catch (IOException e) { + throw new MojoExecutionException(e.getLocalizedMessage()); + } + + log.info("Holiday files created at "+outputDirectory.getAbsolutePath()); + } +} diff --git a/jollyday-pojo-generator/src/main/resources/META-INF/MANIFEST.MF b/jollyday-pojo-generator/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 000000000..e69de29bb diff --git a/jollyday-pojo/pom.xml b/jollyday-pojo/pom.xml new file mode 100644 index 000000000..6ab8b0bd4 --- /dev/null +++ b/jollyday-pojo/pom.xml @@ -0,0 +1,118 @@ + + 4.0.0 + + jollyday-pojo + Jollyday with Plain Old Java Objects + + Plain Old Java Objects based jollyday implementation + + + de.focus-shift + jollyday + 1.5.0-SNAPSHOT + ../pom.xml + + + + + de.focus-shift + jollyday-core + ${project.version} + + + + + + org.threeten + threeten-extra + + + + + ch.qos.logback + logback-classic + test + + + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.2.0 + + + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/pojo + + + + + + + + de.focus-shift + jollyday-pojo-generator + ${project.version} + + + ${project.build.directory}/generated-sources/pojo + + + + + generate-const + generate-sources + + generate + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + bundle-manifest + process-classes + + manifest + + + + + + de.focus_shift.jollyday-pojo + de.focus_shift.jollday.pojo.* + osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)" + osgi.serviceloader;osgi.serviceloader=de.focus_shift.jollyday.core.spi.ConfigurationService + + + + + + + diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/DefaultHoliday.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/DefaultHoliday.java new file mode 100644 index 000000000..40184466c --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/DefaultHoliday.java @@ -0,0 +1,45 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.Year; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Limited.YearCycle; + +public abstract class DefaultHoliday { + + private String descriptionPropertiesKey; + private HolidayType officiality; + private Year validFrom; + private Year validTo; + private YearCycle cycle; + + public DefaultHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle) { + this.descriptionPropertiesKey = descriptionPropertiesKey; + this.officiality = officiality; + this.validFrom = validFrom; + this.validTo = validTo; + this.cycle = cycle; + } + + public String descriptionPropertiesKey() { + return descriptionPropertiesKey; + } + + public HolidayType holidayType() { + return officiality; + } + + public Year validFrom() { + return validFrom; + } + + public Year validTo() { + return validTo; + } + + public YearCycle cycle() { + return cycle; + } + + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/DefaultMovingHoliday.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/DefaultMovingHoliday.java new file mode 100644 index 000000000..dd203305a --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/DefaultMovingHoliday.java @@ -0,0 +1,23 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.Year; +import java.util.Collections; +import java.util.List; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Limited.YearCycle; +import de.focus_shift.jollyday.core.spi.Movable.MovingCondition; + +public abstract class DefaultMovingHoliday extends DefaultHoliday { + + private List conditions; + + public DefaultMovingHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.conditions = conditions; + } + + public List conditions() { + return conditions != null ? conditions : Collections.emptyList(); + } +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoChristianHoliday.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoChristianHoliday.java new file mode 100644 index 000000000..8fe0dbeae --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoChristianHoliday.java @@ -0,0 +1,31 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.Year; +import java.time.chrono.Chronology; +import java.util.List; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.ChristianHoliday; + +public class PojoChristianHoliday extends DefaultMovingHoliday implements ChristianHoliday { + + private ChristianHolidayType type; + private Chronology chronology; + + public PojoChristianHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions, ChristianHolidayType type, Chronology chronology) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle, conditions); + this.type = type; + this.chronology = chronology; + } + + @Override + public ChristianHolidayType type() { + return type; + } + + @Override + public Chronology chronology() { + return chronology; + } + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoConfiguration.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoConfiguration.java new file mode 100644 index 000000000..835f47871 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoConfiguration.java @@ -0,0 +1,46 @@ +package de.focus_shift.jollyday.pojo; + +import java.util.List; +import java.util.stream.Stream; + +import de.focus_shift.jollyday.core.spi.Configuration; +import de.focus_shift.jollyday.core.spi.Holidays; + +public class PojoConfiguration implements Configuration { + + private PojoHolidays javaHolidays; + private List subConfigurations; + private String hierarchy; + private String description; + + public PojoConfiguration() { + } + + public PojoConfiguration(PojoHolidays javaHolidays, List subConfigurations, String hierarchy, String description) { + this.javaHolidays = javaHolidays; + this.subConfigurations = subConfigurations; + this.hierarchy = hierarchy; + this.description = description; + } + + @Override + public Holidays holidays() { + return javaHolidays; + } + + @Override + public Stream subConfigurations() { + return subConfigurations != null ? subConfigurations.stream() : Stream.empty(); + } + + @Override + public String hierarchy() { + return hierarchy; + } + + @Override + public String description() { + return description; + } + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoEthiopianOrthodoxHoliday.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoEthiopianOrthodoxHoliday.java new file mode 100644 index 000000000..044a1e033 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoEthiopianOrthodoxHoliday.java @@ -0,0 +1,22 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.Year; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday; + +public class PojoEthiopianOrthodoxHoliday extends DefaultHoliday implements EthiopianOrthodoxHoliday { + + private EthiopianOrthodoxHolidayType type; + + public PojoEthiopianOrthodoxHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, EthiopianOrthodoxHolidayType type) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.type = type; + } + + @Override + public EthiopianOrthodoxHolidayType type() { + return type; + } + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixed.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixed.java new file mode 100644 index 000000000..0d67c5852 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixed.java @@ -0,0 +1,25 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.MonthDay; +import java.time.Year; +import java.util.List; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Fixed; + +public class PojoFixed extends DefaultMovingHoliday implements Fixed { + + private MonthDay day; + + public PojoFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions, MonthDay day) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle, conditions); + this.day = day; + } + + @Override + public MonthDay day() { + return day; + } + + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayBetweenFixed.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayBetweenFixed.java new file mode 100644 index 000000000..4d845ef4b --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayBetweenFixed.java @@ -0,0 +1,39 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.DayOfWeek; +import java.time.Year; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Fixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed; + +public class PojoFixedWeekdayBetweenFixed extends DefaultHoliday implements FixedWeekdayBetweenFixed { + + private Fixed from; + private Fixed to; + private DayOfWeek weekday; + + public PojoFixedWeekdayBetweenFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, Fixed from, Fixed to, DayOfWeek weekday) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.from = from; + this.to = to; + this.weekday = weekday; + } + + @Override + public Fixed from() { + return from; + } + + @Override + public Fixed to() { + return to; + } + + @Override + public DayOfWeek weekday() { + return weekday; + } + + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayInMonth.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayInMonth.java new file mode 100644 index 000000000..07563dea6 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayInMonth.java @@ -0,0 +1,40 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.DayOfWeek; +import java.time.Month; +import java.time.Year; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth; +import de.focus_shift.jollyday.core.spi.Occurrence; + +public class PojoFixedWeekdayInMonth extends DefaultHoliday implements FixedWeekdayInMonth { + + private DayOfWeek weekday; + private Month month; + private Occurrence which; + + public PojoFixedWeekdayInMonth(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, DayOfWeek weekday, Month month, Occurrence which) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.weekday = weekday; + this.month = month; + this.which = which; + } + + @Override + public DayOfWeek weekday() { + return weekday; + } + + @Override + public Month month() { + return month; + } + + @Override + public Occurrence which() { + return which; + } + + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayRelativeToFixed.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayRelativeToFixed.java new file mode 100644 index 000000000..82482a5e9 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoFixedWeekdayRelativeToFixed.java @@ -0,0 +1,47 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.DayOfWeek; +import java.time.Year; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Fixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed; +import de.focus_shift.jollyday.core.spi.Occurrence; +import de.focus_shift.jollyday.core.spi.Relation; + +public class PojoFixedWeekdayRelativeToFixed extends DefaultHoliday implements FixedWeekdayRelativeToFixed { + + private DayOfWeek weekday; + private Relation when; + private Fixed day; + private Occurrence which; + + public PojoFixedWeekdayRelativeToFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, DayOfWeek weekday, Relation when, Fixed day, Occurrence which) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.weekday = weekday; + this.when = when; + this.day = day; + this.which = which; + } + + @Override + public DayOfWeek weekday() { + return weekday; + } + + @Override + public Relation when() { + return when; + } + + @Override + public Fixed day() { + return day; + } + + @Override + public Occurrence which() { + return which; + } + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoHolidays.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoHolidays.java new file mode 100644 index 000000000..54580bd80 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoHolidays.java @@ -0,0 +1,148 @@ +package de.focus_shift.jollyday.pojo; + +import java.util.ArrayList; +import java.util.List; + +import de.focus_shift.jollyday.core.spi.ChristianHoliday; +import de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday; +import de.focus_shift.jollyday.core.spi.Fixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth; +import de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed; +import de.focus_shift.jollyday.core.spi.IslamicHoliday; +import de.focus_shift.jollyday.core.spi.RelativeToEasterSunday; +import de.focus_shift.jollyday.core.spi.RelativeToFixed; +import de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth; + +public class PojoHolidays implements de.focus_shift.jollyday.core.spi.Holidays { + + protected List christianHoliday = new ArrayList<>(); + protected List islamicHoliday = new ArrayList<>(); + protected List ethiopianOrthodoxHoliday = new ArrayList<>(); + + protected List fixed = new ArrayList<>(); + protected List fixedWeekday= new ArrayList<>(); + protected List fixedWeekdayBetweenFixed= new ArrayList<>(); + protected List fixedWeekdayRelativeToFixed= new ArrayList<>(); + + protected List relativeToFixed = new ArrayList<>(); + protected List relativeToWeekdayInMonth = new ArrayList<>(); + protected List relativeToEasterSunday= new ArrayList<>(); + + public PojoHolidays() { + + } + + public PojoHolidays(List christianHoliday, List islamicHoliday, List ethiopianOrthodoxHoliday, List fixed, List fixedWeekday, List fixedWeekdayBetweenFixed, List fixedWeekdayRelativeToFixed, List relativeToFixed, List relativeToWeekdayInMonth, List relativeToEasterSunday) { + this.christianHoliday = christianHoliday; + this.islamicHoliday = islamicHoliday; + this.ethiopianOrthodoxHoliday = ethiopianOrthodoxHoliday; + this.fixed = fixed; + this.fixedWeekday = fixedWeekday; + this.fixedWeekdayBetweenFixed = fixedWeekdayBetweenFixed; + this.fixedWeekdayRelativeToFixed = fixedWeekdayRelativeToFixed; + this.relativeToFixed = relativeToFixed; + this.relativeToWeekdayInMonth = relativeToWeekdayInMonth; + this.relativeToEasterSunday = relativeToEasterSunday; + } + + @Override + public List fixed() { + return fixed; + } + + public PojoHolidays addFixed(Fixed value) { + this.fixed.add(value); + return this; + } + + @Override + public List relativeToFixed() { + return relativeToFixed; + } + + public PojoHolidays addRelativeToFixed(RelativeToFixed value) { + this.relativeToFixed.add(value); + return this; + } + + @Override + public List relativeToWeekdayInMonth() { + return relativeToWeekdayInMonth; + } + + public PojoHolidays addRelativeToWeekdayInMonth(RelativeToWeekdayInMonth value) { + this.relativeToWeekdayInMonth.add(value); + return this; + } + + @Override + public List fixedWeekdays() { + return fixedWeekday; + } + + public PojoHolidays addFixedWeekday(FixedWeekdayInMonth value) { + this.fixedWeekday.add(value); + return this; + } + + @Override + public List christianHolidays() { + return christianHoliday; + } + + public PojoHolidays addChristianHoliday(ChristianHoliday value) { + this.christianHoliday.add(value); + return this; + } + + @Override + public List islamicHolidays() { + return islamicHoliday; + } + + public PojoHolidays addIslamicHoliday(IslamicHoliday value) { + this.islamicHoliday.add(value); + return this; + } + + @Override + public List fixedWeekdayBetweenFixed() { + return fixedWeekdayBetweenFixed; + } + + public PojoHolidays addFixedWeekdayBetweenFixed(FixedWeekdayBetweenFixed value) { + this.fixedWeekdayBetweenFixed.add(value); + return this; + } + + @Override + public List fixedWeekdayRelativeToFixed() { + return fixedWeekdayRelativeToFixed; + } + + public PojoHolidays addFixedWeekdayRelativeToFixed(FixedWeekdayRelativeToFixed value) { + this.fixedWeekdayRelativeToFixed.add(value); + return this; + } + + @Override + public List ethiopianOrthodoxHolidays() { + return ethiopianOrthodoxHoliday; + } + + public PojoHolidays addEthiopianOrthodoxHoliday(EthiopianOrthodoxHoliday value) { + this.ethiopianOrthodoxHoliday.add(value); + return this; + } + + @Override + public List relativeToEasterSunday() { + return relativeToEasterSunday; + } + + public PojoHolidays addRelativeToEasterSunday(RelativeToEasterSunday value) { + this.relativeToEasterSunday.add(value); + return this; + } +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoIslamicHoliday.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoIslamicHoliday.java new file mode 100644 index 000000000..1f1f10276 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoIslamicHoliday.java @@ -0,0 +1,23 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.Year; +import java.util.List; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.IslamicHoliday; + +public class PojoIslamicHoliday extends DefaultMovingHoliday implements IslamicHoliday { + + private IslamicHolidayType type; + + public PojoIslamicHoliday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, List conditions, IslamicHolidayType type) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle, conditions); + this.type = type; + } + + @Override + public IslamicHolidayType type() { + return type; + } + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoMovingCondition.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoMovingCondition.java new file mode 100644 index 000000000..c0f36db60 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoMovingCondition.java @@ -0,0 +1,33 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.DayOfWeek; + +import de.focus_shift.jollyday.core.spi.Movable.MovingCondition; + +public class PojoMovingCondition implements MovingCondition { + + private DayOfWeek substitute; + private With with; + private DayOfWeek weekday; + + public PojoMovingCondition(DayOfWeek substitute, With with, DayOfWeek weekday) { + this.substitute = substitute; + this.with = with; + this.weekday = weekday; + } + + @Override + public DayOfWeek substitute() { + return substitute; + } + + @Override + public With with() { + return with; + } + + @Override + public DayOfWeek weekday() { + return weekday; + } +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToEasterSunday.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToEasterSunday.java new file mode 100644 index 000000000..dea38f342 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToEasterSunday.java @@ -0,0 +1,31 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.Year; +import java.time.chrono.Chronology; + +import org.threeten.extra.Days; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.RelativeToEasterSunday; + +public class PojoRelativeToEasterSunday extends DefaultHoliday implements RelativeToEasterSunday { + + private Chronology chronology; + private Days days; + + public PojoRelativeToEasterSunday(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, Chronology chronology, Days days) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.chronology = chronology; + this.days = days; + } + + @Override + public Chronology chronology() { + return chronology; + } + + @Override + public Days days() { + return days; + } +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToFixed.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToFixed.java new file mode 100644 index 000000000..0a25b2c56 --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToFixed.java @@ -0,0 +1,49 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.DayOfWeek; +import java.time.Year; + +import org.threeten.extra.Days; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Fixed; +import de.focus_shift.jollyday.core.spi.Relation; +import de.focus_shift.jollyday.core.spi.RelativeToFixed; + +public class PojoRelativeToFixed extends DefaultHoliday implements RelativeToFixed { + + private Fixed date; + + DayOfWeek weekday; + Relation when; + Days days; + + public PojoRelativeToFixed(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, Fixed date, DayOfWeek weekday, Relation when, Days days) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.date = date; + this.weekday = weekday; + this.when = when; + this.days = days; + } + + @Override + public Fixed date() { + return date; + } + + @Override + public DayOfWeek weekday() { + return weekday; + } + + @Override + public Relation when() { + return when; + } + + @Override + public Days days() { + return days; + } + +} diff --git a/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToWeekdayInMonth.java b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToWeekdayInMonth.java new file mode 100644 index 000000000..f02bdaa4e --- /dev/null +++ b/jollyday-pojo/src/main/java/de/focus_shift/jollyday/pojo/PojoRelativeToWeekdayInMonth.java @@ -0,0 +1,40 @@ +package de.focus_shift.jollyday.pojo; + +import java.time.DayOfWeek; +import java.time.Year; + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth; +import de.focus_shift.jollyday.core.spi.Relation; +import de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth; + +public class PojoRelativeToWeekdayInMonth extends DefaultHoliday implements RelativeToWeekdayInMonth { + + private FixedWeekdayInMonth weekdayInMonth; + private DayOfWeek weekday; + private Relation when; + + public PojoRelativeToWeekdayInMonth(String descriptionPropertiesKey, HolidayType officiality, Year validFrom, Year validTo, YearCycle cycle, FixedWeekdayInMonth weekdayInMonth, DayOfWeek weekday, Relation when) { + super(descriptionPropertiesKey, officiality, validFrom, validTo, cycle); + this.weekdayInMonth = weekdayInMonth; + this.weekday = weekday; + this.when = when; + } + + @Override + public FixedWeekdayInMonth weekdayInMonth() { + return weekdayInMonth; + } + + @Override + public DayOfWeek weekday() { + return weekday; + } + + @Override + public Relation when() { + return when; + } + + +} diff --git a/jollyday-pojo/src/main/java/module-info.java b/jollyday-pojo/src/main/java/module-info.java new file mode 100644 index 000000000..1aa4fc32c --- /dev/null +++ b/jollyday-pojo/src/main/java/module-info.java @@ -0,0 +1,18 @@ +import de.focus_shift.jollyday.core.spi.ConfigurationService; +import de.focus_shift.jollyday.pojo.PojoConfigurationService; + +module de.focus_shift.jollyday.pojo { + + provides ConfigurationService with + PojoConfigurationService; + + requires org.slf4j; + requires org.threeten.extra; + requires de.focus_shift.jollyday.core; + + exports de.focus_shift.jollyday.pojo to + de.focus_shift.jollyday.core, + de.focus_shift.jollyday.pojo.test; + + +} diff --git a/jollyday-pojo/src/main/resources/META-INF/services/de.focus_shift.jollyday.core.spi.ConfigurationService b/jollyday-pojo/src/main/resources/META-INF/services/de.focus_shift.jollyday.core.spi.ConfigurationService new file mode 100644 index 000000000..a7a94289a --- /dev/null +++ b/jollyday-pojo/src/main/resources/META-INF/services/de.focus_shift.jollyday.core.spi.ConfigurationService @@ -0,0 +1 @@ +de.focus_shift.jollyday.pojo.PojoConfigurationService diff --git a/jollyday-pojo/src/test/java/de/focus_shift/jollyday/pojo/test/PojoConfigurationServiceTest.java b/jollyday-pojo/src/test/java/de/focus_shift/jollyday/pojo/test/PojoConfigurationServiceTest.java new file mode 100644 index 000000000..08cec928c --- /dev/null +++ b/jollyday-pojo/src/test/java/de/focus_shift/jollyday/pojo/test/PojoConfigurationServiceTest.java @@ -0,0 +1,41 @@ +package de.focus_shift.jollyday.pojo.test; + +import java.time.LocalDate; +import java.time.MonthDay; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import de.focus_shift.jollyday.core.HolidayManager; +import de.focus_shift.jollyday.core.ManagerParameter; +import de.focus_shift.jollyday.core.ManagerParameters; +import de.focus_shift.jollyday.core.spi.Configuration; +import de.focus_shift.jollyday.core.spi.Limited.YearCycle; +import de.focus_shift.jollyday.pojo.PojoConfigurationService; +import de.focus_shift.jollyday.pojo.PojoFixed; + +import static de.focus_shift.jollyday.core.HolidayType.OBSERVANCE; + +class PojoConfigurationServiceTest { + + @Test + void enhancePojoConfigurationServiceWithSpecialHoliday() { + + PojoConfigurationService javaConfigurationService = new PojoConfigurationService(); + ManagerParameter parameter = ManagerParameters.create("de"); + + HolidayManager holidayManager = HolidayManager.getInstance(parameter); + Assertions.assertFalse(holidayManager.isHoliday(LocalDate.of(2022, 3, 22)), "Precondition 22.3 should be no holiday"); + + // add new holiday for 22.3 dynamically via code/api + Configuration configuration = javaConfigurationService.getConfiguration(parameter); + PojoFixed stgandulfholiday = new PojoFixed("St.Gandulf's Day", OBSERVANCE, null, null, YearCycle.EVERY_YEAR, null, MonthDay.of(3, 22)); + configuration.holidays().fixed().add(stgandulfholiday); + HolidayManager.clearManagerCache(); // we have to clear the manager cache because otherwise the holiday manager from above with old configuration would be reused. + + holidayManager = HolidayManager.getInstance(parameter); + Assertions.assertTrue(holidayManager.isHoliday(LocalDate.of(2022, 3, 22), OBSERVANCE), "Ensure newly added holiday is recognized"); + + } +} + diff --git a/jollyday-pojo/src/test/java/module-info.java b/jollyday-pojo/src/test/java/module-info.java new file mode 100644 index 000000000..7310e21d3 --- /dev/null +++ b/jollyday-pojo/src/test/java/module-info.java @@ -0,0 +1,12 @@ +module de.focus_shift.jollyday.pojo.test { + + opens de.focus_shift.jollyday.pojo.test to + org.junit.platform.commons; + + requires de.focus_shift.jollyday.core; + requires de.focus_shift.jollyday.pojo; + requires org.assertj.core; + requires org.junit.jupiter.api; + requires org.junit.jupiter.params; + requires org.threeten.extra; +} diff --git a/pom.xml b/pom.xml index 220654c95..1ef21c2be 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,8 @@ jollyday-core jollyday-jackson jollyday-jaxb + jollyday-pojo + jollyday-pojo-generator