ICAL 101

Ken
2012-01-08
2013-06-05
  • Ken

    Ken - 2012-01-08

    I intend to use ical4j for an online calendar.  I'm using tomcat 6 and mysql and I would like to know the best approach for saving ical4j to a DB.

    I came across this the following for creating a file.  It works fine.  I could store the calendar as a blob in the DB.  Is this the a best practice or should I create fields?

    FileOutputStream fout = new FileOutputStream("mycalendar.ics");
    CalendarOutputter outputter = new CalendarOutputter();
    outputter.output(calendar, fout);
    

    If anyone could point me to a site with good examples, I would certainly appreciate it.

    Your help is appreciated.

     
  • Pascal Robert

    Pascal Robert - 2012-01-08

    You have different options:

    - Install a CalDAV server like CalendarServer or DAViCal (or even Google Calendar) instead of writing your own. Those services already know how to store everything, manage conflicts, etc. And you can use CalDAV clients to update the calendar. You can use ical4j-connector if you need to work with the calendar from a Java application

    - Store the data inside a BLOB or copy it on the file system and make a reference to the file (store the path) in your database if you need too. Me think that storing it on the file system will be faster than getting the data from the blog but of course, it depends. If you will throw out the iCalendar files to HTTP clients, I'm pretty sure that using the file system + the Last-Modified header in the response will make it faster and cacheable.

    - If your iCalendar objects will have a small set of attributes, you can create fields (summary, startTime, etc.) in a database table and generate the iCalendar object when needed.

    It all depends of your needs…

     
  • Ken

    Ken - 2012-01-09

    I appreciated your insight.  This is what I have right now.  It all works.

        private static void saveCalendarToDB(Calendar ical) {
            DB db = new DB();
            Connection conn = null;
            PreparedStatement ps = null;
            try{
                // Convert iCalendar to byte array
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                CalendarOutputter outputter = new CalendarOutputter();
                outputter.output(ical, buffer);
                byte[] byteArray = buffer.toByteArray();
    
                //save byte array to DB
                conn = db.getConn();
                ps = conn.prepareStatement("UPDATE ical4j SET cal4jblob=? WHERE id=1"); //always update the same record
    
                ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
                ps.setBinaryStream(1, bais, byteArray.length);
                
                ps.executeUpdate();
            }
            catch(Exception e){
                e.printStackTrace();
                System.out.println("An error occured updating iCal4J on the database");
            }
            finally{
                db.close(ps);
                db.close(conn);
            }
        }
    

    It's a small website.  I plan on saving and retrieving directly from the database for now.
    Once all the bugs are ironed out I may have have the above method invoke the next method to constantly update a static file (for speed).

        public static void saveCalendarToFile(net.fortuna.ical4j.model.Calendar ical) throws Exception{
            FileOutputStream fout = new FileOutputStream("/home/bubblegum/Desktop/mycalendar.ics");
            CalendarOutputter outputter = new CalendarOutputter();
            outputter.output(ical, fout);
        }
    

    I have included code for other people to benefit from my learning in addition to being scrutinized (I can hold back tears.)  I am concerned about what happens after a few years worth of data.  I'm not sure right now how to handle attachments.  I'm also wondering how to lock down access to the calendar data….  These are just my thoughts I'll probably be confronted with in the near future. 

    Thanks a bunch!!

     
  • Ken

    Ken - 2012-01-09

    This works as well:

    private static Calendar retrieveCalendarFromDB(){
            DB db = new DB();
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            net.fortuna.ical4j.model.Calendar ical = null;
            try{
                conn = db.getConn();
                ps = conn.prepareStatement("SELECT cal4jblob FROM ical4j WHERE id=1");
                rs = ps.executeQuery();
                if (rs.next() ) {
                       // Get as a BLOB
                       Blob aBlob = rs.getBlob(1);
                       byte[] allBytesInBlob = aBlob.getBytes(1, (int) aBlob.length());
                       // Create an instance of ical
                       CalendarBuilder builder = new CalendarBuilder();
                       ByteArrayInputStream bais = new ByteArrayInputStream(allBytesInBlob);
                       ical = builder.build(bais);
                }
            }catch(Exception e){
                e.printStackTrace();
                System.out.println("An error occured retrieving iCal4J from the database");
                ical= new net.fortuna.ical4j.model.Calendar();
            }
            finally{
                db.close(ps);
                db.close(conn);
            }
            return ical;
        }
    
     
  • Ben Fortuna

    Ben Fortuna - 2012-01-11

    Hi Ken,

    Thanks for the examples, happy to know your solution is working for you.

    Potentially we could extend the ical4j-connector to support this type of direct DB persistence (I have already made an attempt at JCR storage, but having difficulty finding time to work on it further). For DB storage we would just need some configuration regarding the table name, fields, etc. Anyway, perhaps this will be a future enhancement.

    regards,
    ben

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks