vCard Mapping deprecated
This article describes the mapping rules that are used when converting contacts to or from vCards using the Open-Xchange Server.
Introduction
In former releases of the Open-Xchange Server, when a contact was imported from a vCard, the server only stored vCard parameter values that could be mapped to internal OX properties of a contact, and ignored all further unknown or not mappable properties. Especially during CardDAV synchronization, this often led to partial data loss after the client fetched a previously imported vCard again from the server, for example if the client tried to save a third instant messenger property, a geographical location, or the PGP public key of the contact.
To circumvent these kinds of problems, the vCard import- and export-workflow was redesigned, and now allows to store the original vCard as well besides the mappable contact properties. If enabled, the original data as sent by the client is stored automatically in the context filestore, and is considered again during export in a way where any updates to the OX contact are merged back into the original vCard.
To support the described merging process, the mapping between OX contact attributes and vCard properties has been slightly adjusted to allow a deterministic conversion in both directions. Additionally, all OX contact attributes that are not covered by a well-known vCard property are exported as extended properties, so that all OX properties in an exported vCard are recognized correctly again during import. Further details about the mapping are documented in Mapping Rules below.
Configuration
Whether original vCards should be stored or not, as well as their maximum allowed size, can be controlled by some new properties in the configuration file contact.properties:
# Specifies whether the original files are persisted during vCard import or
# CardDAV synchronization. If enabled, the original vCard files will be stored
# in the appropriate filestore and are considered during export again. If
# disabled, all not mapped information is discarded and is no longer available
# when exporting the vCard again.
# Defaults to "true".
com.openexchange.contact.storeVCards=true
# Configures the maximum allowed size of a (single) vCard file in bytes.
# vCards larger than the configured maximum size are rejected and not parsed
# by the server. A value of "0" or smaller is considered as unlimited.
# Defaults to 4194304.
com.openexchange.contact.maxVCardSize=4194304
Please note that storing the original vCard requires an attached filestore for the context, so in case there is none (as indicated via com.openexchange.capability.filestore=false), this feature is not available - importing and exporting vCards then works much like before, i.e. no original vCard is saved, and only mappable properties are persisted.
Workflows
When importing and exporting contacts to or from vCard, there are basically two operation modes: On the one hand, the independent import or export of a contact to or from a vCard, and on the other hand, the process of merging contact updates into an original vCard (or the other way around, merging updated vCards into contacts).
While the first one is mainly used for one-time import-/export-purposes, the latter one is performed during a continuous synchronization of contacts as done via CardDAV, yet also a one-time export will pick up and merge with an existing vCard in case it exists. So, importing and exporting basically involves the following steps:
Export a contact with no original vCard:
- Start with a blank vCard
- Write all mapped OX properties into the vCard based on the mapping rules below
Export a contact with an original vCard:
- Load the stored vCard
- Merge all mapped OX properties into the vCard based on the mapping rules below
Import a vCard and create a new contact:
- Create a new contact
- Parse all mapped properties based on the mapping rules below
- Additionally, store the original vCard
Import a vCard and update an existing contact:
- Load the stored contact
- Parse all mapped properties based on the mapping rules below
- Store or overwrite a previously stored original vCard
Mapping Rules
Mapping between known OX contact attributes and vCard attributes is based on the following rules, where some of the mappings are simple and direct, while others are bit more complicated due to their different representations in the underlying data models.
Simple Mappings
Simple mappings refer to properties where some kind of direct mapping between OX contact attributes and vCard attributes exist. Since many properties in vCards can be defined more than once, the mapping uses the most preferred (based on the PREF type parameter) or first property in the vCard. The following list gives an overview about the directly mapped, simple properties:
| OX column ID | OX attribute name | vCard property | Remarks |
|---|---|---|---|
| 517 | anniversary | ANNIVERSARY | |
| 511 | birthday | BDAY | |
| 100 | categories | CATEGORIES | |
| 101 | private_flag | CLASS | Only exported if true |
| 500 | display_name | FN | |
| 515 | nickname | NICKNAME | |
| 518 | note | NOTE | |
| 570 | image1 | PHOTO | |
| 515 | nickname | NICKNAME | |
| 5 | last_modified | REV | Ignored during import |
| 520 | position | TITLE | |
| 514 | profession | ROLE | |
| 223 | uid | UID | |
| 558 | url | URL |
Extended Mappings
Besides the mappings where a direct property mapping is possible, there are some more mappings from OX contact fields to other well-known vCard properties or custom extended properties:
| OX column ID | OX attribute name | vCard property | Remarks |
|---|---|---|---|
| 537 | assistant_name | X-ASSISTANT | Additional fallbacks to X-MS-ASSISTANT, X-KADDRESSBOOK-X-AssistantsName, X-EVOLUTION-ASSISTANT |
| 536 | manager_name | X-MANAGER | Additional fallbacks to X-MS-MANAGER, X-KADDRESSBOOK-X-ManagersName, X-EVOLUTION-MANAGER |
| 516 | spouse_name | X-SPOUSE | Additional fallbacks to X-MS-SPOUSE, X-KADDRESSBOOK-X-SpouseName, X-EVOLUTION-SPOUSE |
| 513 | number_of_children | X-MS-CHILD | |
| 616 | yomi_first_name | X-PHONETIC-FIRST-NAME | |
| 617 | yomi_last_name | X-PHONETIC-LAST-NAME | |
| 571 | userfield01 | X-OX-USERFIELD-01 | |
| 572 | userfield02 | X-OX-USERFIELD-02 | |
| 573 | userfield03 | X-OX-USERFIELD-03 | |
| 574 | userfield04 | X-OX-USERFIELD-04 | |
| 575 | userfield05 | X-OX-USERFIELD-05 | |
| 576 | userfield06 | X-OX-USERFIELD-06 | |
| 577 | userfield07 | X-OX-USERFIELD-07 | |
| 578 | userfield08 | X-OX-USERFIELD-08 | |
| 579 | userfield09 | X-OX-USERFIELD-09 | |
| 580 | userfield10 | X-OX-USERFIELD-10 | |
| 581 | userfield11 | X-OX-USERFIELD-11 | |
| 582 | userfield12 | X-OX-USERFIELD-12 | |
| 583 | userfield13 | X-OX-USERFIELD-13 | |
| 584 | userfield14 | X-OX-USERFIELD-14 | |
| 585 | userfield15 | X-OX-USERFIELD-15 | |
| 586 | userfield16 | X-OX-USERFIELD-16 | |
| 587 | userfield17 | X-OX-USERFIELD-17 | |
| 588 | userfield18 | X-OX-USERFIELD-18 | |
| 589 | userfield19 | X-OX-USERFIELD-19 | |
| 590 | userfield20 | X-OX-USERFIELD-20 | |
| 522 | room_number | X-OX-ROOM-NUMBER | |
| 535 | info | X-OX-INFO | |
| 529 | number_of_employee | X-OX-NUMBER-OF-EMPLOYEE | |
| 534 | business_category | X-OX-BUSINESS-CATEGORY | |
| 532 | commercial_register | X-OX-COMMERCIAL-REGISTER | |
| 531 | tax_id | X-OX-TAX-ID | |
| 530 | sales_volume | X-OX-SALES-VOLUME | |
| 521 | employee_type | X-OX-EMPLOYEE-TYPE | |
| 512 | marital_status | X-OX-MARITAL-STATUS | |
| 618 | yomi_company | X-OX-YOMI-COMPANY | |
| 102 | color_label | X-OX-COLOR-LABEL |
Advanced mappings
Apart from the simple mappings above, there are also more complex vCard properties that refer to or are influenced by more than one OX contact property.
Addresses
- https://tools.ietf.org/html/rfc6350#section-6.3.1
- OX contacts have three address types:
business,homeand andother - For each, OX stores the properties
street,city,state,postal codeandcountry - Additionally, the mailing label for snail mail (as set by some Outlook clients) is held in
addressHome,addressBusinessandaddressOther - In vCards,
ADRproperties have the cardinality*, and may have an assignedLABELfor the mailing label - Each one is stored as structured value (
post office box,extended address,street address,locality,region,postal code,country name) - The address parts are mapped between OX contacts and vCards as follows:
street<->street addresscity<->localitystate<->regionpostal code<->postal codecountry<->country nameaddress<->LABEL
- Hence, there are no corresponding OX fields for
post office boxandextended address - During import, the mapping to vCard
ADRproperties is based on theTYPEparameters and follows the following rules:- For the
businessaddress, the firstADRproperty with typeworkand typeprefis parsed
if not found, parse the first with typework
if not found, delete the corresponding OX address properties - For the
homeaddress, the firstADRproperty with typehomeand typeprefis parsed
if not found, parse the first with typehome
if not found, delete the corresponding OX address properties - For the
otheraddress, the firstADRproperty with typex-otherand typeprefis parsed
if not found, parse the first with typex-other
if not found, parse the first without type parametershomeandwork
if not found, delete the corresponding OX address properties
- For the
- During export, the OX contact addresses are serialized to a previously saved original vCard as follows:
- Generally, if no single OX property that forms a specific address is set anymore, the corresponding vCard property is deleted during the update
- For the
businessaddress, the firstADRproperty with typeworkand typeprefis updated
if not found, update the first property with typeworkand add thepreftype
if not found, add a new property with typesworkandpref - For the
homeaddress, the firstADRproperty with typehomeand typeprefis updated
if not found, update the first property with typehome
if not found, add a new property with typehome - For the
otheraddress, the firstADRproperty with typex-otherand typeprefis updated
if not found, update the first property with typex-other
if not found, update the first property without typeshomeandworkand add thex-othertype
if not found, add a new property with typex-other
E-Mails
- https://tools.ietf.org/html/rfc6350#section-6.4.2
- OX contacts allow storing three different e-mail addresses:
email1(~business),email2(~home) andemail3(~other) - A
telexaddress is stored attelephone_telexin OX contacts, yet it is expressed asEMAILtype in vCards - In vCards,
EMAILproperties have the cardinality * - During import, the mapping to vCard
EMAILproperties is based on theTYPEparameters and follows the following rules:- Generally, if no matching vCard
EMAILproperty is found, the corresponding OX email property is deleted - For the
businessmail address, the firstEMAILproperty with typeworkand typeprefis parsed
if not found, parse the first with typework
if not found, and allEMAILproperties have no distinguishing type (i.e. none is markedwork,home,x-otherorTLX), parse the most preferred one - For the
homemail address, the firstEMAILproperty with typehomeand typeprefis parsed
if not found, parse the first with typehome
if not found, and allEMAILproperties have no distinguishing type (i.e. none is markedwork,home,x-otherorTLX), parse the 2nd most preferred one - For the
othermail address, the firstEMAILproperty with typex-otherand typeprefis parsed
if not found, parse the first with typex-other
if not found, parse theEMAILproperty that is grouped with anX-ABLabelwith value_$!<Other>!$_
if not found, parse the first without type parameterwork,home,x-otherorTLX
if not found, and allEMAILproperties have no distinguishing type (i.e. none is markedwork,home,x-otherorTLX), parse the 3rd most preferred one - For the
telexaddress, the firstEMAILproperty with typeTLXand typeprefis parsed
if not found, parse the first with typeTLX
- Generally, if no matching vCard
- During export, the OX contact mail addresses are serialized to a previously saved original vCard as follows:
- Generally, if no single OX property that forms a specific email is set anymore, the corresponding vCard property is deleted during the update
- For the
businessmail address, the firstEMAILproperty with typeworkand typeprefis updated
if not found, update the first with typeworkand add thepreftype
if not found, and allEMAILproperties have no distinguishing type (i.e. none is markedwork,home,x-otherorTLX), update the most preferred one and add theworktype
if not found, add a new property with typesworkandpref - For the
homemail address, the firstEMAILproperty with typehomeand typeprefis updated
if not found, update the first with typehome
if not found, and allEMAILproperties have no distinguishing type (i.e. none is markedwork,home,x-otherorTLX), update the 2nd most preferred one and add thehometype
if not found, add a new property with typehome - For the
othermail address, the firstEMAILproperty with typex-otherand typeprefis updated
if not found, update the first with typex-other
if not found, update theEMAILproperty that is grouped with anX-ABLabelwith value_$!<Other>!$_and add thex-othertype
if not found, and allEMAILproperties have no distinguishing type (i.e. none is markedwork,home,x-otherorTLX), update the 3rd most preferred one and add thex-othertype
if not found, add a new property with typesx-other - For the
telexaddress, the firstEMAILproperty with typetlxand typeprefis updated
if not found, update the first with typetlx
if not found, add a new property with typetlx
Instant Messenger
- https://tools.ietf.org/html/rfc6350#section-6.4.3
- OX contacts allow to store two IM addresses:
instant_messenger1(~business),instant_messenger2(~home) - OX contacts store IM addresses as arbitrary strings, there are no special protocol semantics applied
- In vCards, IMPP properties have the cardinality *
- In vCards, an instant messenger addresses are formed as URI, where the protocol part indicate the messenger type (such as 'aim' or 'irc')
- During import, the mapping to vCard
IMPPproperties is based on theTYPEparameters and follows the following rules:- The whole URI string is stored during import
- Generally, if no matching vCard
IMPPproperty is found, the corresponding OX instant messenger properties are deleted - For the
businessIM address, the firstIMPPproperty with typeworkand typeprefis parsed
if not found, parse the first with typework
if not found, and all IMPP properties have no distinguishing type (i.e. none is marked work or home), parse the most preferred one - For the
homeIM address, the firstIMPPproperty with typehomeand typeprefis parsed
if not found, parse the first with typehome
if not found, and all IMPP properties have no distinguishing type (i.e. none is marked work or home), parse the 2nd most preferred one
- The whole URI string is stored during import
- During export, the OX contact IM addresses are serialized to a previously saved original vCard as follows:
- If the stored value represents a URI, this URI is used directly, otherwise, a synthetic URI is constructed
- Generally, if no single OX property that forms a specific IM address is set anymore, the corresponding vCard property is deleted during the update
- For the
businessIM address, the firstIMPPproperty with typeworkand typeprefis updated
if not found, update the first with typeworkand add thepreftype
if not found, add a new property with typesworkandpref - For the
homeIM address, the firstIMPPproperty with typehomeand typeprefis updated
if not found, update the first with typehome
if not found, add a new property with typeshome
- If the stored value represents a URI, this URI is used directly, otherwise, a synthetic URI is constructed
Organization
- https://tools.ietf.org/html/rfc6350#section-6.6.4
- OX contacts store organizational attributes at
company,departmentandbranches - In vCards, the structured
ORGproperty holds theX.520 Organization Name and Organization Unit attributes [CCITT.X520.1988] - During import, the mapping to the vCard
ORGproperty is based on the following rules:- The first value from the structured
ORGproperty is used ascompany - The second value from the structured
ORGproperty is used asdepartment - All further values from the structured
ORGproperty are used asbranches - If no
ORGproperty is found, all corresponding contact attributes are deleted, too
- The first value from the structured
- During export, the OX contact's organizational attributes are serialized to a previously saved original vCard as follows:
- If no single OX property that forms the
ORGproperty is set anymore, the corresponding vCard property is deleted during the update - The structured value is always rewritten
- The
companyis used as first value of the structured value - The
departmentis used as second value of the structured value - The
branchesare used as further values of the structured value
- If no single OX property that forms the
Telephone
- https://tools.ietf.org/html/rfc6350#section-6.4.1
- OX contacts store telephone and fax numbers at the fields
telephone_business1,telephone_business2,fax_business,telephone_callback,telephone_car,telephone_company,telephone_home1,telephone_home2,fax_home,cellular_telephone1,cellular_telephone2,telephone_other,fax_other,telephone_isdn,telephone_pager,telephone_primary,telephone_radio,telephone_ttytdd,telephone_ip,telephone_assistant - In vCards, TEL properties have the cardinality *
- During import, the mapping from vCard
TELproperties is based on theTYPEparameters and follows the following rules:- Generally, if no matching vCard
TELproperty is found, the corresponding OX telephone properties are deleted - For the
telephone_pagerattribute, the most preferredTELproperty with typepageris parsed - For the
telephone_ttytddattribute, the most preferredTELproperty with typetextphoneis parsed - For the
telephone_isdnattribute, the most preferredTELproperty with typeisdnis parsed - For the
telephone_carattribute, the most preferredTELproperty with typecaris parsed - For the
cellular_telephone1attribute, the most preferredTELproperty with typecellis parsed - For the
cellular_telephone2attribute, the most preferredTELproperty with typescellandx-2ndis parsed
if not found, parse the second most preferredTELproperty with typecell - For the
telephone_callbackattribute, the most preferredTELproperty with typex-callbackis parsed - For the
telephone_companyattribute, the most preferredTELproperty with typex-companyis parsed - For the
telephone_assistantattribute, the most preferredTELproperty with typex-assistantis parsed - For the
telephone_ipattribute, the most preferredTELproperty with typex-ipis parsed - For the
telephone_radioattribute, the most preferredTELproperty with typex-radiois parsed - For the
telephone_primaryattribute, the most preferredTELproperty with typex-primaryis parsed - For the
fax_businessattribute, the most preferredTELproperty with typesfaxand typeworkis parsed - For the
fax_homeattribute, the most preferredTELproperty with typesfaxand typehomeis parsed - For the
fax_otherattribute, the most preferredTELproperty with typesfaxand typex-otheris parsed - For the
telephone_business1attribute, the most preferredTELproperty with typesvoiceand typeworkis parsed
if not found, parse the most preferredTELproperty with typeworkand without any of the typestext,fax,cell,video,pager,textphone - For the
telephone_business2attribute, the most preferredTELproperty with typesvoice,workandx-2ndis parsed
if not found, parse the most preferredTELproperty with typesworkandx-2ndand without any of the typestext,fax,cell,video,pager,textphone
if not found, parse the second most preferredTELproperty with typesvoiceandwork
if not found, parse the second most preferredTELproperty with typesworkand without any of the typestext,fax,cell,video,pager,textphone - For the
telephone_home1attribute, the most preferredTELproperty with typesvoiceand typehomeis parsed
if not found, parse the most preferredTELproperty with typehomeand without any of the typestext,fax,cell,video,pager,textphone - For the
telephone_home2attribute, the most preferredTELproperty with typesvoice,homeandx-2ndis parsed
if not found, parse the most preferredTELproperty with typeshomeandx-2ndand without any of the typestext,fax,cell,video,pager,textphone
if not found, parse the second most preferredTELproperty with typesvoiceandhome
if not found, parse the second most preferredTELproperty with typeshomeand without any of the typestext,fax,cell,video,pager,textphone - For the
telephone_otherattribute, the most preferredTELproperty with typex-otheris parsed
- Generally, if no matching vCard
- During export, the OX contact telephone numbers are serialized to a previously saved original vCard as follows:
- Generally, if the OX telephone property is not set anymore, the corresponding vCard property is deleted during the update
- For the
telephone_pagerattribute, the most preferredTELproperty with typepageris updated
if not found, add a newTELproperty with typepager - For the
telephone_ttytddattribute, the most preferredTELproperty with typetextphoneis updated
if not found, add a newTELproperty with typetextphone - For the
telephone_isdnattribute, the most preferredTELproperty with typeisdnis updated
if not found, add a newTELproperty with typeisdn - For the
telephone_carattribute, the most preferredTELproperty with typecaris updated
if not found, add a newTELproperty with typecar - For the
cellular_telephone1attribute, the most preferredTELproperty with typecellis updated
if not found, add a newTELproperty with typecell - For the
cellular_telephone2attribute, the most preferredTELproperty with typescellandx-2ndis updated
if not found, parse the update the most preferredTELproperty with typecelland add the typex-2nd
if not found, add a newTELproperty with typescellandx-2nd - For the
telephone_callbackattribute, the most preferredTELproperty with typex-callbackis updated
if not found, add a newTELproperty with typex-callback - For the
telephone_companyattribute, the most preferredTELproperty with typex-companyis updated
if not found, add a newTELproperty with typex-company - For the
telephone_assistantattribute, the most preferredTELproperty with typex-assistantis updated
if not found, add a newTELproperty with typex-assistant - For the
telephone_ipattribute, the most preferredTELproperty with typex-ipis updated
if not found, add a newTELproperty with typex-ip - For the
telephone_radioattribute, the most preferredTELproperty with typex-radiois updated
if not found, add a newTELproperty with typex-radio - For the
telephone_primaryattribute, the most preferredTELproperty with typex-primaryis updated
if not found, add a newTELproperty with typex-primary - For the
fax_businessattribute, the most preferredTELproperty with typesfaxand typeworkis updated
if not found, add a newTELproperty with typesfaxand `work - For the
fax_homeattribute, the most preferredTELproperty with typesfaxand typehomeis updated
if not found, add a newTELproperty with typesfaxandhome - For the
fax_otherattribute, the most preferredTELproperty with typesfaxand typex-otheris updated
if not found, add a newTELproperty with typesfaxandx-other - For the
telephone_business1attribute, the most preferredTELproperty with typesvoiceand typeworkis updated
if not found, update the most preferredTELproperty with typeworkand without any of the typestext,fax,cell,video,pager,textphone
if not found, add a newTELproperty with typesvoice,workandpref - For the
telephone_business2attribute, the most preferredTELproperty with typesvoice,workandx-2ndis updated
if not found, update the most preferredTELproperty with typesworkandx-2ndand without any of the typestext,fax,cell,video,pager,textphone
if not found, update the second most preferredTELproperty with typesvoiceandworkand add the typex-2nd
if not found, update the second most preferredTELproperty with typesworkand without any of the typestext,fax,cell,video,pager,textphoneand add the typex-2nd
if not found, add a newTELproperty with typesvoice,workandx-2nd - For the
telephone_home1attribute, the most preferredTELproperty with typesvoiceand typehomeis updated
if not found, update the most preferredTELproperty with typehomeand without any of the typestext,fax,cell,video,pager,textphone
if not found, add a newTELproperty with typesvoice,homeandpref - For the
telephone_home2attribute, the most preferredTELproperty with typesvoice,homeandx-2ndis updated
if not found, update the most preferredTELproperty with typeshomeandx-2ndand without any of the typestext,fax,cell,video,pager,textphone
if not found, update the second most preferredTELproperty with typesvoiceandhomeand add the typex-2nd
if not found, update the second most preferredTELproperty with typeshomeand without any of the typestext,fax,cell,video,pager,textphoneand add the typex-2nd
if not found, add a newTELproperty with typesvoice,homeandx-2nd - For the
telephone_otherattribute, the most preferredTELproperty with typex-otheris updated
if not found, add a newTELproperty with typesvoiceandx-other
(Structured) name
- https://tools.ietf.org/html/rfc6350#section-6.2.2
- OX contacts stores name-related properties at the fields:
first_name,last_name,second_name,suffixandtitle - In vCards, the structured property
Nstores the different parts of a name, which arefamily,given,additional,prefixesandsuffixes - The parts are mapped between OX contacts and vCards as follows:
last_name<->familyfirst_name<->givensecond_name<->additionaltitle<->prefixessuffix<->suffixes
- During import, the mapping to the vCard
Nproperty is based on the following rules:- If there's no
Nproperty in the vCard, all name-related properties of the contact are deleted - Otherwise, the properties are imported based on the above mapping, with the multi-values in
prefixesandsuffixesbeing concatenated into the corresponding OX contact propertiestitleandsuffix
- If there's no
- During export, the OX contact name properties are serialized to a previously saved original vCard as follows:
- If no single OX property that forms the structured name is set anymore, the corresponding vCard property is deleted during the update
- Otherwise, the names serialized into a new or already existing
Nproperty following the above mapping rules, with the multi-value propertiesprefixesandsuffixesbeing filled with thetitleandsuffixvalues, split by whitespace