BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_calendarloader

Detailed Description

Outline

Purpose

Provide a protocol (or pure interface) for loading calendars.

Classes

See also
bdlt_calendarcache, bdlt_packedcalendar

Description

This component provides a protocol, bdlt::CalendarLoader, for loading calendars from a specific source. Each repository of calendar information can be supported by a distinct implementation of the CalendarLoader protocol. The protocol's primary method, load, loads a calendar into a bdlt::PackedCalendar object. The calendar to load is identified by name, which is specified by a null-terminated C-style string (i.e., const char *).

Thread Safety

Unless otherwise documented, a single calendar loader object is not safe for concurrent access by multiple threads. Classes derived from bdlt::CalendarLoader that are specifically designed for concurrent access must be documented as such. Unless specifically documented otherwise, separate objects of classes derived from bdlt::CalendarLoader may safely be used in separate threads.

Usage

This section illustrates intended use of this component.

Example 1: Implementing the bdlt::CalendarLoader Protocol

This example demonstrates an elided concrete implementation of the bdlt::CalendarLoader protocol that interprets calendar information contained in ASCII strings that are formatted using JSON. Note that, in general, an implementation of bdlt::CalendarLoader must obtain calendar information from some data source. Our elided implementation leaves it unspecified as to where the JSON strings are obtained (i.e., whether from a file system, a database, a local or remote service, etc.).

First, we show the JSON format that our calendar loader accepts. For simplicity, we omit support for holiday codes and weekend-days transitions:

{
"firstDate": "YYYY-MM-DD",
"lastDate": "YYYY-MM-DD",
"weekendDays": [ wd, ... ],
"holidays": [ "YYYY-MM-DD", ... ]
}

Note that "YYYY-MM-DD" is an ISO 8601 representation for the value of a bdlt::Date object and wd is an integer in the range [1 .. 7]. The range used for specifying weekend days corresponds directly to the bdlt::DayOfWeek::Enum enumeration, [e_SUN = 1 .. e_SAT] (see bdlt_dayofweek ). We assume that the four JSON attributes, "firstDate", "lastDate", "weekendDays", and "holidays", must occur in the JSON string in the order in which they appear in the above display, but only "firstDate" and "lastDate" are required attributes.

Then, we define the interface of our implementation:

/// This class provides a concrete implementation of the
/// `bdlt::CalendarLoader` protocol (an abstract interface) for loading
/// a calendar. This elided implementation obtains calendar information
/// from ASCII strings formatted using JSON. The source of the strings
/// is unspecified.
class MyCalendarLoader : public bdlt::CalendarLoader {
public:
// CREATORS
/// Create a `MyCalendarLoader` object.
MyCalendarLoader();
/// Destroy this object.
virtual ~MyCalendarLoader();
// MANIPULATORS
/// Load, into the specified `result`, the calendar identified by
/// the specified `calendarName`. Return 0 on success, and a
/// non-zero value otherwise. If the calendar corresponding to
/// `calendarName` is not found, 1 is returned with no effect on
/// `*result`. If a non-zero value other than 1 is returned
/// (indicating a different error), `*result` is valid, but its
/// value is undefined.
virtual int load(bdlt::PackedCalendar *result,
const char *calendarName);
};
Definition bdlt_calendarloader.h:322
virtual int load(PackedCalendar *result, const char *calendarName)=0
Definition bdlt_packedcalendar.h:592

Next, we implement the creators, trivially, as MyCalendarLoader does not contain any instance data members:

// CREATORS
inline
MyCalendarLoader::MyCalendarLoader()
{
}
inline
MyCalendarLoader::~MyCalendarLoader()
{
}

Then, we implement the load function:

