/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2008 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
package com.funambol.common.pim.icalendar;
import java.io.OutputStream;
import javax.microedition.pim.PIMItem;
import javax.microedition.pim.PIMException;
import javax.microedition.pim.Event;
import javax.microedition.pim.ToDo;
import com.funambol.util.Log;
import com.funambol.common.pim.PimUtils;
import com.funambol.common.pim.vcalendar.CalendarUtils;
import com.funambol.common.pim.vcalendar.BasicVCalendarFormatter;
/**
* This class implements an iCalendar formatter for JSR75 Event or ToDo objects.
* This class should be extended if you want to format extended fields, not
* directly included in the basic JSR75 implementation.
*
* In particular the following methods should be implemented:
*
* <li>getTZID(PIMItem pimItem);</li>
* <li>getTZOffset(PIMItem pimItem);</li>
*
* <li>getTaskAlarmInterval(PIMItem pimItem);</li>
* <li>isAllDay(PIMItem pimItem);</li>
* <li>formatAttendees(PIMItem pimItem, OutputStream os);</li>
*
*/
public class ICalendarFormatter extends BasicVCalendarFormatter {
private final String LOG_TAG = "ICalendarFormatter";
protected String getVersion() {
return ICalendar.VERSION;
}
public ICalendarFormatter(String defaultCharset) {
super(defaultCharset);
}
/**
* Format the VALARM component
* @param pimItem the PIMItem to format
* @param os the output stream
* @throws javax.microedition.pim.PIMException
*/
protected void formatAlarm(PIMItem pimItem, OutputStream os, boolean allFields) throws PIMException {
if (Log.isLoggable(Log.TRACE)) {
Log.trace(LOG_TAG, "formatAlarm");
}
int alarmInterval = -1;
if(pimItem instanceof Event) {
if (isSupported(pimItem, Event.ALARM) && pimItem.countValues(Event.ALARM) > 0) {
alarmInterval = pimItem.getInt(Event.ALARM, 0);
}
} else if(pimItem instanceof ToDo) {
alarmInterval = getTaskAlarmInterval(pimItem);
}
if (alarmInterval >= 0) {
if(alarm.setAlarmInterval(alarmInterval*1000)) {
// The VALARM component has to be formatted
PimUtils.println(os, ICalendar.BEGIN_VALARM);
formatTrigger(pimItem, alarmInterval, os, allFields);
// Format AUDIO ACTION type as default
PimUtils.println(os, ICalendar.ACTION + ":" + ICalendar.ACTION_AUDIO);
PimUtils.println(os, ICalendar.END_VALARM);
}
}
}
protected void formatTrigger(PIMItem pimItem, int alarmInterval, OutputStream os,
boolean allFields) throws PIMException {
if (Log.isLoggable(Log.TRACE)) {
Log.trace(LOG_TAG, "formatTrigger");
}
PimUtils.println(os, ICalendar.TRIGGER + ";" +
ICalendar.VALUE + "=" + ICalendar.DATE_TIME_VALUE + ":" +
alarm.getTriggerAbsoluteTime());
}
/**
* Format the VTIMEZONE component
* @param pimItem the PIMItem to format
* @param os the output stream
* @throws javax.microedition.pim.PIMException
*/
protected void formatTimezone(PIMItem pimItem, OutputStream os) throws PIMException {
if (Log.isLoggable(Log.TRACE)) {
Log.trace(LOG_TAG, "formatTimezone");
}
String tzid = getTZID(pimItem);
if(tzid != null) {
// The VTIMEZONE component has to be formatted
PimUtils.println(os, ICalendar.BEGIN_VTIMEZONE);
PimUtils.println(os, ICalendar.TZID + ":" + tzid);
PimUtils.println(os, ICalendar.END_VTIMEZONE);
}
}
protected void formatDateTimeField(OutputStream os, PIMItem pimItem, int pimField,
String iCalField, boolean checkAllDay, boolean checkTimezone,
boolean allFields) throws PIMException {
if (Log.isLoggable(Log.TRACE)) {
Log.trace(LOG_TAG, "formatDateTime");
}
if(isSupported(pimItem, pimField)) {
if(pimItem.countValues(pimField) > 0) {
long millis = pimItem.getDate(pimField, 0);
boolean allday = checkAllDay ? isAllDay(pimItem) : false;
if(allday) {
iCalField += ";" + ICalendar.VALUE + "=" + ICalendar.DATE_VALUE;
if((pimItem instanceof Event) && pimField == Event.END) {
millis = fixEndDate(millis);
}
}
String tzid = "UTC";
if(checkTimezone && !allday) {
tzid = getTZID(pimItem);
if(tzid != null) {
// Add the TZID param
iCalField += ";" + ICalendar.TZID + "=" + tzid;
long offset = getTZOffset(pimItem);
millis += offset;
}
}
String dateValue = CalendarUtils.formatDateTime(millis, allday, tzid);
PimUtils.println(os, iCalField + ":" + dateValue);
if((pimItem instanceof Event) && pimField == Event.START) {
alarm.setCalStartAbsoluteTime(millis);
}
} else if(allFields) {
// Format empty property
PimUtils.println(os, iCalField + ":");
}
}
}
protected String getTZID(PIMItem pimItem) { return null; }
protected long getTZOffset(PIMItem pimItem) { return 0; }
}