Skip to content
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

Move calendar initialization to server startup #5037

Merged
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
1 change: 1 addition & 0 deletions Integrations/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies {
implementation project(':log-factory')

testImplementation project(':engine-test-utils')
testImplementation TestTools.projectDependency(project, 'engine-time')

testRuntimeOnly project(':log-to-slf4j')
// add configs, and some runtime dependencies to test classpaths
Expand Down
1 change: 1 addition & 0 deletions Plot/Plot.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies {

testImplementation TestTools.projectDependency(project, 'Util')
testImplementation TestTools.projectDependency(project, 'engine-table')
testImplementation TestTools.projectDependency(project, 'engine-time')

testRuntimeOnly project(path: ':configs')
testRuntimeOnly project(path: ':test-configs')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
*/
package io.deephaven.plot.axistransformations;

import io.deephaven.base.testing.BaseArrayTestCase;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.time.calendar.CalendarInit;
import io.deephaven.time.calendar.Calendars;
import junit.framework.TestCase;

import java.nio.file.Paths;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Objects;

public class TestAxisTransformBusinessCalendar extends BaseArrayTestCase {
public class TestAxisTransformBusinessCalendar extends TestCase {

private static final ZoneId TZ_JP = ZoneId.of("Asia/Tokyo");

Expand Down Expand Up @@ -41,6 +42,7 @@ public class TestAxisTransformBusinessCalendar extends BaseArrayTestCase {

@Override
public void setUp() throws Exception {
CalendarInit.init();
final String path = Paths
.get(Objects.requireNonNull(TestAxisTransformBusinessCalendar.class.getResource("/JPOSE.calendar"))
.toURI())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
package io.deephaven.plot.axistransformations;

import io.deephaven.time.calendar.BusinessCalendar;
import io.deephaven.time.calendar.CalendarInit;
import io.deephaven.time.calendar.Calendars;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
Expand All @@ -28,6 +30,11 @@ public class TestAxisTransforms {
final double d9 = -d4;
private final double delta = 0.00001;

@Before
public void setUp() {
CalendarInit.init();
}

@Test
public void testLog() {
final AxisTransform transform = AxisTransforms.LOG;
Expand Down
1 change: 1 addition & 0 deletions engine/time/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies {
implementation project(':Configuration')
implementation project(':log-factory')
implementation depJdom2
Classpaths.inheritDagger(project)

testImplementation TestTools.projectDependency(project, 'Base')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private YearData getYearData(final int year) {
* is different from the schedule for a standard business day or weekend.
* @throws RequirementFailure if any argument is null.
*/
BusinessCalendar(final String name, final String description, final ZoneId timeZone,
public BusinessCalendar(final String name, final String description, final ZoneId timeZone,
final LocalDate firstValidDate, final LocalDate lastValidDate,
final CalendarDay<LocalTime> standardBusinessDay, final Set<DayOfWeek> weekendDays,
final Map<LocalDate, CalendarDay<Instant>> holidays) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@
import org.jdom2.input.SAXBuilder;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* A parser for reading business calendar XML files.
*
* <p>
* Business calendar XML files should be formatted as:
*
* <pre>
Expand Down Expand Up @@ -56,14 +59,14 @@
*
* In addition, legacy XML files are supported. These files have dates formatted as `yyyyMMdd` instead of ISO-8601
* `yyy-MM-dd`. Additionally, legacy uses `businessPeriod` tags in place of the `businessTime` tags.
*
*
* <pre>
* {@code
* <!-- Current format -->
* <businessTime><open>09:30</open><close>16:00</close></businessTime>
* }
* </pre>
*
*
* <pre>
* {@code
* <!-- Legacy format -->
Expand All @@ -73,7 +76,7 @@
*
* The legacy format may be deprecated in a future release.
*/
class BusinessCalendarXMLParser {
public final class BusinessCalendarXMLParser {

private static class BusinessCalendarInputs {
private String calendarName;
Expand Down Expand Up @@ -108,42 +111,82 @@ public static BusinessCalendar loadBusinessCalendar(@NotNull final String file)
public static BusinessCalendar loadBusinessCalendar(@NotNull final File file) {
Require.neqNull(file, "file");
final BusinessCalendarInputs in = parseBusinessCalendarInputs(file);
return new BusinessCalendar(in.calendarName, in.description,
in.timeZone, in.firstValidDate, in.lastValidDate,
in.standardBusinessDay, in.weekendDays, in.holidays);
}

/**
* Loads a business calendar from an XML input stream.
*
* @param inputStream XML input stream
* @return business calendar.
* @throws RequirementFailure if the input is null
*/
public static BusinessCalendar loadBusinessCalendar(@NotNull final InputStream inputStream) {
Require.neqNull(inputStream, "inputStream");
final BusinessCalendarInputs in = parseBusinessCalendarInputs(inputStream);
return new BusinessCalendar(in.calendarName, in.description,
in.timeZone, in.firstValidDate, in.lastValidDate,
in.standardBusinessDay, in.weekendDays, in.holidays);
}

/**
* Loads a business calendar from an XML resource.
*
* @param resource XML input stream
* @return business calendar.
*/
public static BusinessCalendar loadBusinessCalendarFromResource(String resource) throws IOException {
final InputStream in = Calendars.class.getResourceAsStream(resource);
if (in == null) {
throw new RuntimeException("Could not open resource " + resource + " from classpath");
}
try (final InputStream bin = new BufferedInputStream(in)) {
return loadBusinessCalendar(bin);
}
}

private static BusinessCalendarInputs parseBusinessCalendarInputs(@NotNull final File file) {
Require.neqNull(file, "file");
try {
final BusinessCalendarInputs calendarElements = new BusinessCalendarInputs();

Element root = loadXMLRootElement(file);
calendarElements.calendarName = getText(getRequiredChild(root, "name"));
calendarElements.timeZone = TimeZoneAliases.zoneId(getText(getRequiredChild(root, "timeZone")));
calendarElements.description = getText(root.getChild("description"));
calendarElements.holidays = parseHolidays(root, calendarElements.timeZone);
final String firstValidDateStr = getText(root.getChild("firstValidDate"));
calendarElements.firstValidDate =
firstValidDateStr == null ? Collections.min(calendarElements.holidays.keySet())
: DateTimeUtils.parseLocalDate(firstValidDateStr);
final String lastValidDateStr = getText(root.getChild("lastValidDate"));
calendarElements.lastValidDate =
lastValidDateStr == null ? Collections.max(calendarElements.holidays.keySet())
: DateTimeUtils.parseLocalDate(lastValidDateStr);

// Set the default values
final Element defaultElement = getRequiredChild(root, "default");
calendarElements.weekendDays = parseWeekendDays(defaultElement);
calendarElements.standardBusinessDay = parseCalendarDaySchedule(defaultElement);

return calendarElements;
return fill(loadXMLRootElement(file));
} catch (Exception e) {
throw new RuntimeException("Unable to load calendar file: file=" + file.getPath(), e);
}
}

private static BusinessCalendarInputs parseBusinessCalendarInputs(@NotNull final InputStream in) {
Require.neqNull(in, "in");
try {
return fill(loadXMLRootElement(in));
} catch (Exception e) {
throw new RuntimeException("Unable to load calendar file: inputStream=" + in, e);
}
}

private static BusinessCalendarInputs fill(Element root) throws Exception {
final BusinessCalendarInputs calendarElements = new BusinessCalendarInputs();
calendarElements.calendarName = getText(getRequiredChild(root, "name"));
calendarElements.timeZone = TimeZoneAliases.zoneId(getText(getRequiredChild(root, "timeZone")));
calendarElements.description = getText(root.getChild("description"));
calendarElements.holidays = parseHolidays(root, calendarElements.timeZone);
final String firstValidDateStr = getText(root.getChild("firstValidDate"));
calendarElements.firstValidDate =
firstValidDateStr == null ? Collections.min(calendarElements.holidays.keySet())
: DateTimeUtils.parseLocalDate(firstValidDateStr);
final String lastValidDateStr = getText(root.getChild("lastValidDate"));
calendarElements.lastValidDate =
lastValidDateStr == null ? Collections.max(calendarElements.holidays.keySet())
: DateTimeUtils.parseLocalDate(lastValidDateStr);

// Set the default values
final Element defaultElement = getRequiredChild(root, "default");
calendarElements.weekendDays = parseWeekendDays(defaultElement);
calendarElements.standardBusinessDay = parseCalendarDaySchedule(defaultElement);
return calendarElements;
}

private static Element loadXMLRootElement(File calendarFile) throws Exception {
final Document doc;

Expand All @@ -159,6 +202,21 @@ private static Element loadXMLRootElement(File calendarFile) throws Exception {
return doc.getRootElement();
}

private static Element loadXMLRootElement(InputStream in) throws Exception {
final Document doc;

try {
final SAXBuilder builder = new SAXBuilder();
doc = builder.build(in);
} catch (JDOMException e) {
throw new Exception("Error parsing business calendar: inputStream=" + in, e);
} catch (IOException e) {
throw new Exception("Error loading business calendar: inputStream=" + in, e);
}

return doc.getRootElement();
}

private static Element getRequiredChild(@NotNull final Element root, final String child) throws Exception {
Element element = root.getChild(child);
if (element != null) {
Expand Down
Loading
Loading