User:Mollekopf/Drafts/KEP:17
From Kolab Wiki
KEP 17: Kolab XML Format 3.0
| Status | DRAFT |
| Type | design |
| Author | Christian Mollekopf |
| Revision ID | 14081 |
| Created | 2011-12-12 |
| Last Modified | 2013-4-24 |
| Latest Working Copy | KEP-0017.txt |
| Tracker Ticket | N/A |
Abstract
KEP:1[1] defines a new Kolab XML Version 3.0 for the Kolab Format 3.0 specification. This format SHALL be canonical from Kolab Version 3.0 and upward.
This KEP incorporates previous KEPs that have addressed issues in the Kolab Format, most importantly KEP:2[2], KEP:9[3].
Due to reasons outlined in the rationale at the end of this KEP, the Kolab XML format is re-based on the recently released RFC 6321 [4] and RFC 6350 [5] standards. Only where no suitable standards exist does this KEP specify updates on the Kolab Format Version 2.0 definition of these objects.
It is intended to work with international processes wherever possible to ensure that these objects will eventually be addressed through widely adopted standards, as well.
Notation
XML Objects are described using the Relax NG compact syntax[6].
Pattern restriction of single string values are according to [6][7].
General Considerations
Kolab XML is based on XML Version 1.0.
Semantics SHALL be according to the respective RFCs unless specified different by this KEP.
The Kolab Format will consist of a subset of RFC 6321 and RFC 6351 features complemented by application behaviour specifications and additional specifications which are lacking in the RFCs.
That initial subset is defined as the necessary set of fields and semantics required to map the functionality of Kolab Format 2.0 in RFC 6321 / RFC 6351 compliant form plus any additions defined in this KEP.
An implementation of the Kolab XML Format SHALL be able to understand all properties defined in the respective format description and SHALL NOT degrade any property. In any case it SHALL preserve the semantic meaning of the property.
The order of the elements is REQUIRED unless otherwise specified using the Relax NG Format description
The 'X-Kolab-Type' field which is defined for every Kolab XML Object SHALL be used as RFC 2822 [8] message header of the encapsulating email object.
Kolab XML Objects
A Kolab XML Object is a container for the various data types the Kolab Groupware Suite stores.
Currently this includes:
Properties
The following properties apply to all Kolab Objects. The individual datatype definitions of the objects MUST be followed.
Kolab XML Version
value-version = ( #String )
The version number identifies the Kolab XML Format specification which was used to write the file.
The version number MUST be according to #Version number
This property MUST be updated whenever an object is modified.
UID
value-uid = ( #String ) text-uid = element text { #String } uri-uid = element uri { #URI }
A UID uniquely identifying the Kolab XML Object.
The UID SHALL be globally unique.
The global uniqueness of a UID SHOULD be achieved by following the provisions set forth in RFC 4122[9].
The UID MUST NOT be changed after initial creation of the object.
A UID in the uri format (uri-uid), MUST use the URN namespace described in RFC 4122[9].
Implements:
Creation date
value-creation-date = ( #Date-Time )
The date-time timestamp when the object was created.
The date-time MUST be in UTC.
This property MUST NOT be changed after initial creation of the object.
Implements:
Last modification date
value-lastmodified-date = ( #Date-Time )
The date-time timestamp when the object was last modified.
The date-time MUST be in UTC.
This property MUST be updated whenever an object is modified.
Implements:
Product ID
value-productid = ( #String ) property-prodid = element prodid { element text { value-productid } }
An identification of the client who has written out the last version of the object.
The product-id SHOULD uniquely identify the client and the format implementation, including version number, which last modified the object.
This property MUST be updated whenever an object is modified.
This property's primary purpose is debugging.
Implements:
Classification
value-classification = ( "PRIVATE"|"CONFIDENTIAL"|"PUBLIC" )
The classification gives an indication of the (security) classification of the object.
The classification MUST be one of "PRIVATE", "CONFIDENTIAL" and "PUBLIC".
- "PRIVATE": The object contains private information and is meant for the owner of the object only.
- "CONFIDENTIAL": The object contains confidential information and is meant for an authorized group only.
- "PUBLIC": The object doesn't contain any private/confidential information and doesn't have to be handled with extra care.
This property serves mainly the purpose of giving the user an indication how the contained information should be handled.
Client implementations MAY behave differently depending on the classifcation of the object. The implementation SHOULD give the user an indication of the classification so he can act accordingly. If the "Classification" property is absent, the client SHALL behave as if the classification was "PUBLIC".
Implements:
Categories
value-category = ( #String ) property-categories = ( element text { value-category } + )
A simple text tag used to categorize the object.
Categories are plaintext tags which are used group objects into categories.
Categories SHALL be used as plaintext tags only and SHOULD NOT have any encoded structure.
Implements:
Attachment
kolab-property-attach = element attach {
element parameters {
element fmttype { #String },
element x-label { #String } ?,
element encoding { "BASE64" } ?
},
element uri { #URI } |
element binary { #String }
}
xcal-property-attach = element attach {
element parameters {
element fmttype { element text { #String } },
element x-label { element text { #String } } ?,
element encoding { element text { "BASE64" } } ?
},
element uri { #URI } |
element binary { #String }
}
A file attachment.
The attachment MUST either be referenced using the uri element or embedded using the binary element.
- "fmttype": MUST be set to the mimetype of the file.
- "x-label": MAY be used to add a user visible label for the attachment (such as the filename).
- "encoding": MUST be set to "BASE64" for inline encoding. This parameter MUST be set if inline storage using the binary element is used.
The binary content MUST be "Base 64"-encoded according to RFC 4648[10]section-4
Implements:
xCal based objects
element icalendar {
element vcalendar {
element properties {
element prodid { #Product ID },
element version { #xCal Version },
element x-kolab-version { #Kolab XML Version },
},
element components {
element vevent { event } |
element vtodo { todo } |
element vjournal { journal } |
element vfreebusy { freebusy },
recurrence-exception *
}
}
}
All xCal based objects MUST fully comply to RFC 6321[4].
Each Kolab XML Object MUST contain exactly one main todo/event/journal object stored according to RFC 6321[4]. It MAY contain additionally a number of Recurrence exceptions which MUST be of the same type as the main object.
VTimezone MUST NOT be used. Instead timezone identifiers according to #Timezone Identifier MUST be used.
In the following sectopm "incidence" refers to an event, todo or journal entry.
Properties
xCal Version
property-version = element version {
element text { "2.0" }
}
The xCal version number.
Implements:
Related-to
property-relatedto = element related-to {
text-uid
}
Parent relationship of the todo.
This property MUST specify a "Parent" relationship. Other relations MUST NOT be used.
A "Parent" relation SHALL specify the parent todo of this todo.
The value MUST contain the UID of another object which has a parent relationship to this object.
Implements:
Start date
property-dtstart = element dtstart {
element parameters {
xcal-tzid ?
} ?,
xcal-date-or-date-time
}
Start date of the event/todo/journal entry.
"All-Day" Events are indicated by using the date-only format for the dtstart property.
Implements:
End date
property-dtend = element dtend {
element parameters {
xcal-tzid ?
} ?,
xcal-date-or-date-time
}
End date of the event/journal entry.
The value type of this property MUST be the same as the #Start date property, and its value MUST be later in time than the value of the #Start date property. Furthermore, this property MUST be specified as a date with local time if and only if the #Start date property is also specified as a date with local time.
This property MUST NOT be specified if an #Incidence Duration was specified.
Implements:
Incidence Duration
property-duration = element duration {
element duration { #Duration }
}
Duration of the event/journal entry.
This property MUST NOT be specified if an #End date was specified.
Implements:
Due date
property-due = element due {
element parameters {
xcal-tzid ?
} ?,
xcal-date-or-date-time
}
Date until the todo should be completed.
The value type of this property MUST be the same as the #Start date property, and its value MUST be later in time than the value of the #Start date property. Furthermore, this property MUST be specified as a date with local time if and only if the #Start date property is also specified as a date with local time.
Implements:
Transparency
property-transp = element transp {
element text { "OPAQUE" | "TRANSPARENT" }
}
Specifies, if an event is free/busy-relevant.
- "OPAQUE": The event is visible in freebusy time searches.
- "TRANSPARENT": The event is invisible in freebusy time searches.
If not specified this property SHALL default to "OPAQUE". Events with the transparency set to "TRANSPARENT" MUST NOT be used in any free/busy time searches/generation.
Implements:
Sequence
property-seq = element sequence {
element integer { xsd:integer }
}
The sequence number of the object.
This property MUST be increased by one everytime the object is modified.
The initial value of this property SHALL be zero.
This property is used primarily for iTip message handling.
Implements:
Recurrences
The complete set of recurrences MUST be derived using the #Start date, #Recurrence rule, #Recurrence date and #Exception date properties.
If no #Start date is available (i.e. in a todo), the recurrence SHALL be ignored.
The following procedure SHALL be used:
- Derive recurrence set from #Recurrence rule and #Start date
- Add further recurrence dates contained in #Recurrence date
- Remove exceptions from #Exception date
- Apply changes from Recurrence exceptions matching a #Recurrence ID stored in the same Kolab XML Object
Duplicate recurrences (same start-date) MUST be ignored and considered as a single occurence.
The #Start date is part of the complete recurrence set.
Implements:
Recurrence exception
recurrence-exception = (
element vevent { event } |
element vtodo { todo }
)
A recurrence exception overwrites properties of the base object in a specific recurrence of an event/todo.
A recurrence exception can be identified as exception by the presence of the #Recurrence ID property which MUST be specified on recurrence exceptions and MUST NOT be specified on the base object.
A recurrence exception MUST be of the same type as the base object.
A recurrence exception SHALL copy ALL properties of the base event, and adjust as required, and it SHALL NOT be applied on top of the orginial event properties (The exception replaces the complete original event definition for the specific occurrence).
A recurrence exception MUST NOT define a new recurrence rule using any of #Recurrence rule, #Recurrence date, #Exception date
Recurrence exceptions MUST be defined in the same Kolab XML Object as the base object.
The #UID parameter of the recurrence exception MUST match the #UID parameter of the base object.
Recurrence rule
type-weekday = ("SU" | "MO" | "TU" | "WE" | "TH" | "FR" | "SA")
byday-pattern = (xsd:integer?type-weekday)
property-rrule = element rrule {
element recur {
element freq { "SECONDLY" | "MINUTELY" | "HOURLY" | "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY" },
( element until { xcal-date-time } | element count { xsd:positiveInteger })?,
element interval { xsd:positiveInteger }?,
element bysecond { xsd:positiveInteger }*,
element byminute { xsd:positiveInteger }*,
element byhour { xsd:positiveInteger }*,
element byday { byday-pattern }*,
element bymonthday { xsd:integer }*,
element byyearday { xsd:integer }*,
element byweekno { xsd:integer }*,
element bymonth { xsd:positiveInteger }*,
element bysetpos { xsd:integer }*,
element wkst { type-weekday }?
}
}
Description of a recurring incidence.
The recurrence rule SHALL be expanded according to RFC 5545 section-3.8.5.3.
- until: The value type MUST be the same as the #Start date property. If #Start date was specified as date-time in local time without Timezone information the until date-time MUST be specified as local-time. If #Start date was specified as date-time in UTC or local time with Timezone information then the until date-time MUST be specified as UTC date-time.
Implements:
Recurrence date
property-rdate = element rdate {
element parameters {
xcal-tzid ?
} ?,
xcal-date-or-date-time +
}
A list of dates which should be added to the recurrences. An alternative format to the #Recurrence rule
While RFC 5545 section-3.8.5.2 permits the usage of a "PERIOD" type for this property to change the duration of a specific recurrence, this MUST NOT be used. The different duration SHOULD be indicated by specifying a #Recurrence exception instead.
Implements:
Exception date
property-exdate = element exdate {
element parameters {
xcal-tzid ?
}?,
xcal-date-or-date-time +
}
A list of dates to be excluded from the calculated recurrence set.
Recurrences with a start date matching an exception date MUST be excluded from the recurrence set.
Implements:
Recurrence ID
property-recurrence-id = element recurrence-id {
element parameters {
xcal-tzid ?,
element range { element text { "THISANDFUTURE" } }?
}?,
xcal-date-or-date-time
}
A date-time value, matching the #Start date of one specific recurrence to identify it.
The value type MUST be the same as the #Start date property. If #Start date was specified as date-time in local time without Timezone information the until date-time MUST be specified as local-time. If #Start date was specified as date-time in UTC or local time with Timezone information then the until date-time MUST be specified as UTC date-time.
This property MUST NOT be specified on the base object, but only on a #Recurrence exception.
If this property does not match any recurrence in the defined recurrence set, the whole #Recurrence exception MUST be ignored.
- "range": If the range parameter is specified, not only the matched recurrence is subject to the changes in the #Recurrence exception but also all future recurrences.
Implements:
Summary
property-summary = element summary {
element text { #String }
}
A brief description of the object.
This property MAY be interpreted as "title" or "display name" of the object. This property SHOULD be prominently visible to the user in a client implementation as it is one of the primary means for identifaction of the object.
Implements:
Description
property-description = element description {
element text { #String }
}
A more complete description of the incidence.
This property MAY be interpreted as "body" or "content" of the object. This property serves the purpose of attaching more information to the object.
Implements:
Priority
property-priority = element priority {
element integer { xsd:integer { minInclusive = "0" maxInclusive = "9" } }
}
Priority of the object.
The range MUST be in the range 0 to 9.
- 0 specifies an undefined priority.
- 1 specifies the highest priority.
- 9 specifies the lowest priority,
This property gives the user the possibilty to prioritize various objects. A client implementation SHOULD give the user the possibilty to sort objects according to priority.
A client implementation MAY use only a subset of priorities but it MUST understand all priority values. If a client implementation uses a range with a lower granularity it SHOULD preserve the original value if it is not modified. It SHOULD also define a mapping which preserves the meaning of the value.
Implements:
Status
property-status = element status {
element text { #String }
}
Status of the incidence.
For a #Todo it MUST be one of "NEEDS-ACTION", "COMPLETED", "IN-PROCESS", "CANCELLED".
For an #Event it MUST be one of "TENTATIVE", "CONFIRMED", "CANCELLED".
For a #Journal it MUST be one of "DRAFT", "FINAL", "CANCELLED".
The status of an incidence SHOULD be reflected in the visualization of an incidence.
Implements:
Percent complete
property-percent = element percent-complete {
element integer { xsd:integer { minInclusive = "0" maxInclusive = "100" } }
}
The work progress of a task, in percent.
The range MUST be from 0 to 100, with 0 indicating the task has not been started and 100 indicating the task has been completed.
The "percent-complete" property MAY' have the value 100 without the #Status property being set on "COMPLETED". This indicates that all necessary work has been done, but the todo is still not entierly completed.
Implements:
Location
property-location = element location {
element text { #String }
}
A textual description of the intended location of the incidence.
This MAY be an address or any other textual description of the location.
Implements:
Organizer
property-organizer = element organizer {
element parameters {
element cn { element text { #String } } ?,
element dir { element uri { uri-uid } } ?
} ?,
element cal-address { #Mailto URI }
}
The organizer of the incidence.
The cal-address MUST be a valid #Mailto URI. A contact MAY be referenced using the uri-uid.
- The cn parameter SHALL represent the display name of the organizer.
Implements:
Object URL
property-url = element url {
element uri { xsd:anyURI }
}
A URL associated with the calendar object.
The URL MAY point to a more dynamic version of the same calendar object, or it may also point to a website related to the calendar object.
Implements:
Attendee
property-attendee = element attendee {
element parameters {
element cn { element text { #String } } ?,
element rsvp { element boolean { xsd:boolean } } ?,
element partstat { element text {
"NEEDS-ACTION" |
"ACCEPTED" |
"DECLINED" |
"TENTATIVE" |
"DELEGATED"
} } ?,
element role { element text {
"CHAIR" |
"REQ-PARTICIPANT" |
"OPT-PARTICIPANT" |
"NON-PARTICIPANT"
} } ?,
element dir { element uri { uri-uid } } ?,
element delegated-to { element cal-address { Mailto URI } + } ?,
element delegated-from { element cal-address { Mailto URI } + } ?,
element cutype { element text {
"INDIVIDUAL" |
"GROUP" |
"RESOURCE" |
"UNKNOWN" |
"ROOM"
} } ?,
}?,
element cal-address { Mailto URI }
}
An attendee of an event.
The cal-address MUST be a valid Mailto URI. A contact MAY be referenced using the uri-uid.
- "cn": The display name of the contact.
- "rsvp": Used by the #Organizer to request a participation status reply from an attendee of a group-scheduled event or to-do. This parameter SHALL default to "FALSE" if not specified.
- "partstat": The participation status of the attendee. A client implementation MAY decide to automatically send an email to the #Organizer of the event if the "rsvp" parameter is set. This parameter SHALL default to "NEEDS-ACTION" if not specified.
- "NEEDS-ACTION": Event needs action.
- "ACCEPTED": Event accepted.
- "DECLINED": Event declined.
- "TENTATIVE": Event tentatively accepted.
- "DELEGATED": Event delegated.
- "role": The indended role the attendee will have. This parameter SHALL default to "REQ-PARTICIPANT" if not specified.
- "CHAIR": Indicates chair of the calendar entity.
- "REQ-PARTICIPANT": Indicates a participant whose participation is required.
- "OPT-PARTICIPANT": Indicates a participant whose participation is optional.
- "NON-PARTICIPANT": Indicates a participant who is copied for information purposes only.
- "dir": A uri pointing to a directory entry of the attendee.
- "delegated-to": Specifies the address of a calendar user to whom the attendee delegated participation.
- "delegated-from": Specifies the address of a calendar user that has delegated his participation to this attendee.
- "cutype": The type of attendee. This parameter SHALL default to "INDIVIDUAL".
- "INDIVIDUAL": Marks the attendee as an indiviual.
- "GROUP": Marks the attendee as a group of individuals. Useful to add e.g. a mailinglist as attendee.
- "RESOURCE": Marks the attendee as a physical resource. Used for Resource Management.
- "UNKNOWN": Should not be used. Undefined semantics.
- "ROOM": Should not be used. Undefined semantics.
Implements:
Freebusy Property
property-freebusy = element freebusy {
element parameters {
element fbtype { element text { "BUSY"|"BUSY-TENTATIVE"|"X-OUT-OF-OFFICE" } } ?,
element x-event {
element uid { #UID },
element summary { #Summary },
element location { #Location },
} ?,
}?,
element period {
element start{ #Start date },
element end { #End date },
}*
}
A collection of Freebusy Periods.
- "fbtype": The type of freebusy information. This parameter SHALL default to "BUSY".
- "BUSY": Indicates that the time interval is busy.
- "BUSY-TENTATIVE": Indicates that the time interval is busy because one or more events have been tentatively scheduled for that interval.
- "X-OUT-OF-OFFICE": Marks that the #Organizer of the freebusy object is out of office.
- "x-event": Meta-Information about which calendar object resulted in the contained periods. When used, this freebusy property SHALL only contain periods of the given calendar object.
The cal-address MUST be a valid #Mailto URI. A contact MAY be referenced using the uri-uid.
Implements:
Alarm
property-trigger = element trigger {
(
element parameters {
element related { element text { "START" | "END" } } ?
}?,
element duration { #Duration }
) | (
xcal-date-time
)
}
Specifies the trigger either on a specific date or with a combination of a duration relative to the #Start date or the #End date of the incidence.
- "related": Indicates if the trigger should be a duration of "duration" before the #Start date or the #End date. If not specified this parameter SHALL default to "START".
The duration SHALL denote the duration before either the #Start date or the #End date occurs, depending on the "related" parameter.
For #Todo components, instead of the #End date either the #Due date or the #Start date + #Duration SHALL be used.
If a date-time value is used it MUST be in UTC.
type-emailprop = element properties {
element action { text { "EMAIL" } },
element summary { #Summary },
element description { #Description },
element attendee { element cal-address { #Mailto URI } } +,
property-trigger,
(
element duration { #Duration },
element repeat { element integer { xsd:integer } }
) ?
}
An email alarm, which sends an email to each attendee on trigger.
Properties:
- "summary": The subject line of the email
- "description": The body of the email.
- "attendee": A receipent of the email alarm.
- "duration": Interval for additional repetitions.
- "repeat": Number of repetitions additionally to the trigger. (0 repetitions results in 1 execution of the alarm)
type-audioprop = element properties {
element action { text { "AUDIO" } },
element attach { xcal-property-attach } ?
property-trigger,
(
element duration { #Duration },
element repeat { element integer { xsd:integer } }
) ?
}
An audio alarm, which plays a sound on trigger.
- The attach property MUST point to an audio resource, which is rendered when the alarm is triggered.
type-dispprop = element properties {
element action { text { "DISPLAY" } },
element description { #Description },
property-trigger,
(
element duration { #Duration },
element repeat { element integer { xsd:integer } }
) ?
}
A display alarm which displays a message to the user on trigger.
component-valarm = element valarm {
type-audioprop | type-dispprop | type-emailprop
}
An alarm which can be added to todos or events
Interpretation of all values MUST be according to RFC 5545 section-3.6.6.
An alarm can trigger repeatedly by setting "duration", which SHALL indicate the break between alarms and "repeat", which SHALL indicate the number of repetitions.
Implements:
Todo
todo = element vtodo {
element properties {
element uid { text-uid },
element created { #Creation date },
element dtstamp { #Last modification date },
element sequence { #Sequence }, ?
element class { #Classification } ?,
element categories { property-categories } ?,
element related-to { #Related-to } *,
element dtstart { #Start date } ?,
element due { #Due date } ?,
element rrule { #Recurrence rule } ?,
element rdate { #Recurrence date } ?,
element exdate { #Exception date } ?,
element recurrence-id { #Recurrence ID } ?,
element summary { #Summary } ?,
element description { #Description } ?,
element priority { #Priority } ?,
element status { #Status } ?,
element percent-complete { #Percent complete } ?,
element location { #Location } ?,
element organizer { #Organizer } ?
element url { #Object URL } ?,
element attendee { #Attendee } *,
element attach { xcal-property-attach } *,
element x-custom { #Kolab Custom Property } *
},
element components {
element valarm { alarm } +
}?
}
An object representing a task/todo.
- X-Kolab-Type: application/x-vnd.kolab.task
Implements:
Event
event = element vevent {
element properties {
element uid { text-uid },
element created { #Creation Date },
element dtstamp { #Last modification date },
element sequence { #Sequence }, ?
element class { #Classification } ?,
element categories { property-categories } ?,
element dtstart { #Start date },
element dtend { #End date } ? |
element duration { #Incidence Duration } ?,
element transp { #Transparency } ?,
element rrule { #Recurrence rule } ?,
element rdate { #Recurrence date } ?,
element exdate { #Exception date } ?,
element recurrence-id { #Recurrence ID } ?,
element summary { #Summary } ?,
element description { #Description } ?,
element priority { #Priority } ?,
element status { #Status } ?,
element location { #Location } ?,
element organizer { #Organizer } ?
element url { #Object URL } ?,
element attendee { #Attendee } *,
element attach { xcal-property-attach } *,
element x-custom { #Kolab Custom Property } *
},
element components {
element valarm { alarm } +
}?
}
An object representing an event.
- Content-Type: application/calendar+xml
- X-Kolab-Type: application/x-vnd.kolab.event
Implements:
Journal
journal = element vjournal {
element properties {
element uid { text-uid },
element created { #Creation Date },
element dtstamp { #Last modification date },
element sequence { #Sequence }, ?
element class { #Classification } ?,
element categories { #Categories } ?,
element dtstart { #Start date } ?,
element summary { #Summary } ?,
element description { #Description } ?,
element status { #Status } ?,
element attendee { #Attendee } *,
element attach { xcal-property-attach } *,
element x-custom { #Kolab Custom Property } *
}
}
An object representing an journal entry. Journal entries SHALL, as opposed to notes, be related to a calendar date.
- Content-Type: application/calendar+xml
- X-Kolab-Type: application/x-vnd.kolab.journal
Implements:
Freebusy
freebusy = element vfreebusy {
element properties {
element uid { text-uid },
element dtstamp { #Last modification date },
element dtstart { #Start date },
element dtend { #End date } ? |
element organizer { #Organizer } ?
element freebusy { #Freebusy Property } *,
}
}
An object representing a collection of free or busy time information.
- Content-Type: application/calendar+xml
- X-Kolab-Type: application/x-vnd.kolab.freebusy
Implements:
xCard based objects
All xCard based objects MUST fully comply to RFC 6351[5].
Each Kolab XML Object MUST contain exactly one contact/distribution list object stored according to RFC 6351[5].
Properties
Kind
property-kind = element kind {
element text { "individual" | "group" }
}
Specifies the kind of xCard object.
This property MUST be set to "individual" for #Contact objects.
This property MUST be set to "group" for #Distribution List objects.
Implements:
Name
property-fn = element fn {
element text { #String }
}
A formatted text corresponding to the name of the contact/distribution list.
This property SHOULD be the primary identifier for a user to recognize the contact.
Implements:
Name Components
property-n = element n {
element surname { #String }*,
element given { #String }*,
element additional { #String }*,
element prefix { #String }*,
element suffix { #String }*
}
Specifies the indvidual components the name of the contact consists of.
Components:
- "surname": A surname (familyname) of the contact.
- "given": A given name of the contact.
- "additional": An additional name.
- "prefix": A honorific prefix.
- "suffix": A honorific suffix.
Client implementations SHOULD be able to handle multiple values of each component.
Implements:
Note
property-note = element note {
element text { #String }
}
To specify supplemental information or a comment that is associated with the contact.
Implements:
Freebusy URL
property-fburl = element fburl {
element uri { xsd:anyURI }
}
Specifies the URI for the busy time associated with the contact.
Implements:
Title
property-title = element title {
element text { #String }
}
Specifies a position or profession of the contact.
In contrast to #Role, this property denotes a general profession/occupation of the contact, and is not bound to a specifc organization.
Examples:
* "Computer Scientist"
Implements:
Affiliation
Affiliation specific elements are grouped by a "group" element. The "group" element is the xCard equivalent to the "group construct" as specified in RFC 6350 section-3.3 and is specified in RFC 6351 section-5.
A contact MAY be associated with multiple organizations by using multiple affiliation groups.
Organization
property-org = element org {
element text { #String } +
}
A organization associated with the contact
A single "org" property MUST be used for only one organization.
Organizations are of no specific type.
The first text value MUST denote the organizations name.
Further text values MAY be appended to denote organizational units the contact is associated with.
Implements:
Logo
property-logo = element logo {
element uri { #URI inline encoding }
}
A logo of the organization the contact is affiliated with
Implements:
Role
property-role = element role {
element text { #String }
}
Specifies a role/function of the contact within the organization.
In contrast to #Title, this property denotes a specific role/function within an organization, and not a generic profession/occupation.
Examples:
* "Systems Architect" * "Manager,Distributed Applications"
Implements:
URL
property-url = element url {
element parameters { element type { element text { "x-blog" } } } ?,
element uri { xsd:anyURI }
}
A generic URL which is related to the contact.
The the following types SHOULD be used to indicate the type of the URL.
- "x-blog": Indicates that the URL points to a blog related to the contact.
If no type is specified, the URI SHALL be interpreted as generic website related to the contact.
Implements:
Address
property-adr = element adr {
element parameters {
element pref { element integer { 1 } } ?,
element type {
element text { "work" | "home" } +
} ?,
element label { #String } ?
} ?,
element pobox { #String },
element ext { #String },
element street { #String },
element locality { #String },
element region { #String },
element code { #String },
element country { #String }
}
An address of the contact or organization.
Address components:
- "pobox": The post office box. This component SHOULD NOT be used as recommended by RFC 6350section-6.3.1.
- "ext": The extended address (e.g., apartment or suite number). This component SHOULD NOT be used as recommended by RFC 6350section-6.3.1.
- "street": The street address.
- "locality": The locality (e.g., city).
- "region": The region (e.g., state or province).
- "code": The postal code.
- "country": The country name. Countries SHALL be named according to the official short names in english specified in ISO 3166-1 which can be looked up here [7][13].
The following types are defined:
- "work": Indicates that the address is work related.
- "home": Indicates that the address is home address.
The "pref" parameter MAY be used to indicate the preferred address. Only one address SHOULD be marked as preferred address.
The "label" parameter MAY be used to set a label for the address which client implementations SHOULD present to the user as primary means for identification of the address.
If used within an #Affiliation this property SHALL be used for any related address, such as an office of the organization. The "label" parameter MAY be used to store a freeform version of such a location description (i.e. office).
Implements:
Nickname
property-nickname = element nickname {
element text { #String } *
}
A list of nicknames.
Implements:
Related
property-related = element related {
element parameters {
element type {
element text {
"spouse" | "child" | "x-manager" | "x-assistant"
} +
}?
}?,
( element uri { uri-uid } | element text { #String } )
}
Specifies a relation of the contact to another contact.
Clients SHALL use a uri-uid to reference a Contact object when using the uri element. Clients MUST be able to deal with uri-uid.
Types:
- "spouse": Specifies that the related contact is the spouse of this contact. This value SHOULD only occur within the toplevel related property.
- "child": Specifies that the related contact is the child of this contact. This value SHOULD only occur within the toplevel related property.
- "x-manager": Specifies a manager of the contact within the organization. This value SHOULD only occur within related properties within an #Affiliation.
- "x-assistant": Specifies an assistant of the contact within the organization. This value SHOULD only occur within related properties within an #Affiliation.
Implements:
Birthday
property-bday = element bday {
xcard-date-time
}
The birthday of the contact.
The date-time value MUST be in local time.
Implements:
Anniversary
property-anniversary = element anniversary {
xcard-date-time
}
The anniversary of the relationship the contact is part of.
The date-time value MUST be in local time.
Implements:
Photo
property-photo = element photo {
element uri { #URI inline encoding }
}
An image or photograph representing the contact.
Implements:
Gender
property-gender = element gender {
element sex { "" | "M" | "F"}
}
Specifies the gender of the contact.
Values:
- "": Not specified
- "M": Male
- "F": Female
If this property is not specified it SHALL default to "".
Implements:
Language
property-lang = element lang {
element language-tag { #String }
}
A language that MAY be used to contact the contact.
A language MAY be defined freely and does not follow a naming-scheme.
Implements:
Telephone
property-tel = element tel {
element parameters {
element pref { element integer { 1 } } ?,
element type {
element text { "work" | "home" | "text" | "voice"
| "fax" | "cell" | "video" | "pager"
| "textphone" | "x-car" }+
}?
}?,
element text { #String }
}
A telephone number.
A telephone number MAY have one or more type defined.
The following types are defined:
- "work": Indicates that the telephone number is work related.
- "home": Indicates that the telephone number is private.
- "text": Indicates that the telephone number supports text messages (SMS).
- "voice": Indicates a voice telephone number.
- "fax": Indicates a fax machine telephone number.
- "cell": Indicates a cellular or mobile telephone number.
- "video": Indicates a video conferencing telephone number.
- "pager": Indicates a paging device telephone number.
- "textphone": Indicates a telecommunication device for people with hearing or speech difficulties.
- "x-car": Indicates the telephone number of a car.
Only the defined types MUST be used.
If a client implementation uses another undefined type, this type SHALL be mapped to the most suitable of the defined values.
The "pref" parameter MAY be used to indicate a preferred telephone number. Multiple numbers MAY be marked as preferred.
Implements:
IM Address
property-impp = element impp {
element parameters { element pref { element integer { 1 } } } ?,
element uri { xsd:anyURI }
}
A Instant Messenger contact.
The "pref" parameter MAY be used to indicate the preferred IM address. Only one IM address SHOULD be marked as preferred address.
Implements:
property-email = element email {
element parameters {
element pref { element integer { 1 } } ?,
element type { element text { "work" | "home" } } *
} ?,
element text { #String }
}
An email address of the contact.
The text value SHOULD be interpreted as addr-spec according to RFC 5322[14] [8].
The "pref" parameter MAY be used to indicate the preferred email address. Only one email address SHOULD be marked as preferred address. The "type" parameter MAY be used to indicate the type of the email address.
- "work": indicates the email address is work related
- "home": indicates the email address is a private email address
Implements:
Global Positioning
property-geo = element geo {
element uri{ #Geo URI }
}
Specifies a global position of the contact.
The global position SHOULD be interpreted as a location which is related to the contact, respectively meaningful for the user of the contact object.
Implements:
Cryptographic Key
property-key = element key {
element uri { #URI inline encoding }
}
Specifies a public key or authentication certificate associated with the contact.
This key MAY be used to encrypt or sign using OpenPGP or S/MIME. The embedded key SHALL have the type "application/pgp-keys" or "application/pkcs7-mime".
Implements:
Cryptographic Preferences
property-crypto = element x-crypto {
element allowed { element text { "PGP/INLINE" | "PGP/MIME" | "S/MIME" | "S/MIMEOpaque" }* } ?,
element signpref { element text { "Never" | "Always" | "IfPossible" | "Ask" } } ?,
element encryptpref { element text { "Never" | "Always" | "IfPossible" | "Ask" } } ?
}
Specifies crypto related settings.
- "allowed": Specifies the allowed encryption/signing protocols for sending mail to the contact. This setting SHOULD override the default settings of the mail composer. If none of the allowed protocols is available the signing/encrypting SHOULD fail. If not specified all protocols are allowed.
- "PGP/INLINE": Allows inline-PGP for encrypted and signed content.
- "PGP/MIME": Allows PGP/MIME for encrypted and signed content.
- "S/MIME": Allows clear signed messages using S/MIME.
- "S/MIMEOpaque": Allows opaque signed messages using S/MIME.
- "signpref": This preference SHOULD be considered when sending content to the contact. If not specified this preference SHALL default to "Ask"
- "Never": Never sign something before sending.
- "Always": Alway sign, abort if signing is not possible.
- "IfPossible": Sign if possible, otherwise just send unsigned.
- "Ask": Always ask the user what to do.
- "encryptpref": This preference SHOULD be considered when sending content to the contact. If not specified this preference SHALL default to "Ask"
- "Never": Never encrypt something before sending.
- "Always": Alway encrypt, abort if encryption is not possible.
- "IfPossible": Encrypt if possible, otherwise just send unencrypted.
- "Ask": Always ask the user what to do.
These properties MAY be considered in email communication with the client.
Uses:
Member
property-member = element member {
element uri { #Contact URI }
}
A member of the distribution list.
A member MUST contain a valid #Contact URI.
Implements:
Contact
contact = element vcard {
element uid { uri-uid },
element x-kolab-version { #Kolab XML Version },
element prodid { #Product ID },
element rev { #Last modified date },
element categories { #Categories } ?,
element kind { "individual" },
element fn { #Name },
element n { #Name Components } ?,
element note { #Note } ?,
element fburl { #Freebusy URL } ?,
element title { #Title } *,
element group {
attribute name { "Affiliation" },
element org { #Organization },
element logo { #Logo } ?,
element role { #Role } *,
element related { #Related } *,
element adr { #Address } *
} *,
element url { #URL } *,
element adr { #Address } *,
element nickname { #Nickname },
element related { #Related } *,
element bday { #Birthday } ?,
element anniversary { #Anniversary } ?,
element photo { #Photo } ?,
element gender { #Gender } ?,
element lang { #Language } *,
element tel { #Telephone } *,
element impp { #IM Address } *,
element email { #EMail } *,
element geo { #Global Positioning } *,
element key { #Cryptographic Key } *,
element x-crypto { #Cryptographic Preferences } ?,
element x-custom { #Kolab Custom Property } *
}
An address book entry for a contact.
- Content-Type: application/vcard+xml
- X-Kolab-Type: application/x-vnd.kolab.contact
If the vcard:kind element is absent, it MUST default to "individual".
Implements:
Distribution List
distlist = element vcard {
element uid { text-uid },
element x-kolab-version { #Kolab XML Version },
element prodid { #Product ID },
element rev { #Last modification date },
element categories { #Categories } ?,
element kind { "group" },
element fn { #Name },
element member { #Member } *,
element x-custom { #Kolab Custom Property } *
}
A distribution list mostly used for emailing.
- Content-Type: applica: A honorific suffix.
Client implementations SHOULD be able to handle multiple values of each component.
Implements:
Note
property-note = element note {
element text { #String }
}
To specify supplemental information or a comment that is associated with the contact.
Implements:
Freebusy URL
property-fburl = element fburl {
element uri { xsd:anyURI }
}
Specifies the URI for the busy time associated with the contact.
Implements:
Title
property-title = element title {
element text { #String }
}
Specifies a position or profession of the contact.
In contrast to #Role, this property denotes a general profession/occupation of the contact, and is not bound to a specifc organization.
Examples:
* tion/vcard+xml
- X-Kolab-Type: application/x-vnd.kolab.distribution-list
The vcard:kind element MUST have the value "group".
Note
note = element note {
attribute version { #Kolab XML Version },
element uid { value-uid },
element prodid { value-productid },
element creation-date { value-creation-date },
element last-modification-date { value-lastmodified-date },
element categories { value-category } *,
element classification { value-classification } ?,
element attachment { kolab-property-attach } *,
element summary { #String } ?,
element description { #String } ?,
element x-custom { #Kolab Custom Property} *
}
A generic note, not necessarily associated with a specific date.
- Content-Type: application/vnd.kolab+xml
- X-Kolab-Type: application/x-vnd.kolab.note
File
file = element file {
attribute version { #Kolab XML Version },
element uid { value-uid },
element prodid { value-productid },
element creation-date { value-creation-date },
element last-modification-date { value-lastmodified-date },
element categories { value-category } *,
element classification { value-classification } ?,
element file { kolab-property-attach },
element note { #String } ?,
element x-custom { #Kolab Custom Property} *
}
A snapshot of a file.
- Content-Type: application/vnd.kolab+xml
- X-Kolab-Type: application/x-vnd.kolab.file
Properties
Configuration
configuration = element configuration {
attribute version { #Kolab XML Version },
element uid { value-uid },
element prodid { #Product ID },
element creation-date { #Creation date },
element last-modification-date { #Last modification date },
element type { #String },
configurationtype-fields
}
A Kolab configuration object.
- Content-Type: application/vnd.kolab+xml
- X-Kolab-Type: application/x-vnd.kolab.configuration.TYPE
The TYPE of the X-Kolab-Type MUST correspond to the "type" element.
The individual configurationtype-fields SHALL be defined individual KEP proposals. Depending on the "type" value the corresponding configurationtype-fields SHALL be used.
Implements:
Value Types
Date-Time
Following the provisions set forth in RFC 6321 section 3.6.5, date-time values MUST be specified as unspecified local time (floating time), UTC, or local time in a specific time zone.
VTIMEZONE fields MUST NOT be used in Kolab Format 3.0.
UTC-offset times MUST NOT be used.
A time value MUST only specify the second 60 when specifying a positive leap second. Implementations that do not support leap seconds SHOULD interpret the second 60 as equivalent to the second 59.
Timezone Identifier
For the Kolab Format, the name of that time zone is a string, which MUST be a geographical time zone identifier in the uniform naming convention designed by Paul Eggert, specifying time zones from the Olson database, a.k.a. tz database, a.k.a. zoneinfo database [18].
A Timezone identifier MUST NOT be specified for UTC date-times.
Clients MUST preserve user preference and selection in the "tz" attribute to the maximum extent possible.
Clients SHOULD check if a new update of the Olson database or the authoritative database used by the system is available and get that update at least once every three months, OR suggest update policies for their respective operating systems that ensure the time zone data database gets updated regularly. As far as is currently known, all commonly used and supported GNU/Linux distributions do this already.
When creating a new object with time zone sensitive fields, clients SHOULD default to the local time zone of the user, but SHOULD allow the user to select the time zone for storage.
When modifying existing objects, clients MUST use the value of the 'tz' attribute of the respective fields to set the default/preselected value for the editing of the fields, where applicable. For instance the 'start-date' and 'end-date' time zone defaults if presented to the user by the client MUST match those stored in the 'tz' attribute. The time zone stored in the 'tz' attribute SHOULD only be changed based upon user interaction.
tzid mapping table
There should be mapping between time zone identifiers from and to the Olson database locations for systems not based on the Olson time zone identifiers, i.e. Microsoft Windows. In order to achieve that, Kolab Systems will work with the various client implementers to provide a canonical mapping table that all clients without Olson database can use for such mapping on their systems against the Olson database locations. This tzid mapping table will be provided publicly under a Free Software license. Format and usage of that mapping table shall be defined in another KEP. This mapping MUST be performed on writing that only defined Timezone Identifiers are written to the Kolab XML Object.
xCal Timezone Identifier
xcal-tzid = element tzid {
element text { #String }
}
xCal based objects MUST prefix the timezone identifier with "/kolab.org/".
Implements:
xCal Date-Time
xcal-date-time = date-time {
xsd:string { pattern = "\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ?" }
}
xcal-date = date {
xsd:string { pattern = "\d\d\d\d-\d\d-\d\d" }
}
xcal-date-or-date-time = ( xcal-date | xcal-date-time )
The date and time pattern MUST be in the format
"yyyy-MM-dd:hh:mm:ss"
To indicate that a date-time is in UTC a 'Z' MUST be appended.
Implements:
xCard Date-Time
xcard-date-time = date-time {
xsd:string { pattern = "\d\d\d\d\d\d\d\dT\d\d\d\d\d\dZ?" }
}
xcard-date = date {
xsd:string { pattern = "\d\d\d\d\d\d\d\d" }
}
xcard-date-or-date-time = ( xcard-date | xcard-date-time )
The date and time pattern MUST be in the format
"yyyyMMddThhmmss"
The date-time value MUST be a local time as specified in RFC 6350[20]. Note that while RFC 6350[20] allows the usage of UTC-offset times, this MUST NOT be used.
To indicate that a date-time is in UTC a 'Z' MUST be appended.
Implements:
Examples
- Floating Time according to RFC 6321: <date-time>2011-05-17T13:00:00</date-time>
- UTC according to RFC 6321: <date-time>2011-05-17T13:00:00Z</date-time>
- Local time in timezone according to RFC 6321:
<parameters>
<tzid><text>/kolab.org/Europe/Zurich</text></tzid>
</parameters>
<date-time>2011-05-17T13:00:00</date-time>
- Floating Time according to RFC 6351: <anniversary><date-time>20090808T143000</date-time></anniversary>
Color
The value SHALL be a sRGB[12][21] color value expressed in a 6-digit hexadecimal web color[13][21] with the magic value of 'XXXXXX' referring to an explicit 'No Color' selection.
String
Strings MUST be represented as defined by xsd:string in [14].
Integer
An integer as defined by xsd:positiveInteger, xsd:negativeInteger and xsd:integer in [15].
Duration
pattern-duration = xsd:string {
pattern = "(+|-)?P(\d+W)|(\d+D)?"
~ "(T(\d+H(\d+M)?(\d+S)?)|"
~ "(\d+M(\d+S)?)|"
~ "(\d+S))?"
}
A duration according to RFC 6321 section 3.6.6.
Implements:
URI
A URI MUST be represented as defined by xsd:anyURI in [16].
URI inline encoding
The encoding MUST be "Base 64" according to RFC 4648[10]section-4
The uri scheme MUST be according to RFC 2397[22].[17]
Example
data:image/jpeg;base64,MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhv AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0 <...remainder of base64-encoded data...>
data:application/pgp-keys;base64,MIICajCCAdOgAwIBAgICBE UwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05l <... remainder of base64-encoded data ...>
Mailto URI
A Mailto URI MUST conform to RFC 6068[23].
The name of the contact MAY be embedded in the email address as specified in RFC 822[24] section-6.1. This technique SHALL only be used if no other means to indicate the name are available. In case the name is included, URL-reserved characters MUST be encoded.
Example:
mailto:John%20Doe%3cjdoe%40example.com%3e
Contact URI
value-uri = xsd:AnyURI
Any URI which is somehow relevant to identify/contact a Contact.
Clients SHALL either use a uri-uid to reference a Contact object or a #Mailto URI to specify a single email address. Clients MUST be able to deal with both uri-uid and #Mailto URI.
Geo URI
A geographic location identifier MUST conform to RFC 5870[25].
Versioning
Version number
A Version number MUST be a string according to KEP:5[26]
The version number SHALL reflect the Kolab XML Format definition version. An implementation SHOULD NOT write to a file with a higher version number, because that will potentially lead to data loss.
Due to the different formats of the Kolab XML Objects the version number is stored in different places:
- Objects according to RFC 5545 [19] such as Event/Todo contain the version number in the x-kolab-version element which MUST be contained in the vcalendar properties sequence.
- Objects according to RFC 6350 [20] such as Contact/DistributionList contain the version number in the x-kolab-version element which MUST be contained as top-level element directly in the vcard element
- Custom Kolab Objects MUST contain the version number in the version attribute of the root element.
If no version number is present, the version of the implementation SHALL be assumed.
Version upgrades / Backwards Compatibilty
Minor version upgrades MUST be backwards compatible in terms that they MUST only add OPTIONAL values. This ensures that implementations using a newer versions of the format can still read file written by an older implementation. Minor version upgrades MUST NOT remove OPTIONAL values or add/remove REQUIRED values.
An implementation MUST be able to read older versions of the format with the same major version number, meaning there is no conversion needed for minor format upgrades. An implementation of an older version of the format 'MAY be able to read newer versions, but it doesn't have to preserve additional data from the newer version of the format (a read/write cycle of a new format with an old implementation will potentially result in data loss.).
Implementation
To have one implementation which can be used by as many clients as possible libkolabxml will be developed. libkolabxml is a library written in C++ with bindings for PHP/Python and possibly further languages using SWIG[27].
Scope
- the serialization/deserialization from/to the xml string to/from the in memory representation
- ensuring that all written/read objects are structurally valid
The implementation doesn't provide any interpretation of the data.
Technology
Internally the serialization is based on xsdcxx[28] which internally uses the xerces validating xml parser. The databindings are based on XSD schemas partially kolab specific and partially provided by calconnect[29].
Version Upgrade
A simple upgrade of libkolabxml should provide an interactionless upgrade
Implementation limitations
Because the library validates the xml files, any unknown element will cause the validation to fail. This means even new optional element disable an older version of the library to read the document.
Extensibility
The extensibilty mechanisms of xCal/xCard are not supported, unless the extension elements are added to the Kolab Format specifcation (and thus, it's implementation).
Vendors MAY extend the format on their own by making use of the optional #Kolab Custom Property which ensures backwards compatibility.
Vendors SHOULD add their extensions using a #Kolab XML Format Enhancement Proposal to the official Kolab XML Format so other Vendors can reuse the values.
Kolab Custom Property
kolab-custom = x-custom {
element identifier { #String },
element value { #String }
}
The element MUST NOT be added to elements other than the following:
- icalendar/vcalendar/properties
- vcard
- note
- configuration
The "x-custom" element MUST appear on toplevel within those elements, custom properties which are deeper within the structure are not supported.
The "x-custom" element contains two subelement only:
- "identifier": unique identifier used to identify custom property.
- "value": value of the custom property
Client implementatinos SHALL preserve all custom properties.
Example:
<x-custom> <identifier>cusotomtypeidentifier</identifier> <value>customvalue</value> </x-custom>
Support of existing Extensions
The Kolab XML Format MAY be extended by adding new supported extensions to xCal/xCard objects or new elements to custom Kolab XML objects. In order to do this, extensions MUST be added to the Kolab XML Format Specification first. Extensions added to the Kolab XML Format are not subject to the limited extension approach as lined out above.
Extensions added to the Kolab XML Format MUST NOT introduce redundant data.
Kolab XML Format Enhancement Proposal
A proposal to extend the Kolab XML Format should be sent to kep-secretariat@lists.kolabsys.com.
A proposal SHALL have the following structure:
- Extension name: x-vendor-name
Desired name of the extension
- Structure:
<x-vendor-name> <value1/> <value2/> </x-vendor-name>
Description of the structure in XML, Relax NG or similar.
- Example:
<x-kolab-specialproperty> <value1>val1</value1> <value2>val2</value2> </x-kolab-specialproperty>
A real world example how such an extension would look like.
- Description:
Exact description of the value and how it is used using the in RFC 2119 [30] defined keywords.
- Rationale:
A description why the value is needed.
- Author:
Author of the application
This allows the Kolab Community to evaluate if the extension is reasonable and can't be modeled using the existing properties. The discussion SHALL take place on kolab-format@kolab.org.
Upgrade Path
This KEP replaces the complete Kolab XML Format specification. Old implementations will not be able to read documents produced according to this specification.
Rationale
Overview
The current Kolab XML Format specification is for many problems not powerful enough, resulting in constant extension through KEPs. Further the specification is not very explicit about the value semantics, leading to a potential problems for interoperability and maintainability of the format.
The original motivation to create an own Kolab XML Format, the interoperability issues of iCal and vCard, still apply, but those specifications have improved since and the approach how to define this format has been reconsidered. The recent release of the xCal/xCard specifications provide a good specification base for our format. The calendaring problem space is complex and it is very difficult to design a format from scratch which serves all current needs and is extensible in a sustainable manner. By using those RFCs as "framework" we can ensure that format can grow in a sustainable way, while we can start with only the needed subset of values.
Given that at least Kontact follows those specifications closely, making use of this format also makes the mapping to the UI a lot easier.
The process for this KEP evolved from the idea to have an XSD-binding based library for the old format to a complete redefinition of the format. Some key points which were evaluated, respectively some conclusions made in the process were:
- A pure XSD-based databinding in native languages is not enough because XSD is not expressive enough (cannot validate all constructs) and there is a lack of tools (i.e. for PHP)
- The current Kolab Format would have to be extended extensively in order to support all features of Kontact, resulting in something similar to existing standards
- We're so much bound to iCal/vCard by the client implementations that we can in fact not change much in the format without breaking a usecase (try to simplify recurrences and you'll see...). => The client UI defines our format (to some extent)
- Interoperability is not ensured by the format, there is still a lot of room for different interpretation on the interpretation layer. The format description therefore needs to go beyond what values are allowed and give descriptions of the value semantics and how clients should behave.
- The used RFCs have too many options and are thus never fully implemented.
While the used RFCs do provide a solid base for a format specification, they were never meant as storage format, but as a format for representation and transport. This becomes apparent in the flexiblity of the specifications, allowing often many different ways to do the same thing and providing a miriad of optional parameters. To be usable as a storage format, the Kolab XML Format specification provides the additional information/restrictions resulting in a sparse, canonical and normative format where every property serves a particular usecase.
This specification was designed to serve all currently existing usecases while allowing for future extensions. This means the properties are designed in a way that they don't serve any hypothethic usecase but rather existing ones, while being extensible in a way that the format can grow and support new usecases in a sustainable way. This way "dead-on-arrival" properties which serve no real usecase and have to be maintained for the lifetime of the format, can be avoided. The used RFCs provide an excellent "framework" for this task.
Interoperability
It was established that the existing iCal and vCard specifications suffer from interoperability issues, not because the specifications are bad, but because they are too flexible and too large to ever be fully implemented. This results in different clients speaking different "dialects" (subsets which are all conforming to iCal but incompatible to each other).
The approach the first Kolab XML Format version took, was to redefine the format from scratch, resulting in a simpler, actually implementable specification. It oversimplified some problems though, lacked a firm specification and finally didn't provide all features for the usecases of today.
By reusing the existing iCal/vCard specifications we can not only reuse the value semantics, which are difficult define, we can also use those specifications as framework within which our specification can grow according to our needs, while we can be sure that we are not oversimplifying a problem because the used RFCs make sure we can implement/model at least all their features.
By defining the Kolab XML Format as a fully RFC compliant subset, we ensure an implementable specification which provides additional specification where the RFC's are not exact enough or allow for too many options. This way the interoperability of the format is improved. By being RFC compliant, a sustainable format is ensured which should also lower the adoption barrier for other projects.
It is acknowledged that the format alone does not solve interoperability and that a system where different client implementations exchange data (such as Kolab) need a transformation layer which maps the values of the Kolab XML Format to the internally used values of each implementation. The Kolab XML Format specification provides the "common grounds" for these translation layers. A translation layer can appear in client implementations which implement the Kolab XML Format, or on a server where a CalDAV implementation can map Kolab XML Values to the respective "iCal dialect" the client speaks (iCal dialect because every implementation which uses iCal uses a slightly different subset of iCal).
This way we achieve a strict and exact definition of our format. By implementing the said translation layers we take control that can ensure true interoperability.
Date-Time format
- Local time with timezone information indicates that local time in a specific location is wanted
- Local time without timezone information indicates that local time in the current location is wanted (and that it should change with the location)
- UTC indicates that an absolute time is wanted which is not bound to locations or timezones.
Timezones are only referred to by identifier and not directly embedded, with the idea that the interpreting system can use updated timezone information. It is true that this results in information loss in terms that it is not known anymore to which UTC time the originally described time (using a timezone) originally resolved. It is assumed that the intention of the user is to have an event at a certain time, no matter how the timezones changed. As an example:
Paul scheduled a meeting at 10:00 in Paris because he starts working at 8:00 in the office. If now the timezone had changed by one hour he still would want his meeting at 10:00 and not suddenly at 9:00 although that means the UTC time of the meeting has effectively changed. This is due to the fact that his daily schedule changes with changing timezones.
Therefore embedding the old timezone information, while preserving the originally intended UTC time, would work agains Paul's intention of having a meeting two hours after work.
UTC offset times are not used because they are an oversimplifaction of timezones.
KEP:2 Background notes on design decisions and backwards compatibility explains this in further detail.
Reason for not implementing the default extensions mechanisms
The extension mechanisms provided by xCal/xCard are much to complicated to implement by allowing arbitrary content anywhere in the xml structure. Since this data has to be stored by clients in their in-memory representation one would have to store xPath/value pairs, which could be inserted into the structure on writing. Also the parser would have to check in every element if extension elements are nested, since there is no single defined place where extension elements are. This is too complicated given that it hardly serves any usecase.
Using an XSD based databinding this feature is not even feasible (except by adding an xs:any element before and after every single element in the document).
With the restricted version, we can build data-bindings to access the data and can collect the custom element in on defined place.
Further, by restricting the extensibility, we encourage vendors to include their extensions into the official format, which is only benefical for the Kolab eco-system.
Reason for not using namespaces and the element name as identifier
Theoretically vendors could arbitrarily extend the format with elements of any name in a their own namespace. The problem with this is that all implementation need to be able to read the elements in order to preserve them.
Points of concern with the used RFC's
The main points of concern with the used RFC's are:
- extension mechanism
- interoperability
- no defined ordering
While the first two have been discussed already, the last needs some explanation. While there is a performance penalty in reading the elements without defined order (one has to potentially loop everytime through all elements before finding the right one, in the worst case), this is not the main concern. The main concern is that XSD does not allow to specify unordered content without a workaround, and with this workaround we loose complete control over cardinalities (how many times and if an element MUST appear). This is of course an implementation specific problem but since there doesn't seem to be any additional value in unordered content it's still at least a questionable design decision.
The said workaround is to make all types of the unordered list an extension of a "BaseType". If a list of this "BaseType" is defined, it is obviously possible to add elements of the type "BaseType" to the list in any order.
To fix this shortcoming of the used RFC's the order is required in the Kolab XML Format.
Hierarchical Categories
This part describes hierarchical categories as they're traditionally used by Kontact. Hierachical categories are still being used until more powerful concepts such as PIM-Item Relations are in place.
value-category = ( #String ) category-hierarchy = value-category("\"value-category)* property-categories = ( element text { category-hierarchy } + )
Hierachical categories used for backwards compatibility
The tags MAY use a hierarchy by prepending parent tags using '\' (Backslash: U+005C) as delimiter.
A value-category MUST NOT contain a '\' (Backslash: U+005C).
Defining a single category-hierarchy SHALL be sufficient to define all categories which are part of the hierarchy, but the object "MUST" only get the whole category-hierarchy as category and not each indvidual value-category.
A category SHALL be identifieable by string comparison. The whole category-hierarchy MUST be compared.
References
- ↑ KEP:1 Bootstrapping the KEP process
- ↑ 2.0 2.1 KEP:2 Modification of datetime: store local time, add 'tz' attribute
- ↑ 3.0 3.1 3.2 KEP:9 Configuration_storage_in_XML_objects
- ↑ 4.0 4.1 4.2 RFC 6321: XML Representation of iCal (xCal)
- ↑ 5.0 5.1 5.2 RFC 6351: XML Representation of vCard (xCard)
- ↑ [1] Relax NG compact syntax
- ↑ [2] XSD Pattern
- ↑ RFC 2822: Internet Message Format
- ↑ 9.0 9.1 RFC 4122
- ↑ 10.0 10.1 RFC 4648
- ↑ 11.0 11.1 KEP:3 Introduction of subevent sub-tag for exclusion from recurrence
- ↑ KEP:8 Priority for events, matching iCalendar priority range
- ↑ official short names in English [3]
- ↑ RFC 5322 Internet Message Format
- ↑ RFC 4880 OpenPGP Message Format
- ↑ RFC 5751 Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.2 Message Specification
- ↑ KEP:13 Update contact object (Draft)
- ↑ Wikipedia: Zoneinfo
- ↑ 19.0 19.1 RFC 5545: XML Representation of iCal (xCal)
- ↑ 20.0 20.1 20.2 RFC 6350: XML Representation of vCard (xCard)
- ↑ 21.0 21.1 [4] sRGB
- ↑ RFC 2397 The "data" URL scheme"
- ↑ RFC 6068 The 'mailto' URI Scheme
- ↑ RFC 822 Standard for ARPA Internet Text Messages
- ↑ RFC 5870 A Uniform Resource Identifier for Geographic Locations ('geo' URI)
- ↑ KEP:5 Server Product Versioning
- ↑ SWIG
- ↑ xsdcxx
- ↑ [5] iCalendar in XML Schema
- ↑ RFC 2119: Key words for use in RFCs to Indicate Requirement Levels
- ↑ Dont use xml 1.1
Copyright
This document has been placed in the public domain.
