Wer mit Liferay (genauer: Mit einem Portlet) eine iCal-Datei ausliefern will, benötigt zuerst mal iCal4j. Ich brauchte die JARs backport-util-concurrent-3.1 und ical4j-1.0.3, aber vermutlich benötigt man auch noch commons-lang-2.6 und commons-logging-1.1.1, davon habe ich (ältere) bereits durch/für Liferay im Projekt. Die anderen brauchte ich nicht.
Anmerkung: Außerdem habe ich eine leere Datei namens ical4j.properties direkt in src angelegt, um eine Warnung zu unterdrücken.
Um eine Ressource abzurufen, nutze ich die ResourceURL von Liferay, in meinem Fall plus einer Event-ID:
1 2 3 4 |
ResourceURL calendarURL = myRenderResponse.createResourceURL(); calendarURL.setParameter("eventID", myEventID); View myView = new VelocityView("myVelocityView"); myView.put("calendarURL", calendarURL); |
Ein Aufruf der URL landet in der serveResource() meines Portlets, und mündet in der Erzeugung des Files:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// TODO day-long dummy event! java.util.Calendar date = java.util.Calendar.getInstance(); date.set(java.util.Calendar.MONTH, java.util.Calendar.DECEMBER); date.set(java.util.Calendar.DAY_OF_MONTH, 25); VEvent christmas = new VEvent(new Date(date.getTime()), "Christmas Day"); // siehe unten! //christmas.getProperties().getProperty(Property.DTSTART).getParameters().add(Value.DATE); // create ical-event from VEvent, plus necessary props net.fortuna.ical4j.model.Calendar calendar = new net.fortuna.ical4j.model.Calendar(); calendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN")); calendar.getProperties().add(Version.VERSION_2_0); //calendar.getProperties().add(CalScale.GREGORIAN); calendar.getComponents().add(christmas); // actual output: CalendarOutputter outputter = new CalendarOutputter(); <del>// TODO else: Error "Parameter [VALUE] must only be specified once":</del> <del>outputter.setValidating(false);</del> outputter.output(calendar, response.getPortletOutputStream()); // set filename to be dowloaded: response.addProperty(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=event.ics"); // otherwise file will be interpreted as HTML-document: response.setContentType("text/calendar"); |
ACHTUNG: Wer einen Termin mit Startzeit (und Endzeit) erzeugen will, muss dem VEvent ein (zwei) Objekte vom Typ DateTime statt Date übergeben!
Quellen: Basis, verschiedene iCal4j-Fehlermeldungen, Filename setzen, ICS Mime type, Unterschied Date/DateTime 😉
Wer rausfindet, warum mir beim Validieren ein “Parameter [VALUE] must only be specified once” geworfen wird, bekommt ein Bier! EDIT: Es lag an der jetzt auskommentierten Zeile! Prost!