org.jasig.schedassist.impl.caldav.DefaultCaldavDialectImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jasig.schedassist.impl.caldav.DefaultCaldavDialectImpl.java

Source

/**
 * 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);
    }

}