Java tutorial
/** * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.schedassist.impl.caldav; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import javax.annotation.Resource; import net.fortuna.ical4j.model.Calendar; import net.fortuna.ical4j.model.component.VEvent; import net.fortuna.ical4j.model.property.ProdId; import org.apache.commons.lang.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; import org.apache.http.entity.StringEntity; import org.jasig.schedassist.model.ICalendarAccount; import org.jasig.schedassist.model.IEventUtils; import org.springframework.beans.factory.annotation.Autowired; /** * Class to encapsulate generation of the dialect between the scheduling assistant * and the CalDAV server. * * @author Nicholas Blair, nblair@doit.wisc.edu * @version $Id: DefaultCaldavDialectImpl.java 51 2011-05-06 14:35:33Z nblair $ */ public class DefaultCaldavDialectImpl implements CaldavDialect { private static final String UTF_8 = "UTF-8"; private static final String TEXT_CALENDAR = "text/calendar"; /** * Date format expected by CalDAV servers. */ protected static final String DATE_FORMAT = "yyyyMMdd'T'HHmmss'Z'"; /** * {@link ProdId} attached to {@link Calendar}s sent to the CalDAV server by the Scheduling Assistant. */ protected static final ProdId PROD_ID = new ProdId("-//jasig.org//Jasig Scheduling Assistant 1.0//EN"); private URI caldavHost; private String accountHomePrefix = "/ucaldav/user/"; private String accountHomeSuffix = "/calendar/"; private IEventUtils eventUtils; private String userPathSegmentAttributeName = "uid"; private Log log = LogFactory.getLog(this.getClass()); /** * @return the accountHomePrefix */ public String getAccountHomePrefix() { return accountHomePrefix; } /** * @param accountHomePrefix the accountHomePrefix to set */ public void setAccountHomePrefix(String accountHomePrefix) { this.accountHomePrefix = accountHomePrefix; } /** * @return the accountHomeSuffix */ public String getAccountHomeSuffix() { return accountHomeSuffix; } /** * @param accountHomeSuffix the accountHomeSuffix to set */ public void setAccountHomeSuffix(String accountHomeSuffix) { this.accountHomeSuffix = accountHomeSuffix; } /** * * @return the userPathSegmentAttributeName */ public String getUserPathSegmentAttributeName() { return userPathSegmentAttributeName; } /** * @param userPathSegmentAttributeName */ public void setUserPathSegmentAttributeName(String userPathSegmentAttributeName) { this.userPathSegmentAttributeName = userPathSegmentAttributeName; } /* (non-Javadoc) * @see org.jasig.schedassist.impl.caldav.CaldavDialect#getCaldavHost() */ @Override public URI getCaldavHost() { return this.caldavHost; } /** * Annotated with {@link Resource} to allow injection by name. * * @param caldavHost the caldavHost to set */ @Resource public void setCaldavHost(URI caldavHost) { this.caldavHost = caldavHost; } /** * @param eventUtils the eventUtils to set */ @Autowired public void setEventUtils(IEventUtils eventUtils) { this.eventUtils = eventUtils; } /* * (non-Javadoc) * @see org.jasig.schedassist.impl.caldav.CaldavDialect#generateGetCalendarRequestEntity(java.util.Date, java.util.Date) */ public HttpEntity generateGetCalendarRequestEntity(Date startDate, Date endDate) { final String content = generateGetCalendarRequestXML(startDate, endDate); StringEntity requestEntity; try { requestEntity = new StringEntity(content, "text/xml", UTF_8); return requestEntity; } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e); } } /** * Generate the XML that makes up a valid CalDAV calendar-query request body that would * be issued with a REPORT request for Calendar events between the 2 {@link Date} arguments. * * @param startDate * @param endDate * @return calendar-query XML content for REPORT request */ protected String generateGetCalendarRequestXML(Date startDate, Date endDate) { StringBuilder content = new StringBuilder(); content.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); content.append("<C:calendar-query xmlns:D=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">"); content.append(" <D:prop>"); content.append(" <D:getetag/>"); content.append(" <C:calendar-data/>"); content.append(" </D:prop>"); content.append(" <C:filter>"); content.append(" <C:comp-filter name=\"VCALENDAR\">"); content.append(" <C:comp-filter name=\"VEVENT\">"); content.append(" <C:time-range start=\"" + formatDateTime(startDate) + "\" end=\"" + formatDateTime(endDate) + "\"/>"); content.append(" </C:comp-filter>"); content.append(" </C:comp-filter>"); content.append(" </C:filter>"); content.append("</C:calendar-query>"); String result = content.toString(); log.debug(result); return result; } /* * (non-Javadoc) * @see org.jasig.schedassist.impl.caldav.CaldavDialect#generateCreateAppointmentRequestEntity(net.fortuna.ical4j.model.component.VEvent) */ public HttpEntity generatePutAppointmentRequestEntity(VEvent event) { Calendar wrapped = this.eventUtils.wrapEventInCalendar(event); return generatePutAppointmentRequestEntity(wrapped); } /* (non-Javadoc) * @see org.jasig.schedassist.impl.caldav.CaldavDialect#generatePutAppointmentRequestEntity(net.fortuna.ical4j.model.Calendar) */ @Override public HttpEntity generatePutAppointmentRequestEntity(Calendar calendar) { try { StringEntity requestEntity = new StringEntity(calendar.toString(), TEXT_CALENDAR, UTF_8); return requestEntity; } catch (UnsupportedEncodingException e) { throw new IllegalStateException(e); } } /* * (non-Javadoc) * @see org.jasig.schedassist.impl.caldav.CaldavDialect#calculateCalendarAccountHome(org.jasig.schedassist.model.ICalendarAccount) */ @Override public String getCalendarAccountHome(ICalendarAccount calendarAccount) { Validate.notNull(calendarAccount, "calendarAccount argument must not be null"); final String userPathSegmentAttribute = calendarAccount.getAttributeValue(userPathSegmentAttributeName); Validate.notNull(userPathSegmentAttribute, "userPathSegment attribute (" + userPathSegmentAttributeName + ") in calendarAccount argument must not be null"); StringBuilder uri = new StringBuilder(); uri.append(getCaldavHost().toString()); uri.append(getAccountHomePrefix()); uri.append(userPathSegmentAttribute); uri.append(getAccountHomeSuffix()); return uri.toString(); } /* (non-Javadoc) * @see org.jasig.schedassist.impl.caldav.CaldavDialect#resolveCalendarURI(org.jasig.schedassist.impl.caldav.CalendarWithURI) */ @Override public URI resolveCalendarURI(CalendarWithURI calendar) { Validate.notNull(calendar, "CalendarWithURI argument cannot be null"); StringBuilder result = new StringBuilder(); result.append(this.caldavHost.toString()); result.append(calendar.getUri()); URI uri; try { uri = new URI(result.toString()); return uri; } catch (URISyntaxException e) { log.error("cannot construct uri from " + result.toString(), e); throw new IllegalStateException("cannot construct uri from " + result.toString(), e); } } /** * Convert the date to a String using the format: * <pre> yyyyMMdd'T'HHmmssZ </pre> * * @param date * @return */ protected String formatDateTime(Date date) { SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); df.setTimeZone(TimeZone.getTimeZone("UTC")); return df.format(date); } }