Introduction to icalendar
Icalendar, short for "ical", is the standard for "calendar Data Exchange" (RFC 2445). It provides a common data format for storing calendar information, such as events, conventions, and to-do items. It not only allows users to send meetings or to-do events by email, but also allows independent use, not limited to a certain transmission protocol.
Currently, all popular calendar tools, such as Lotus Notes, outlook, Gmail, and Apple iCal, support the icalendar standard. Their file extensions include. iCal,. ICS,. IFB, And. icalendar. The C & S (Calendaring and scheduling) core object is a series of calendar and schedule information. Generally, these calendars and itinerary information only contain one icalendar component (the icalendar component is divided into events (vevent), to-do (vtodo), and Journal (vjournal), free/busy time (vfreebusy), vtimezone (time zones), and valarm (alarms), but multiple icalendar components can be organized together.
The first line of the C & S core object must be "begin: vcalendar" and the last line must be "end: vcalendar ". The two rows are mainly composed of a series of calendar attributes and one or more icalendar components.
The following example shows the event "Bastille Day party" that occurred between five o'clock P.M., January 1, July 14, 1997 and, January 1, July 15, 1997 ".
Begin: vcalendar ------ start version: 2.0 ------ version prodid: ical4j V1.0 // en ------ sign for creating this object begin: vevent ------ Event start dtstart: 19970714t170000z ------ Event start time dtend: 19970715t040000z ------ Event End Time Summary: Bastille Day party ------ Event summary end: vevent ------ Event end: vcalendar ------ end
Icalendar programming Basics
Ical4j Introduction
Ical4j (2.0) is a set of Java APIs for reading and writing icalendar data streams. It supports the icalendar specification RFC 2445, including the parser, object model, and generator.
File read/write
Reading and writing in any file format is the most basic operation. Listing 1 demonstrates these two basic operations. The calendarbuilder object is used to parse and construct the icalendar model through the input stream. It is worth noting that calendarbuilder is NOT thread-safe.
Listing 1: icalendar file read/write example
Public static void readandwrite (string in, string out) throws ioexception, parserexception, validationexception {fileinputstream fin = new fileinputstream (in); calendarbuilder builder = new calendarbuilder (); Calendar calendar = builder. build (FIN); // todo: Process icalendar data... ... Fileoutputstream fout = new fileoutputstream (out); calendaroutputter outputter = new calendaroutputter (); outputter. Output (calendar, fout );}
Icalendar Index
After indexing components and attributes, you can search for components and attributes more effectively. In general, you can use indexes to continuously check whether an event (or convention, etc.) exists. In this scenario, you need to update calendar regularly and check whether the event already exists. Because you need to constantly check events in the calendar, indexing events in the calendar makes sense.
Listing 2: icalendar Index
// Create the index list indexedcomponentlist indexedevents = new indexedcomponentlist (mycalendar. getcomponents (component. vevent), property. UID); // check the event for (iterator I = inputcalendar. getcomponents (component. vevent ). iterator (); I. hasnext ();) {vevent event = (vevent) I. next (); component existing = indexedevents. getcomponent (event. getuid (). getvalue (); If (existing = NULL) {mycalendar. getcomponents (). add (event ); } Else if (! Event. equals (existing) {// delete an existing event and add the modified event mycalendar. getcomponents (). remove (existing); mycalendar. getcomponents (). add (event );}}
As shown in List 2, note that the UID is used to identify a unique event. After obtaining the index component list, we can use UID to check whether an event exists. Modify the event if it exists. Otherwise, add the event.
Create calendar/events/meetings
Icalendar provides a common data format for storing calendar information such as events, conventions, and to-do items, how to create events, conventions, and to-do events is a matter of great concern, such as listing 3. A calendar must have some basic attributes, such as prodid and version, but only once. Some are optional, such as calscale. For details, see RFC 2445.
Listing 3: Create an event example
// Create a time zone)
Timezoneregistry registry = timezoneregistryfactory. getinstance (). createregistry ();
Timezone = registry. gettimezone ("America/mexico_city ");
Vtimezone TZ = timezone. getvtimezone ();
// Start time: nine o'clock A.M., January 1, April 1, 2008
Java. util. Calendar startdate = new gregoriancalendar ();
Startdate. settimezone (timezone );
Startdate. Set (Java. util. Calendar. Month, java. util. Calendar. yml );
Startdate. Set (Java. util. Calendar. day_of_month, 1 );
Startdate. Set (Java. util. Calendar. Year, 2008 );
Startdate. Set (Java. util. Calendar. hour_of_day, 9 );
Startdate. Set (Java. util. Calendar. Minute, 0 );
Startdate. Set (Java. util. Calendar. Second, 0 );
// The end time is: April 1, 2008 one o'clock P.M.
Java. util. Calendar enddate = new gregoriancalendar ();
Enddate. settimezone (timezone );
Enddate. Set (Java. util. Calendar. Month, java. util. Calendar. yml );
Enddate. Set (Java. util. Calendar. day_of_month, 1 );
Enddate. Set (Java. util. Calendar. Year, 2008 );
Enddate. Set (Java. util. Calendar. hour_of_day, 13 );
Enddate. Set (Java. util. Calendar. Minute, 0 );
Enddate. Set (Java. util. Calendar. Second, 0 );
// Create an event
String eventname = "Progress Meeting ";
Datetime start = new datetime (startdate. gettime ());
Datetime end = new datetime (enddate. gettime ());
Vevent meeting = new vevent (START, end, eventname );
// Add Time Zone Information
Meeting. getproperties (). Add (tz. gettimezoneid ());
// Generate a unique identifier
Uidgenerator ug = new uidgenerator ("uidgen ");
UID uid = ug. generateuid ();
Meeting. getproperties (). Add (UID );
// Add participants.
Attendee dev1 = new attendee (URI. Create ("mailto: dev1@mycompany.com "));
Dev1.getparameters (). Add (role. req_participant ipant );
Dev1.getparameters (). Add (New CN ("Developer 1 "));
Meeting. getproperties (). Add (dev1 );
Attendee dev2 = new attendee (URI. Create ("mailto: dev2@mycompany.com "));
Dev2.getparameters (). Add (role. opt_participant ipant );
Dev2.getparameters (). Add (New CN ("developer 2 "));
Meeting. getproperties (). Add (dev2 );
// Create a calendar
Net. Fortuna. ical4j. model. Calendar icscalendar = new net. Fortuna. ical4j. model. Calendar ();
Icscalendar. getproperties (). Add (New prodid ("-// events calendar // ical4j 1.0 // en "));
Icscalendar. getproperties (). Add (calscale. Gregorian );
// Add an event
Icscalendar. getcomponents (). Add (meeting );
Timezoneregistry indicates a repository (repository) of the net. Fortuna. ical4j. model. timezone handle ). Listing 4 demonstrates how to obtain a timezoneregistry and obtain a timezone through timezoneregistry ).
Listing 4: getting the time zone example
CalendarBuilder builder = new CalendarBuilder(); Calendar calendar = builder.build(new FileInputStream("mycalendar.ics")); TimeZoneRegistry registry = builder.getRegistry(); TimeZone tz = registry.getTimeZone("Australia/Melbourne");
Add attachment and binary data
The ical4j code library allows users to add binary data. Class attach can be used to add binary data, such as code list 5.
Code List 5: Example of adding binary data
Public static void Merge (string subject, string out, string binary) throws ioexception, parserexception, validationexception, parseexception {fileinputstream bin = new fileinputstream (Binary); bytearrayoutputstream bout = new bytearrayoutputstream (); calendar calendar = New Calendar (); dateformat format = new simpledateformat ("mm/DD/YYYY hh: mm"); datetime start = new datetime (format. parse ("11/09/2009 08:00 "). gettime (); datetime end = new datetime (format. parse ("11/09/2009 09:00 "). gettime (); Calendar. getproperties (). add (New prodid ("-// Ben Fortuna // ical4j 1.0 // en"); Calendar. getproperties (). add (version. version_2_0); Calendar. getproperties (). add (calscale. gregorian); vevent event = new vevent (START, end, subject); event. getproperties (). add (New UID (New uidgenerator ("ical4j "). generateuid (). getvalue (); For (INT I = bin. read (); I> = 0;) {bout. write (I); I = bin. read ();} parameterlist Params = new parameterlist (); Params. add (encoding. base64); Params. add (value. binary); attach = new attach (Params, bout. tobytearray (); event. getproperties (). add (attach); Calendar. getcomponents (). add (event); // verify the calendar. validate (); fileoutputstream fout = new fileoutputstream (out); calendaroutputter outputter = new calendaroutputter (); outputter. output (calendar, fout );}
The program output result is:
BEGIN:VCALENDAR PRODID:-//Ben Fortuna//iCal4j 1.0//EN VERSION:2.0 CALSCALE:GREGORIAN BEGIN:VEVENT DTSTAMP:20091119T124443Z DTSTART:20091109T080000 DTEND:20091109T090000 SUMMARY:iCal4j Attach Binary Example UID:20091119T124443Z-iCal4j@192.168.1.100 ATTACH;ENCODING=BASE64;VALUE=BINARY:VGhp333cyBhIENsaWVudCBmb3IgRS1CdXNpb mVzcyBJbWFnZQ== END:VEVENT END:VCALENDAR
Cyclic events
Icalendar supports circular events, that is, events occur more than once. Generally, a series of dates (rdate) or a circular rule (rrule) are used ). Here is a simple rrule example.
Events occur on July 29, January every month.
Rrule: freq = monthly; interval = 2; byday = 29
Note: The non-leap year in February only has 28 days. Therefore, this rule indicates that an event will jump between February and February of the previous year.
The following describes how the program generates a series of date and a rrule ). Listing 6 describes how to generate a date list.
Listing 6: Example of creating a loop event (using rdate)
Public static void addrdate (string subject, string out) throws ioexception, parserexception, validationexception, urisyntaxexception, parseexception {calendar ar calendar AR = new calendar AR (); Calendar. getproperties (). add (New prodid ("-// Ben Fortuna // ical4j 1.0 // en"); Calendar. getproperties (). add (version. version_2_0); Calendar. getproperties (). add (calscale. gregorian); periodlist = new periodlist (); parameterlist paralist = new parameterlist (); dateformat format = new simpledateformat ("mm/DD/YYYY hh: mm "); datetime startdate1 = new datetime (format. parse ("11/09/2009 08:00"); datetime startdate2 = new datetime (format. parse ("11/10/2009 09:00"); datetime enddate1 = new datetime (format. parse ("11/09/2009 09:00"); datetime enddate2 = new datetime (format. parse ("11/10/2009"); periodlist. add (New Period (startdate1, enddate1); periodlist. add (New Period (startdate2, enddate2); vevent event = new vevent (startdate1, enddate1, subject); event. getproperties (). add (New UID (New uidgenerator ("ical4j "). generateuid (). getvalue (); paralist. add (parameterfactoryimpl. getinstance (). createparameter (value. period. getname (), value. period. getvalue (); rdate = new rdate (paralist, periodlist); event. getproperties (). add (rdate); Calendar. getcomponents (). add (event); // verify the calendar. validate (); fileoutputstream fout = new fileoutputstream (out); calendaroutputter outputter = new calendaroutputter (); outputter. output (calendar, fout );}
The program output result is:
Begin: vcalendar
Prodid:-// Ben Fortuna // ical4j 1.0 // en
Version: 2.0
Calscale: Gregorian
Begin: vevent
Dtstamp: 20091119t100938z
Dtstart: 20091109t000000z
Dtend: 20091109t020.z
Summary: ical4j rdate example
UID: 20091119T100938Z-iCal4j@IBM-3C6595B4005.cn.ibm.com
Rdate; value = period: 20091109t000000z/20091109t00000z, 20091110t00000z/200 91110t030000z
End: vevent
End: vcalendar
Listing 7 demonstrates how to use rrule to create a cyclic event, which lasts four times every week from January 1, November 9, 2009.
Code listing 7: Example of creating a loop event (using rrule)
Public static void addrrule (string subject, string out)
Throws ioexception, parserexception, validationexception,
Urisyntaxexception, parseexception {
Calendar calendar = New Calendar ();
Dateformat format = new simpledateformat ("mm/DD/YYYY hh: mm ");
Datetime start = new datetime (format. parse ("11/09/2009 08:00"). gettime ());
Datetime end = new datetime (format. parse ("11/09/2009 09:00"). gettime ());
Calendar. getproperties (). Add (New prodid ("-// Ben Fortuna // ical4j 1.0 // en "));
Calendar. getproperties (). Add (version. version_2_0 );
Calendar. getproperties (). Add (calscale. Gregorian );
Vevent event = new vevent (START, end, subject );
Event. getproperties (). Add (New UID (New uidgenerator ("ical4j"). generateuid ()
. Getvalue ()));
Recur = new recur (recur. Weekly, 4 );
Recur. setinterval (2 );
Rrule rule = new rrule (Recur );
Event. getproperties (). Add (rule );
Calendar. getcomponents (). Add (event );
// Verify
Calendar. Validate ();
Fileoutputstream fout = new fileoutputstream (out );
Calendaroutputter outputter = new calendaroutputter ();
Outputter. Output (calendar, fout );
}
The program output result is:
Begin: vcalendar
Prodid:-// Ben Fortuna // ical4j 1.0 // en
Version: 2.0
Calscale: Gregorian
Begin: vevent
Dtstamp: 20091119t094724z
Dtstart: 20091109t080000
Dtend: 20091109t090000
Summary: ical4j rrule usage example
UID: 20091119T094724Z-iCal4j@IBM-3C6595B4005.cn.ibm.com
Rrule: freq = weekly; interval = 2; Count = 4
End: vevent
End: vcalendar
Extension
In general, components, properties, and parameters that are not defined in rfc2445 are called non-standard or extended objects. Icalendar allows you to expand components/attributes/parameters, but the name must start with X-and be compatible with the icalendar standard (unless ical4j is enabled. parsing. objects are represented by xcomponent, xproperty, and xparameter respectively.
The following example demonstrates how to extend the attribute ical4j_extension_sample of an event, as shown in listing 8.
Listing 8: extended Event property example
Public static void extension (string subject, string out)
Throws ioexception, parserexception, validationexception, urisyntaxexception
, Parseexception {
Calendar calendar = New Calendar ();
Dateformat format = new simpledateformat ("mm/DD/YYYY hh: mm ");
Datetime start = new datetime (format. parse ("11/09/2009 08:00"). gettime ());
Datetime end = new datetime (format. parse ("11/09/2009 09:00"). gettime ());
Calendar. getproperties (). Add (New prodid ("-// Ben Fortuna // ical4j 1.0 // en "));
Calendar. getproperties (). Add (version. version_2_0 );
Calendar. getproperties (). Add (calscale. Gregorian );
Vevent event = new vevent (START, end, subject );
Event. getproperties (). Add (New UID (New uidgenerator ("ical4j ")
. Generateuid (). getvalue ()));
// Note: the extended attributes must start with X-
Property xproperty = propertyfactoryimpl. getinstance ()
. Createproperty ("X-iCal4j-extension ");
Xproperty. setvalue ("ical4j_extension_sample ");
Event. getproperties (). Add (xproperty );
Calendar. getcomponents (). Add (event );
// Validate
Calendar. Validate ();
Fileoutputstream fout = new fileoutputstream (out );
Calendaroutputter outputter = new calendaroutputter ();
Outputter. Output (calendar, fout );
}
The program output result is:
Begin: vcalendar
Prodid:-// Ben Fortuna // ical4j 1.0 // en
Version: 2.0
Calscale: Gregorian
Begin: vevent
Dtstamp: 20091119t093429z
Dtstart: 20091109t080000
Dtend: 20091109t090000
Summary: ical4j extension example
UID: 20091119T093429Z-iCal4j@IBM-3C6595B4005.cn.ibm.com
X-iCal4j-extension: ical4j_extension_sample.
End: vevent
End: vcalendar
Introduction to ical4j Connector
Ical4j connector Ctor is an extension of the ical4j code base. It provides support for connecting back-end calendar/vCard servers (supported HTTP methods include get, Head, post, put, delete, Trace, copy, move), including caldav, server compatible with carddav, and JCR (Java content repository ).
Http://tech.ddvip.com/2010-03/1269846004148755_4.html