Skip to content
Snippets Groups Projects
Commit 12962b58 authored by srosse's avatar srosse
Browse files

OO-1934: enhance all calendars for Outlook compatibility, add TTL property

parent c84c3a92
No related branches found
No related tags found
No related merge requests found
......@@ -56,12 +56,12 @@ import org.olat.core.util.StringHelper;
import org.olat.core.util.i18n.I18nManager;
import net.fortuna.ical4j.data.CalendarBuilder;
import net.fortuna.ical4j.data.CalendarOutputter;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.Component;
import net.fortuna.ical4j.model.ComponentList;
import net.fortuna.ical4j.model.Parameter;
import net.fortuna.ical4j.model.Property;
import net.fortuna.ical4j.model.PropertyList;
import net.fortuna.ical4j.model.ValidationException;
import net.fortuna.ical4j.model.component.VEvent;
......@@ -83,13 +83,15 @@ import net.fortuna.ical4j.util.Strings;
* Initial Date: June 1, 2008
*
* @author Udit Sajjanhar
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class ICalServlet extends HttpServlet {
private static final long serialVersionUID = -155266285395912535L;
private static final OLog log = Tracing.createLoggerFor(ICalServlet.class);
private final int cacheAge = 60 * 60 * 12;
private static final int TTL_HOURS = 6;
private static final int cacheAge = 60 * 60 * TTL_HOURS;//6 Hours
private static final ConcurrentMap<String,VTimeZone> outlookVTimeZones = new ConcurrentHashMap<>();
/** collection of iCal feed prefixs **/
......@@ -226,9 +228,8 @@ public class ICalServlet extends HttpServlet {
} else {
// read and return the calendar file
Calendar calendar = calendarManager.readCalendar(calendarType, calendarID);
updateUrlProperties(calendar);
DBFactory.getInstance().commitAndCloseSession();
new CalendarOutputter(false).output(calendar, response.getOutputStream());
outputCalendar(calendar, request, response);
}
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUrl);
......@@ -241,6 +242,59 @@ public class ICalServlet extends HttpServlet {
httpResponse.setHeader("Cache-Control", "max-age="+ cacheAge);
}
private void outputCalendar(Calendar calendar, HttpServletRequest request, HttpServletResponse response)
throws ValidationException, IOException {
boolean outlook = isOutlook(request);
updateUrlProperties(calendar);
Writer out = response.getWriter();
out.write(Calendar.BEGIN);
out.write(':');
out.write(Calendar.VCALENDAR);
out.write(Strings.LINE_SEPARATOR);
out.write(Version.VERSION_2_0.toString());
boolean calScale = false;
for (Iterator<?> propIter = calendar.getProperties().iterator(); propIter.hasNext();) {
Object pobject = propIter.next();
if(pobject instanceof Property) {
Property property = (Property)pobject;
if(Version.VERSION.equals(property.getName())) {
//we force version 2.0
} else if(Version.CALSCALE.equals(property.getName())) {
out.write(property.toString());
calScale = true;
} else {
out.write(property.toString());
}
}
}
if(!calScale) {
out.write(CalScale.GREGORIAN.toString());
}
outputTTL(out);
Set<String> timezoneIds = new HashSet<>();
outputCalendarComponents(calendar, out, outlook, timezoneIds);
if(outlook) {
outputTimeZoneForOutlook(timezoneIds, out);
}
out.write(Calendar.END);
out.write(':');
out.write(Calendar.VCALENDAR);
}
/**
* Collect all the calendars, update the URL properties and the UUID.
*
* @param identity
* @param request
* @param response
* @throws IOException
*/
private void generateAggregatedCalendar(Identity identity, HttpServletRequest request, HttpServletResponse response) throws IOException {
PersonalCalendarManager homeCalendarManager = CoreSpringFactory.getImpl(PersonalCalendarManager.class);
if(identity == null) {
......@@ -257,6 +311,8 @@ public class ICalServlet extends HttpServlet {
out.write(Strings.LINE_SEPARATOR);
out.write(Version.VERSION_2_0.toString());
out.write(CalScale.GREGORIAN.toString());
outputTTL(out);
Set<String> timezoneIds = new HashSet<>();
int numOfFiles = iCalFiles.size();
......@@ -281,6 +337,22 @@ public class ICalServlet extends HttpServlet {
return false;
}
/**
* Append TTL:<br>
* @see http://stackoverflow.com/questions/17152251/specifying-name-description-and-refresh-interval-in-ical-ics-format
* @see http://tools.ietf.org/html/draft-daboo-icalendar-extensions-06
*
* @param out
* @throws IOException
*/
private void outputTTL(Writer out)
throws IOException {
out.write("X-PUBLISHED-TTL:PT" + TTL_HOURS + "H");
out.write(Strings.LINE_SEPARATOR);
out.write("REFRESH-INTERVAL;VALUE=DURATION:PT" + TTL_HOURS + "H");
out.write(Strings.LINE_SEPARATOR);
}
private void outputTimeZoneForOutlook(Set<String> timezoneIds, Writer out) {
for(String timezoneId:timezoneIds) {
if(StringHelper.containsNonWhitespace(timezoneId)) {
......@@ -306,6 +378,15 @@ public class ICalServlet extends HttpServlet {
String prefix = fileInfos.getType() + "-" + fileInfos.getCalendarId() + "-";
updateUUID(calendar, prefix);
outputCalendarComponents(calendar, out, outlook, timezoneIds);
} catch (IOException | OLATRuntimeException e) {
log.error("", e);
}
}
private void outputCalendarComponents(Calendar calendar, Writer out, boolean outlook, Set<String> timezoneIds)
throws IOException {
try {
ComponentList events = calendar.getComponents();
for (final Iterator<?> i = events.iterator(); i.hasNext();) {
Object comp = i.next();
......
......@@ -244,9 +244,10 @@ public class ICalFileCalendarManager implements CalendarManager, InitializingBea
return cal;
}
/**
* Internal read calendar file from filesystem
*/
/**
* Internal read calendar file from filesystem. It doesn't
* use the cache and return a not shared calendar.
*/
@Override
public Calendar readCalendar(String type, String calendarID) {
if(log.isDebug()) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment