001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014: //
015: //All Rights Reserved.
016: package org.columba.addressbook.parser;
017:
018: import java.io.InputStream;
019: import java.io.OutputStream;
020: import java.util.Date;
021: import java.util.Iterator;
022:
023: import net.wimpi.pim.Pim;
024: import net.wimpi.pim.contact.basicimpl.AddressImpl;
025: import net.wimpi.pim.contact.basicimpl.CommunicationsImpl;
026: import net.wimpi.pim.contact.basicimpl.ContactImpl;
027: import net.wimpi.pim.contact.basicimpl.EmailAddressImpl;
028: import net.wimpi.pim.contact.basicimpl.OrganizationImpl;
029: import net.wimpi.pim.contact.basicimpl.OrganizationalIdentityImpl;
030: import net.wimpi.pim.contact.basicimpl.PersonalIdentityImpl;
031: import net.wimpi.pim.contact.io.ContactMarshaller;
032: import net.wimpi.pim.contact.io.ContactUnmarshaller;
033: import net.wimpi.pim.contact.model.Address;
034: import net.wimpi.pim.contact.model.Communications;
035: import net.wimpi.pim.contact.model.EmailAddress;
036: import net.wimpi.pim.contact.model.OrganizationalIdentity;
037: import net.wimpi.pim.contact.model.PersonalIdentity;
038: import net.wimpi.pim.contact.model.PhoneNumber;
039: import net.wimpi.pim.factory.ContactIOFactory;
040:
041: import org.columba.addressbook.model.AddressModel;
042: import org.columba.addressbook.model.ContactModel;
043: import org.columba.addressbook.model.EmailModel;
044: import org.columba.addressbook.model.IContactModel;
045: import org.columba.addressbook.model.IEmailModel;
046: import org.columba.addressbook.model.PhoneModel;
047:
048: /**
049: * Contact data parser for a vCard-standard compliant text/plain file.
050: * <p>
051: * It makes use of the jpim library. Its not really a wrapper. It only
052: * creates a mapping between the jpim data model and our data model.
053: *
054: * @author fdietz
055: */
056: public class VCardParser {
057:
058: /**
059: * Write vcard contact to outpustream.
060: *
061: * @param c
062: * contact data
063: * @param out
064: * outputstream
065: */
066: public static void write(IContactModel c, OutputStream out) {
067: ContactIOFactory ciof = Pim.getContactIOFactory();
068: ContactMarshaller marshaller = ciof.createContactMarshaller();
069: marshaller.setEncoding("UTF-8");
070:
071: // create jpim contact instance
072: net.wimpi.pim.contact.model.Contact exportContact = new ContactImpl();
073:
074: PersonalIdentity identity = new PersonalIdentityImpl();
075: exportContact.setPersonalIdentity(identity);
076:
077: // set sort-string/displayname
078:
079: identity.setSortString(c.getSortString());
080:
081: // set first name
082: identity.setFirstname(c.getGivenName());
083: // set formatted name
084: identity.setFormattedName(c.getFormattedName());
085: // set last name
086:
087: identity.setLastname(c.getFamilyName());
088:
089: identity.setBirthDate(c.getBirthday());
090:
091: // add all additional names (middle names)
092: String[] s = ParserUtil.getArrayOfString(
093: c.getAdditionalNames(), ",");
094: for (int i = 0; i < s.length; i++) {
095: identity.addAdditionalName(s[i]);
096: }
097:
098: // add all nicknames
099: s = ParserUtil.getArrayOfString(c.getNickName(), ",");
100: for (int i = 0; i < s.length; i++) {
101: identity.addNickname(s[i]);
102: }
103:
104: // add all prefixes
105: s = ParserUtil.getArrayOfString(c.getNamePrefix(), ",");
106: for (int i = 0; i < s.length; i++) {
107: identity.addPrefix(s[i]);
108: }
109:
110: // add all suffixes
111: s = ParserUtil.getArrayOfString(c.getNameSuffix(), ",");
112: for (int i = 0; i < s.length; i++) {
113: identity.addSuffix(s[i]);
114: }
115:
116: // set website/homepage
117: exportContact.setURL(c.getHomePage());
118:
119: Communications communications = new CommunicationsImpl();
120: exportContact.setCommunications(communications);
121:
122: // add email addresses
123:
124: Iterator it = c.getEmailIterator();
125: while (it.hasNext()) {
126: IEmailModel model = (IEmailModel) it.next();
127: EmailAddress adr = new EmailAddressImpl();
128: adr.setType(EmailAddress.TYPE_INTERNET);
129: adr.setAddress(model.getAddress());
130: communications.addEmailAddress(adr);
131: }
132:
133: // add all addresses
134: Iterator it2 = c.getAddressIterator();
135: while (it2.hasNext()) {
136: AddressModel model = (AddressModel) it2.next();
137: Address adr = new AddressImpl();
138: adr.setCity(model.getCity());
139: adr.setPostalCode(model.getZipPostalCode());
140: adr.setPostBox(model.getPoBox());
141: adr.setRegion(model.getStateProvinceCounty());
142: adr.setStreet(model.getStreet());
143: adr.setLabel(model.getLabel());
144: exportContact.addAddress(adr);
145: }
146:
147: OrganizationalIdentity organizationalIdentity = new OrganizationalIdentityImpl();
148: exportContact.setOrganizationalIdentity(organizationalIdentity);
149: organizationalIdentity.setOrganization(new OrganizationImpl());
150:
151: // set name of organization
152: organizationalIdentity.getOrganization().setName(
153: c.getOrganisation());
154:
155: exportContact.setNote(c.getNote());
156:
157: // save contact to outputstream
158: marshaller.marshallContact(out, exportContact);
159: }
160:
161: /**
162: * Fill the contact model from the import contact
163: *
164: * @param importContact import contact
165: *
166: * @return contact model
167: *
168: */
169: public static ContactModel fillContactModel(
170: net.wimpi.pim.contact.model.Contact importContact) {
171: ContactModel c = new ContactModel();
172:
173: OrganizationalIdentity organisationalIdentity = importContact
174: .getOrganizationalIdentity();
175:
176: if (importContact.hasPersonalIdentity()) {
177: PersonalIdentity identity = importContact
178: .getPersonalIdentity();
179:
180: // sort-string
181: c.setSortString(identity.getSortString());
182:
183: // list of nick names
184: if (identity.getNicknameCount() > 0)
185: c.setNickName(ParserUtil.getStringOfArray(identity
186: .listNicknames(), ","));
187:
188: // list of prefixes
189: if (identity.listPrefixes().length > 0)
190: c.setNamePrefix(ParserUtil.getStringOfArray(identity
191: .listPrefixes(), ","));
192:
193: c.setFamilyName(identity.getLastname());
194: c.setGivenName(identity.getFirstname());
195:
196: // list of additional names (middle names)
197: if (identity.listAdditionalNames().length > 0)
198: c.setAdditionalNames(ParserUtil.getStringOfArray(
199: identity.listAdditionalNames(), ","));
200:
201: // list of suffices
202: if (identity.listSuffixes().length > 0)
203: c.setNameSuffix(ParserUtil.getStringOfArray(identity
204: .listSuffixes(), ","));
205:
206: // formatted name
207: c.setFormattedName(identity.getFormattedName());
208:
209: // birthday
210: Date birthday = importContact.getPersonalIdentity()
211: .getBirthDate();
212: if (birthday != null)
213: c.setBirthday(birthday);
214:
215: }
216:
217: // url to website/homepage
218: c.setHomePage(importContact.getURL());
219:
220: // email addresses and phone numbers
221: if (importContact.hasCommunications()) {
222: Communications communications = importContact
223: .getCommunications();
224:
225: Iterator it = communications.getEmailAddresses();
226: while (it.hasNext()) {
227: EmailAddress adr = (EmailAddress) it.next();
228:
229: int type = EmailModel.TYPE_WORK;
230: if (adr.isType("HOME"))
231: type = EmailModel.TYPE_HOME;
232: else if (adr.isType("WORK"))
233: type = EmailModel.TYPE_WORK;
234: else if (adr.isType("OTHER"))
235: type = EmailModel.TYPE_OTHER;
236:
237: c.addEmail(new EmailModel(adr.getAddress(), type));
238: }
239:
240: it = communications.getPhoneNumbers();
241: while (it.hasNext()) {
242: PhoneNumber phone = (PhoneNumber) it.next();
243:
244: int type = PhoneModel.TYPE_BUSINESS_PHONE;
245: if (phone.isCar())
246: type = PhoneModel.TYPE_CAR_PHONE;
247: else if (phone.isCellular())
248: type = PhoneModel.TYPE_MOBILE_PHONE;
249: else if (phone.isFax())
250: type = PhoneModel.TYPE_HOME_FAX;
251: else if (phone.isHome())
252: type = PhoneModel.TYPE_HOME_PHONE;
253: else if (phone.isISDN())
254: type = PhoneModel.TYPE_ISDN;
255: else if (phone.isPager())
256: type = PhoneModel.TYPE_PAGER;
257: else if (phone.isWork())
258: type = PhoneModel.TYPE_BUSINESS_PHONE;
259:
260: c.addPhone(new PhoneModel(phone.getNumber(), type));
261: }
262: }
263:
264: // address list
265: if (importContact.listAddresses().length > 0) {
266: // not that the editor ui only supports max of 3 addresses to edit
267: Address[] addresses = importContact.listAddresses();
268: for (int i = 0; i < addresses.length; i++) {
269: Address a = addresses[i];
270:
271: int type = -1;
272: if (a.isHome())
273: type = AddressModel.TYPE_HOME;
274: else if (a.isWork())
275: type = AddressModel.TYPE_WORK;
276: else
277: type = AddressModel.TYPE_OTHER;
278:
279: AddressModel adr = new AddressModel(a.getPostBox(), a
280: .getStreet(), a.getCity(), a.getPostalCode(), a
281: .getRegion(), a.getCountry(), a.getLabel(),
282: type);
283:
284: c.addAddress(adr);
285: }
286: }
287:
288: // name of organisation
289: if (organisationalIdentity != null) {
290: if (organisationalIdentity.hasOrganization())
291: c.setOrganisation(organisationalIdentity
292: .getOrganization().getName());
293:
294: c.setTitle(organisationalIdentity.getTitle());
295: c.setProfession(organisationalIdentity.getRole());
296: }
297:
298: c.setNote(importContact.getNote());
299:
300: // dummy address
301: if (!c.getEmailIterator().hasNext())
302: c.addEmail(new EmailModel("", EmailModel.TYPE_WORK));
303:
304: return c;
305: }
306:
307: /**
308: * Parse vCard contact data from inputstream.
309: *
310: * @param in
311: * inputstream to vCard data
312: * @return contact
313: */
314: public static IContactModel[] read(InputStream in) {
315: ContactIOFactory ciof = Pim.getContactIOFactory();
316: ContactUnmarshaller unmarshaller = ciof
317: .createContactUnmarshaller();
318: unmarshaller.setEncoding("UTF-8");
319:
320: net.wimpi.pim.contact.model.Contact[] importContacts = unmarshaller
321: .unmarshallContacts(in);
322:
323: ContactModel[] contacts = new ContactModel[importContacts.length];
324:
325: for (int i = 0; i < importContacts.length; i++) {
326: contacts[i] = fillContactModel(importContacts[i]);
327: }
328:
329: return contacts;
330: }
331:
332: }
|