Managing Calendar and Invites in Java
- 6 minutes read - 1071 wordsCalendars are used to store formation for various events. Calendar viewer displays the month-date view and for each day displays the events/reminders information.
Invites are the events in the form of email. Once the invite for an event sent to a user via email then that event will be stored in the calendar view and same can be seen in the day information of the calendar view.
Calendars
Calendar data can be stored in files; there are some standard formats for storing calendars
iCalendar is a computer file format which allows Internet users to send meeting requests and tasks to other Internet users, via email, or sharing files with an extension of .ics
. Recipients of the iCalendar
data file (with supporting software, such as an email client or calendar application) can respond to the sender easily or counter propose another meeting date/time.
Core object
iCalendar
’s design was based on the previous file format vCalendar
created by the Internet Mail Consortium (IMC).
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:uid1@example.com
DTSTAMP:19970714T170000Z
ORGANIZER;CN=John Doe:MAILTO:john.doe@example.com
DTSTART:19970714T170000Z
DTEND:19970715T035959Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR
Other tags
Events (VEVENT). To-do (VTODO), VJOURNAL, VFREEBUSY, etc
Supported Products
iCalendar
is used and supported by a large number of products, including Google Calendar, Apple iCal, GoDaddy Online Group Calendar, IBM Lotus Notes, Yahoo! Calendar, Evolution (software) , KeepandShare, Lightning extension for Mozilla Thunderbird and SeaMonkey, and by Microsoft Outlook.
Java Solution
We can export events information in a .ics
file as per the iCalendar
format, using Java File IO apis. Similarly Invites/Meeting requests can be sent as email using Java Mail API. Here is flow diagram.
Implementation steps for Sending Email Invites
-
Register calendar mime type in java
// register the text/calendar mime type MimetypesFileTypeMap mimetypes = (MimetypesFileTypeMap)MimetypesFileTypeMap.getDefaultFileTypeMap(); mimetypes.addMimeTypes("text/calendar ics ICS"); // register the handling of text/calendar mime type MailcapCommandMap mailcap = (MailcapCommandMap) MailcapCommandMap.getDefaultCommandMap(); mailcap.addMailcap("text/calendar;;x-java-content-handler=com.sun.mail.handlers.text_plain");
-
Create message and assign recipients and sender.
// create a message MimeMessage msg = new MimeMessage(session); // set the from and to address InternetAddress addressFrom = new InternetAddress(from); msg.setFrom(addressFrom); InternetAddress[] addressTo = new InternetAddress[recipients.length]; for (int i = 0; i < recipients.length; i++) { addressTo[i] = new InternetAddress(recipients[i]); } msg.setRecipients(Message.RecipientType.TO, addressTo);
-
Create an alternative body part.
// Create an alternative Multipart Multipart multipart = new MimeMultipart("alternative");
-
Set body of invite.
// part 1, html text MimeBodyPart descriptionPart = new MimeBodyPart(); String content = "<font size='\'2\''>" + emailMsgTxt + "</font>"; descriptionPart.setContent(content, "text/html; charset=utf-8"); multipart.addBodyPart(descriptionPart);
-
Add Calendar part
// Add part two, the calendar BodyPart calendarPart = buildCalendarPart(); multipart.addBodyPart(calendarPart);
The method calendar part can be generated in following ways.
- Using Plain Text
SimpleDateFormat iCalendarDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmm'00'"); BodyPart calendarPart = new MimeBodyPart(); String calendarContent = "BEGIN:VCALENDAR\n" + "METHOD:REQUEST\n" + "PRODID: BCP - Meeting\n" + "VERSION:2.0\n" + "BEGIN:VEVENT\n" + "DTSTAMP:" + iCalendarDateFormat.format(currentdate) + "\n" + "DTSTART:" + iCalendarDateFormat.format(startdatetime) + "\n" + "DTEND:" + iCalendarDateFormat.format(enddatetime) + "\n" + "SUMMARY:Test 123\n" + "UID:324\n" + "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:MAILTO:kuldeep@nagarro.com\n" + "ORGANIZER:MAILTO:kuldeep@nagarro.com\n" + "LOCATION:gurgaon\n" + "DESCRIPTION:learn some stuff\n" + "SEQUENCE:0\n" + "PRIORITY:5\n" + "CLASS:PUBLIC\n" + "STATUS:CONFIRMED\n" + "TRANSP:OPAQUE\n" + "BEGIN:VALARM\n" + "ACTION:DISPLAY\n" + "DESCRIPTION:REMINDER\n" + "TRIGGER;RELATED=START:-PT00H15M00S\n" + "END:VALARM\n" + "END:VEVENT\n" + "END:VCALENDAR"; calendarPart.addHeader("Content-Class","urn:content-classes:calendarmessage"); calendarPart.setContent(calendarContent, "text/calendar;method=CANCEL");
- Using ICal4J Library ( Ref to Next section for more detail on ICal4J)
// Create a TimeZone TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry(); TimeZone timezone = registry.getTimeZone("America/Mexico_City"); java.util.Calendar startDate = new GregorianCalendar(); startDate.setTimeZone(timezone); startDate.set(java.util.Calendar.MONTH, java.util.Calendar.JANUARY); startDate.set(java.util.Calendar.DAY_OF_MONTH, 18); startDate.set(java.util.Calendar.YEAR, 2012); startDate.set(java.util.Calendar.HOUR_OF_DAY, 9); startDate.set(java.util.Calendar.MINUTE, 0); startDate.set(java.util.Calendar.SECOND, 0); // End Date is on: April 1, 2008, 13:00 java.util.Calendar endDate = new GregorianCalendar(); endDate.setTimeZone(timezone); endDate.set(java.util.Calendar.MONTH, java.util.Calendar.JANUARY); endDate.set(java.util.Calendar.DAY_OF_MONTH, 18); endDate.set(java.util.Calendar.YEAR, 2012); endDate.set(java.util.Calendar.HOUR_OF_DAY, 13); endDate.set(java.util.Calendar.MINUTE, 0); endDate.set(java.util.Calendar.SECOND, 0); // Create the 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 attendees.. Attendee dev1 = new Attendee(URI.create("mailto:dev1@mycompany.com")); dev1.getParameters().add(Role.REQ_PARTICIPANT); 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); dev2.getParameters().add(new Cn("Developer 2")); meeting.getProperties().add(dev2); VAlarm reminder = new VAlarm(new Dur(0, -1, 0, 0)); // repeat reminder four (4) more times every fifteen (15) minutes.. reminder.getProperties().add(new Repeat(4)); reminder.getProperties().add(new Duration(new Dur(0, 0, 15, 0))); // display a message.. reminder.getProperties().add(Action.DISPLAY); reminder.getProperties().add(new Description("Progress Meeting")); reminder.getProperties().add(new Trigger(new Dur(0, 0, 15, 0))); Transp transp = new Transp("OPAQUE"); meeting.getProperties().add(transp); Location loc = new Location("Gurgaon"); meeting.getProperties().add(loc); meeting.getAlarms().add(reminder); // 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(new Method("REQUEST")); icsCalendar.getProperties().add(new Sequence(0)); icsCalendar.getProperties().add(new Priority(5)); icsCalendar.getProperties().add(new Status("CONFIRMED")); icsCalendar.getProperties().add(new Uid("324")); // Add the event and print icsCalendar.getComponents().add(meeting); String calendarContent = icsCalendar.toString(); calendarPart.addHeader("Content-Class","urn:content-classes:calendarmessage"); calendarPart.setContent(calendarContent, "text/calendar;method=CANCEL");
-
Put above multipart content in message
// Put the multipart in message msg.setContent(multipart);
-
And finally send above Mime message as email
Transport transport = session.getTransport("smtp"); transport.connect(); transport.sendMessage(msg, msg.getAllRecipients()); transport.close();
Follow the references for more detail on creating email session and using java Mail API.
More on ICal4J library
iCal4j is used for modifying existing iCalendar data or creating new iCalendar data from scratch.
-
Parsing an iCalendar file - Support for parsing and building an iCalendar object model is provided by the
CalendarParser
andContentHandler
interfaces. You can provide your own implementations of either of these, or just use the default implementations as provided by theCalendarBuilder
classFileInputStream fin = new FileInputStream("mycalendar.ics"); CalendarBuilder builder = new CalendarBuilder(); Calendar calendar = builder.build(fin);
-
Creating a new Calendar - Creating a new calendar is quite straight-forward, in that all you need to remember is that a Calendar contains a list of Properties and Components. A calendar must contain certain standard properties and at least one component to be valid. You can verify that a calendar is valid via the method
Calendar.validate()
. AlliCal4j
objects also overrideObject.toString()
, so you can verify the resulting calendar data via this mechanism.Calendar calendar = new Calendar(); calendar.getProperties().add(new ProdId("-//Ben Fortuna//iCal4j 1.0//EN")); calendar.getProperties().add(Version.VERSION_2_0); calendar.getProperties().add(CalScale.GREGORIAN); // Add events, etc..
Output BEGIN:VCALENDAR PRODID:-//Ben Fortuna//iCal4j 1.0//EN VERSION:2.0 CALSCALE:GREGORIAN END:VCALENDAR
-
Creating an Event - One of the more commonly used components is a
VEvent
. To create a VEvent you can either set the date value and properties manually or you can make use of the convenience constructors to initialise standard values.java.util.Calendar cal = java.util.Calendar.getInstance(); cal.set(java.util.Calendar.MONTH, java.util.Calendar.DECEMBER); cal.set(java.util.Calendar.DAY_OF_MONTH, 25); VEvent christmas = new VEvent(new Date(cal.getTime()), "Christmas Day"); // initialise as an all-day event.. christmas.getProperties().getProperty(Property.DTSTART).getParameters().add(Value.DATE);
Output: BEGIN:VEVENT DTSTAMP:20050222T044240Z DTSTART;VALUE=DATE:20051225 SUMMARY:Christmas Day END:VEVENT
-
Saving an iCalendar File - When saving an
iCalendar
fileiCal4j
will automatically validate your calendar object model to ensure it complies with theRFC2445
specification. If you would prefer not to validate your calendar data you can disable the validation by callingCalendarOutputter.setValidating(false)
.FileOutputStream fout = new FileOutputStream("mycalendar.ics"); CalendarOutputter outputter = new CalendarOutputter(); outputter.output(calendar, fout);
References
- http://en.wikipedia.org/wiki/ICalendar
- http://en.wikipedia.org/wiki/VCal
- http://www.imc.org/pdi/vcal-10.txt
- http://java.sun.com/developer/onlineTraining/JavaMail/contents.html
- http://wiki.modularity.net.au/ical4j/index.php?title=Main_Page