| // Copyright 2007 The Android Open Source Project |
| |
| package com.google.wireless.gdata.calendar.serializer.xml; |
| |
| import com.google.wireless.gdata.calendar.data.EventEntry; |
| import com.google.wireless.gdata.calendar.data.When; |
| import com.google.wireless.gdata.calendar.data.Reminder; |
| import com.google.wireless.gdata.calendar.data.Who; |
| import com.google.wireless.gdata.data.StringUtils; |
| import com.google.wireless.gdata.parser.xml.XmlGDataParser; |
| import com.google.wireless.gdata.parser.xml.XmlParserFactory; |
| import com.google.wireless.gdata.parser.ParseException; |
| import com.google.wireless.gdata.serializer.xml.XmlEntryGDataSerializer; |
| |
| import org.xmlpull.v1.XmlSerializer; |
| |
| import java.io.IOException; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| |
| |
| /** |
| * Serializes Google Calendar event entries into the Atom XML format. |
| */ |
| // TODO: move all strings into constants. share with parser? |
| public class XmlEventEntryGDataSerializer extends XmlEntryGDataSerializer { |
| |
| public static final String NAMESPACE_GCAL = "gCal"; |
| public static final String NAMESPACE_GCAL_URI = |
| "http://schemas.google.com/gCal/2005"; |
| |
| public XmlEventEntryGDataSerializer(XmlParserFactory factory, |
| EventEntry entry) { |
| super(factory, entry); |
| } |
| |
| protected EventEntry getEventEntry() { |
| return (EventEntry) getEntry(); |
| } |
| |
| protected void declareExtraEntryNamespaces(XmlSerializer serializer) |
| throws IOException { |
| serializer.setPrefix(NAMESPACE_GCAL, NAMESPACE_GCAL_URI); |
| } |
| |
| /* (non-Javadoc) |
| * @see XmlEntryGDataSerializer#serializeExtraEntryContents |
| */ |
| protected void serializeExtraEntryContents(XmlSerializer serializer, |
| int format) |
| throws IOException, ParseException { |
| EventEntry entry = getEventEntry(); |
| |
| serializeEventStatus(serializer, entry.getStatus()); |
| serializeTransparency(serializer, entry.getTransparency()); |
| serializeVisibility(serializer, entry.getVisibility()); |
| Enumeration attendees = entry.getAttendees().elements(); |
| while (attendees.hasMoreElements()) { |
| Who attendee = (Who) attendees.nextElement(); |
| serializeWho(serializer, entry, attendee); |
| } |
| |
| serializeRecurrence(serializer, entry.getRecurrence()); |
| // either serialize reminders directly under the entry, or serialize |
| // whens (with reminders within the whens) -- should be just one. |
| if (entry.getRecurrence() != null) { |
| if (entry.getReminders() != null) { |
| Enumeration reminders = entry.getReminders().elements(); |
| while (reminders.hasMoreElements()) { |
| Reminder reminder = (Reminder) reminders.nextElement(); |
| serializeReminder(serializer, reminder); |
| } |
| } |
| } else { |
| Enumeration whens = entry.getWhens().elements(); |
| while (whens.hasMoreElements()) { |
| When when = (When) whens.nextElement(); |
| serializeWhen(serializer, entry, when); |
| } |
| } |
| serializeOriginalEvent(serializer, |
| entry.getOriginalEventId(), |
| entry.getOriginalEventStartTime()); |
| serializeWhere(serializer, entry.getWhere()); |
| |
| serializeCommentsUri(serializer, entry.getCommentsUri()); |
| |
| Hashtable extendedProperties = entry.getExtendedProperties(); |
| if (extendedProperties != null) { |
| Enumeration propertyNames = extendedProperties.keys(); |
| while (propertyNames.hasMoreElements()) { |
| String propertyName = (String) propertyNames.nextElement(); |
| String propertyValue = (String) extendedProperties.get(propertyName); |
| serializeExtendedProperty(serializer, propertyName, propertyValue); |
| } |
| } |
| } |
| |
| private static void serializeEventStatus(XmlSerializer serializer, |
| byte status) |
| throws IOException { |
| |
| String statusString; |
| |
| switch (status) { |
| case EventEntry.STATUS_TENTATIVE: |
| statusString = "http://schemas.google.com/g/2005#event.tentative"; |
| break; |
| case EventEntry.STATUS_CANCELED: |
| statusString = "http://schemas.google.com/g/2005#event.canceled"; |
| break; |
| case EventEntry.STATUS_CONFIRMED: |
| statusString = "http://schemas.google.com/g/2005#event.confirmed"; |
| break; |
| default: |
| // should not happen |
| // TODO: log this |
| statusString = "http://schemas.google.com/g/2005#event.tentative"; |
| } |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "eventStatus"); |
| serializer.attribute(null /* ns */, "value", statusString); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "eventStatus"); |
| } |
| |
| private static void serializeRecurrence(XmlSerializer serializer, |
| String recurrence) |
| throws IOException { |
| if (StringUtils.isEmpty(recurrence)) { |
| return; |
| } |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "recurrence"); |
| serializer.text(recurrence); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "recurrence"); |
| } |
| |
| private static void serializeTransparency(XmlSerializer serializer, |
| byte transparency) |
| throws IOException { |
| |
| String transparencyString; |
| |
| switch (transparency) { |
| case EventEntry.TRANSPARENCY_OPAQUE: |
| transparencyString = |
| "http://schemas.google.com/g/2005#event.opaque"; |
| break; |
| case EventEntry.TRANSPARENCY_TRANSPARENT: |
| transparencyString = |
| "http://schemas.google.com/g/2005#event.transparent"; |
| break; |
| default: |
| // should not happen |
| // TODO: log this |
| transparencyString = |
| "http://schemas.google.com/g/2005#event.transparent"; |
| } |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "transparency"); |
| serializer.attribute(null /* ns */, "value", transparencyString); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "transparency"); |
| } |
| |
| |
| private static void serializeVisibility(XmlSerializer serializer, |
| byte visibility) |
| throws IOException { |
| |
| String visibilityString; |
| |
| switch (visibility) { |
| case EventEntry.VISIBILITY_DEFAULT: |
| visibilityString = "http://schemas.google.com/g/2005#event.default"; |
| break; |
| case EventEntry.VISIBILITY_CONFIDENTIAL: |
| visibilityString = |
| "http://schemas.google.com/g/2005#event.confidential"; |
| break; |
| case EventEntry.VISIBILITY_PRIVATE: |
| visibilityString = "http://schemas.google.com/g/2005#event.private"; |
| break; |
| case EventEntry.VISIBILITY_PUBLIC: |
| visibilityString = "http://schemas.google.com/g/2005#event.public"; |
| break; |
| default: |
| // should not happen |
| // TODO: log this |
| visibilityString = "http://schemas.google.com/g/2005#event.default"; |
| } |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "visibility"); |
| serializer.attribute(null /* ns */, "value", visibilityString); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "visibility"); |
| } |
| |
| private static void serializeWho(XmlSerializer serializer, |
| EventEntry entry, |
| Who who) |
| throws IOException, ParseException { |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "who"); |
| String email = who.getEmail(); |
| if (!StringUtils.isEmpty(email)) { |
| serializer.attribute(null /* ns */, "email", email); |
| } |
| |
| String value = who.getValue(); |
| if (!StringUtils.isEmpty(value)) { |
| serializer.attribute(null /* ns */, "valueString", value); |
| } |
| |
| String rel = null; |
| switch (who.getRelationship()) { |
| case Who.RELATIONSHIP_NONE: |
| break; |
| case Who.RELATIONSHIP_ATTENDEE: |
| rel = "http://schemas.google.com/g/2005#event.attendee"; |
| break; |
| case Who.RELATIONSHIP_ORGANIZER: |
| rel = "http://schemas.google.com/g/2005#event.organizer"; |
| break; |
| case Who.RELATIONSHIP_PERFORMER: |
| rel = "http://schemas.google.com/g/2005#event.performer"; |
| break; |
| case Who.RELATIONSHIP_SPEAKER: |
| rel = "http://schemas.google.com/g/2005#event.speaker"; |
| break; |
| default: |
| throw new ParseException("Unexpected rel: " + who.getRelationship()); |
| } |
| if (!StringUtils.isEmpty(rel)) { |
| serializer.attribute(null /* ns */, "rel", rel); |
| } |
| |
| String status = null; |
| switch (who.getStatus()) { |
| case Who.STATUS_NONE: |
| break; |
| case Who.STATUS_ACCEPTED: |
| status = "http://schemas.google.com/g/2005#event.accepted"; |
| break; |
| case Who.STATUS_DECLINED: |
| status = "http://schemas.google.com/g/2005#event.declined"; |
| break; |
| case Who.STATUS_INVITED: |
| status = "http://schemas.google.com/g/2005#event.invited"; |
| break; |
| case Who.STATUS_TENTATIVE: |
| status = "http://schemas.google.com/g/2005#event.tentative"; |
| break; |
| default: |
| throw new ParseException("Unexpected status: " + who.getStatus()); |
| } |
| if (!StringUtils.isEmpty(status)) { |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, |
| "attendeeStatus"); |
| serializer.attribute(null /* ns */, "value", status); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, |
| "attendeeStatus"); |
| } |
| |
| String type = null; |
| switch (who.getType()) { |
| case Who.TYPE_NONE: |
| break; |
| case Who.TYPE_REQUIRED: |
| type = "http://schemas.google.com/g/2005#event.required"; |
| break; |
| case Who.TYPE_OPTIONAL: |
| type = "http://schemas.google.com/g/2005#event.optional"; |
| break; |
| default: |
| throw new ParseException("Unexpected type: " + who.getType()); |
| } |
| if (!StringUtils.isEmpty(type)) { |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, |
| "attendeeType"); |
| serializer.attribute(null /* ns */, "value", type); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "attendeeType"); |
| } |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "who"); |
| } |
| |
| private static void serializeWhen(XmlSerializer serializer, |
| EventEntry entry, |
| When when) |
| throws IOException { |
| // TODO: throw exn if startTime is empty but endTime is not? |
| String startTime = when.getStartTime(); |
| String endTime = when.getEndTime(); |
| if (StringUtils.isEmpty(when.getStartTime())) { |
| return; |
| } |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "when"); |
| serializer.attribute(null /* ns */, "startTime", startTime); |
| if (!StringUtils.isEmpty(endTime)) { |
| serializer.attribute(null /* ns */, "endTime", endTime); |
| } |
| if (entry.getReminders() != null) { |
| Enumeration reminders = entry.getReminders().elements(); |
| while (reminders.hasMoreElements()) { |
| Reminder reminder = (Reminder) reminders.nextElement(); |
| serializeReminder(serializer, reminder); |
| } |
| } |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "when"); |
| } |
| |
| private static void serializeReminder(XmlSerializer serializer, |
| Reminder reminder) |
| throws IOException { |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "reminder"); |
| byte method = reminder.getMethod(); |
| String methodStr = null; |
| switch (method) { |
| case Reminder.METHOD_ALERT: |
| methodStr = "alert"; |
| break; |
| case Reminder.METHOD_EMAIL: |
| methodStr = "email"; |
| break; |
| case Reminder.METHOD_SMS: |
| methodStr = "sms"; |
| break; |
| } |
| if (methodStr != null) { |
| serializer.attribute(null /* ns */, "method", methodStr); |
| } |
| |
| int minutes = reminder.getMinutes(); |
| if (minutes != Reminder.MINUTES_DEFAULT) { |
| serializer.attribute(null /* ns */, "minutes", |
| Integer.toString(minutes)); |
| } |
| |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "reminder"); |
| } |
| |
| private static void serializeOriginalEvent(XmlSerializer serializer, |
| String originalEventId, |
| String originalEventTime) |
| throws IOException { |
| if (StringUtils.isEmpty(originalEventId) || |
| StringUtils.isEmpty(originalEventTime)) { |
| return; |
| } |
| |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "originalEvent"); |
| int index = originalEventId.lastIndexOf("/"); |
| if (index != -1) { |
| String id = originalEventId.substring(index + 1); |
| if (!StringUtils.isEmpty(id)) { |
| serializer.attribute(null /* ns */, "id", id); |
| } |
| } |
| serializer.attribute(null /* ns */, "href", originalEventId); |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "when"); |
| serializer.attribute(null /* ns */, "startTime", originalEventTime); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "when"); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "originalEvent"); |
| } |
| |
| |
| private static void serializeWhere(XmlSerializer serializer, |
| String where) |
| throws IOException { |
| if (StringUtils.isEmpty(where)) { |
| return; |
| } |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "where"); |
| serializer.attribute(null /* ns */, "valueString", where); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "where"); |
| } |
| |
| private static void serializeCommentsUri(XmlSerializer serializer, |
| String commentsUri) |
| throws IOException { |
| if (commentsUri == null) { |
| return; |
| } |
| |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "feedLink"); |
| serializer.attribute(null /* ns */, "href", commentsUri); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "feedLink"); |
| } |
| |
| private static void serializeExtendedProperty(XmlSerializer serializer, |
| String name, |
| String value) |
| throws IOException { |
| serializer.startTag(XmlGDataParser.NAMESPACE_GD_URI, "extendedProperty"); |
| serializer.attribute(null /* ns */, "name", name); |
| serializer.attribute(null /* ns */, "value", value); |
| serializer.endTag(XmlGDataParser.NAMESPACE_GD_URI, "extendedProperty"); |
| } |
| } |