macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Transforming iCal Calendars with Java
Pages: 1, 2, 3

Saving Back to Disk

Most of the work is done. We need to save the calendar back to disk, which amounts to reversing the process you followed when reading from disk. There is one more subtle point. Look back at the iCal picture from the first section. Notice this line.



X-WR-CALNAME;VALUE=TEXT:example

The calendar's name is stored as part of the text. Since we will be saving the calendar under a new name, we also need to change this value in the text. Once again we use reg ex to locate the string to be changed and supply the new value in the changeCalendarName() method. Here's the code for saving the calendar back to disk.

package ical;

import java.io.File;
import java.io.IOException;
import java.io.FileWriter;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class ICalendarFromString {

  private static final String CALENDAR_HOME = "Calendar/";
  private static FileWriter fileWriter;

  public static void saveStringAsCalendarFile(String contents,
                                              String destinationCalendar)
                         throws CalendarNotSavedException {
    createCalendarFileWriter(destinationCalendar);
    contents = changeCalendarName(contents, destinationCalendar);
    writeCalendarToFile(contents);
  }

  private static void createCalendarFileWriter(String calendarName)
                            throws CalendarNotSavedException {
    File outputFile = new File(CALENDAR_HOME + calendarName + ".ics");
    try {
      fileWriter = new FileWriter(outputFile);
    } catch (IOException e) {
      throw new CalendarNotSavedException(e.getMessage(), e.getCause());
    }
  }

  private static String changeCalendarName(String contents, String destinationName) {
    Pattern calendarNamePattern = Pattern.compile("(.*?CALNAME.*?:)(.*?)\n");
    Matcher calendarNameMatcher = calendarNamePattern.matcher(contents);
    return calendarNameMatcher.replaceAll("$1" + destinationName + "\n");
  }

  private static void writeCalendarToFile(String contents) throws CalendarNotSavedException {
    try {
      fileWriter.write(contents);
      fileWriter.close();
    } catch (IOException e) {
      throw new CalendarNotSavedException(e.getMessage(), e.getCause());
    }

  }
}

Here we have used a CalendarNotSavedException that is exactly the same as a CalendarNotFoundException with the obvious name changes.

Putting It All Back

All you need is a entry point to the program. This Main just contains a main() that reads the example.ics calendar from disk, changes it, and stores it as ipod.ics.

package ical;

public class Main {
  public static void main(String[] args) {
    try {
      String contents = ICalendarToString.getCalendarAsString("example");
      contents = ICalendarTodoConverter.convert(contents);
      ICalendarFromString.saveStringAsCalendarFile(contents, "ipod");
    } catch (CalendarNotFoundException e) {
      System.out.println("Could not find Calendar example.ics: " + e.getMessage());
    } catch (CalendarNotSavedException e) {
      System.out.println("Could not save transformed calendar: " + e.getMessage());
    }
  }
}

The resulting file ipod.ics looks like this:

Screen shot.

It loads beautifully into iCal and synchs perfectly with my iPod. Now I can view my todos. There are many ways to extend this application. The main point is that with ICalendarToString and ICalendarFromString, you have the framework to convert a calendar into a form in which you can transform it any way you want. I should know better than to make promises about future articles, but another technique is to build a calendar object model and be able to manipulate events and todos without thinking at all about their persistence.

Daniel H. Steinberg is the editor for the new series of Mac Developer titles for the Pragmatic Programmers. He writes feature articles for Apple's ADC web site and is a regular contributor to Mac Devcenter. He has presented at Apple's Worldwide Developer Conference, MacWorld, MacHack and other Mac developer conferences.


Read more Java Programming on the Mac columns.

Return to the Mac DevCenter.