// MANIPULATORS
int MyCalendarLoader::load(bdlt::PackedCalendar *result,
const char *calendarName)
{

Next, we look up the calendar identified by calendarName and load the corresponding text into a bsl::string object, json (as stated earlier, we do not specify in this example from where the calendar information is obtained):

// Obtain the information for the calendar identified by 'calendarName'
// from an unspecified data source and load it into the 'json' string.
// Since a JSON parser is not available to 'bdlt', this example assumes
// that 'json' is populated with the following specific data:
//..
// {
// "firstDate": "1990-01-01",
// "lastDate": "1990-12-31",
// "weekendDays": [ 1, 7 ],
// "holidays": [ "1990-05-28", "1990-07-04", "1990-09-03" ]
// }
//..
// Similarly, we hard-wire the value of a status flag, 'rc', to
// indicate that this string was successfully retrieved from the data
// source.
int rc = 0; // success obtaining calendar information
if (rc != 0) {
return 1; // RETURN
}
Definition bslstl_string.h:1281

Note that the non-zero value 1 is returned only in the case where the calendar information corresponding to calendarName cannot be found (per the contract for the load method).

Then, we parse the "firstDate" and "lastDate" attributes from the json string, loading the results into like-named variables:

// Parse the "firstDate" and "lastDate" JSON attributes and load the
// results into 'firstDate' and 'lastDate', respectively. It is an
// error if either of the "firstDate" or "lastDate" attributes are
// missing, or if they are out of order.
bdlt::Date firstDate;
bdlt::Date lastDate;
// For the purposes of this Usage, we hard-wire the first and last
// dates that are hypothetically parsed from the 'json' string, and
// set the 'rc' status flag indicating that parsing succeeded.
firstDate.setYearMonthDay(1990, 1, 1);
lastDate.setYearMonthDay( 1990, 12, 31);
rc = 0; // success parsing "firstDate" and "lastDate" attributes
if (rc != 0 || firstDate > lastDate) {
return 2; // RETURN
}
result->removeAll();
result->setValidRange(firstDate, lastDate);
Definition bdlt_date.h:294
void setYearMonthDay(int year, int month, int day)
Definition bdlt_date.h:871
void setValidRange(const Date &firstDate, const Date &lastDate)

Next, we parse the "weekendDays" attribute from json and load the result into a bdlt::DayOfWeekSet object, dayOfWeekSet:

// For the purposes of this Usage, we hard-wire a boolean flag
// indicating that the "weekendDays" attribute was hypothetically
// detected in the 'json' string.
bool isWeekendDaysAttributePresent = true;
if (isWeekendDaysAttributePresent) {
// Parse the "weekendDays" JSON attribute and load 'dayOfWeekSet'
// with the result.
bdlt::DayOfWeekSet dayOfWeekSet;
// For the purposes of this Usage, we hard-wire the weekend days
// that are hypothetically parsed from the 'json' string, and set
// the 'rc' status flag indicating that parsing succeeded.
dayOfWeekSet.add(bdlt::DayOfWeek::e_SUN);
dayOfWeekSet.add(bdlt::DayOfWeek::e_SAT);
rc = 0; // success parsing "weekendDays" attribute
if (rc != 0) {
return 3; // RETURN
}
result->addWeekendDays(dayOfWeekSet);
}
Definition bdlt_dayofweekset.h:398
void add(DayOfWeek::Enum value)
Add the specified value to this set.
Definition bdlt_dayofweekset.h:790
void addWeekendDays(const DayOfWeekSet &weekendDays)
@ e_SUN
Definition bdlt_dayofweek.h:125
@ e_SAT
Definition bdlt_dayofweek.h:131

Now, we parse the "holidays" attribute from json and load the result into a bsl::vector<bdlt::Date> object, holidays:

// For the purposes of this Usage, we hard-wire a boolean flag
// indicating that the "holidays" attribute was hypothetically detected
// in the 'json' string.
bool isHolidaysAttributePresent = true;
if (isHolidaysAttributePresent) {
// Parse the "holidays" JSON attribute and load 'holidays' with the
// result.
// For the purposes of this Usage, we hard-wire the holidays that
// are hypothetically parsed from the 'json' string, and set the
// 'rc' status flag indicating that parsing succeeded.
holidays.push_back(bdlt::Date(1990, 5, 28)); // Memorial Day
holidays.push_back(bdlt::Date(1990, 7, 4)); // Independence Day
holidays.push_back(bdlt::Date(1990, 9, 3)); // Labor Day
rc = 0; // success parsing "holidays" attribute
if (rc != 0) {
return 4; // RETURN
}
while (it != holidays.end()) {
const bdlt::Date& holiday = *it;
if (holiday < firstDate || holiday > lastDate) {
return 5; // RETURN
}
result->addHoliday(holiday);
++it;
}
}
void addHoliday(const Date &date)
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2511
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2519
Definition bslstl_vector.h:1025
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:3760
VALUE_TYPE const * const_iterator
Definition bslstl_vector.h:1058

Note that the addHoliday method can extend the range of the calendar. Our calendar loader instead imposes the requirement that the dates specified in the "holidays" JSON attribute must be within the range [firstDate .. lastDate].

Finally, we return 0 indicating success:

return 0;
}