/* * Funambol is a mobile platform developed by Funambol, Inc. * Copyright (C) 2009 Funambol, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "Powered by Funambol" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by Funambol". */ package com.funambol.common.pim.vcard; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import com.funambol.common.pim.ArrayList; import com.funambol.util.StringUtil; import javax.microedition.pim.PIM; import javax.microedition.pim.PIMList; import javax.microedition.pim.ContactList; import javax.microedition.pim.PIMItem; import javax.microedition.pim.Contact; import com.funambol.util.Log; import com.funambol.util.ConsoleAppender; import junit.framework.*; /** * This is a ent-to-end test for the vCard parsing/formatting process. */ public class VCardEndToEndTest extends TestCase { public VCardEndToEndTest(String name) { super(name); Log.initLog(new ConsoleAppender()); Log.setLogLevel(Log.ERROR); } public void setUp() { Log.setLogLevel(Log.ERROR); } public void tearDown() { } /** * Iterate all the vCard test cases */ public void disabledtestEndToEnd() throws Throwable { if (Log.isLoggable(Log.DEBUG)) { Log.debug("--- endToEndTest ---"); } InputStream cardsStream = getClass().getResourceAsStream( "/res/vcard/goodvcards.txt"); ContactList cList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST,PIM.READ_WRITE); String vcard; do { vcard = VCardTestUtils.getNextVCardItem(cardsStream); if (vcard.length() > 0) { Contact item = cList.createContact(); singleVCardTest(vcard, item); } } while (vcard.length() > 0); } /** * Test flow for each test case: * 1 - parse vCard item -> PIMItem * 2 - format PIMItem -> vCard item * 3 - order vCard items fields of the items coming from points 1 and 2 * 4 - compare the vCard strings */ public void singleVCardTest(String originalVcard, Contact pimItem) throws Throwable { // parsing vCard ByteArrayInputStream is = new ByteArrayInputStream(originalVcard.getBytes()); VCardSyntaxParserListener lis = new ContactParserListener(pimItem, false); VCardSyntaxParser parser = new VCardSyntaxParser(is); parser.setListener(lis); parser.parse(); // formatting vCard VCardFormatter formatter = new VCardFormatter(); ByteArrayOutputStream ostream = new ByteArrayOutputStream(); formatter.format(pimItem, ostream, false); String formattedVcard = ostream.toString(); // ordering formattedVcard = orderVCard(formattedVcard); originalVcard = orderVCard(originalVcard); // comparing if(!formattedVcard.equals(originalVcard)) { Log.error("[VCalendarEndToEndTest.singleVCardTest] formattedVcard: "); Log.error(formattedVcard); Log.error("[VCalendarEndToEndTest.singleVCardTest] originalVcard: "); Log.error(originalVcard); } assertTrue(formattedVcard.equals(originalVcard)); } /** * Order the iCalendar item fields alphabetically. */ private String orderVCard(String vcard) { ArrayList fields_al = new ArrayList(); String line = ""; String field = ""; while(vcard.length() > 0) { int lbIndex = vcard.indexOf('\n'); if(lbIndex>=0) { String value = vcard.substring(0, lbIndex); if (value != null && value.length() > 0) { line = StringUtil.trim(value, '\r'); } else { line = ""; } vcard = vcard.substring(lbIndex+1); } else { line = StringUtil.trim(vcard, '\n'); line = StringUtil.trim(line, '\r'); vcard = ""; } if (line.length() > 0) { if(line.charAt(0) == com.funambol.common.pim.Utils.FOLDING_INDENT_CHAR) { // this is a multi line field field += line.substring(1); // cut the indent char } else { // We also discard emtpy fields as we are not formatting // all fields boolean skip = false; field = field.trim(); if(!field.equals("") && !field.endsWith(":")) { // We shall skip all the unsupported fields/attributes String upField = field.toUpperCase(); if (upField.startsWith("ORG")) { // The unit is not supported int pos = upField.indexOf(";"); if (pos >= 0) { field = field.substring(0, pos); } } else if (upField.startsWith("TEL") && upField.indexOf("FAX") > 0) { // The home work attr is not supported here int pos = upField.indexOf("HOME"); if (pos > 0) { field = field.substring(0, pos) + "WORK" + field.substring(pos + 4); } } else if (upField.startsWith("TEL") && upField.indexOf("PREF") > 0) { // We ignore the pref because it is not supported int pos = upField.indexOf(";PREF"); if (pos > 0) { field = field.substring(0, pos) + field.substring(pos+5); } } else if (upField.startsWith("ADR")) { int col = upField.indexOf(":"); if (col != -1) { int end = upField.indexOf(";", col); if (end != col + 1) { field = field.substring(0, col + 1) + field.substring(end); } } } if (upField.startsWith("TEL") && upField.indexOf("CELL") > 0 && upField.indexOf("VOICE") > 0) { int pos = upField.indexOf(";VOICE"); if (pos > 0) { field = field.substring(0, pos) + field.substring(pos+6); } } if (upField.startsWith("EMAIL") && upField.indexOf("INTERNET") > 0) { int pos = upField.indexOf(";INTERNET"); if (pos > 0) { field = field.substring(0, pos) + field.substring(pos+9); } } if (upField.startsWith("PHOTO")) { int pos = upField.indexOf(";TYPE=JPEG"); if (pos > 0) { field = field.substring(0, pos) + field.substring(pos+10); } } if (upField.startsWith("TEL") && upField.indexOf("CELL") > 0 && upField.indexOf("HOME") > 0) { skip = true; } if (upField.startsWith("TEL") && upField.indexOf("CELL") > 0 && upField.indexOf("WORK") > 0) { skip = true; } if (upField.startsWith("TEL") && upField.indexOf("VIDEO") > 0) { skip = true; } if (upField.startsWith("X-")) { skip = true; } if (upField.startsWith("LABEL")) { skip = true; } if (upField.startsWith("FN")) { skip = true; } if (upField.startsWith("BDAY")) { skip = true; } // If a field ends with a bunch of ';', we just ignore // them do { if (field.endsWith(";")) { field = field.substring(0, field.length() - 1); } } while(field.endsWith(";")); // The field may be empty now, after removing ; if (field.endsWith(":")) { skip = true; } if (!skip) { fields_al.add(field); } } field = line; } } } // add the latest field fields_al.add(field); // order the fields array list String result = ""; String[] fields = StringUtil.getStringArray(fields_al); for(int i=0; i<fields.length; i++) { for(int j=fields.length-1; j>i; j--) { if(fields[j].compareTo(fields[j-1])<0) { String temp = fields[j]; fields[j] = fields[j-1]; fields[j-1] = temp; } } result += fields[i] + "\r\n"; } return result; } }