11de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa/* 21de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Copyright (C) 2011 The Android Open Source Project 31de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 41de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License"); 51de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * you may not use this file except in compliance with the License. 61de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * You may obtain a copy of the License at 71de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 81de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * http://www.apache.org/licenses/LICENSE-2.0 91de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 101de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software 111de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS, 121de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * See the License for the specific language governing permissions and 141de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * limitations under the License. 151de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa */ 161de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawapackage com.android.vcard; 171de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 181de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport android.util.Log; 191de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 201de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.ArrayList; 211de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Arrays; 221de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Collection; 231de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.HashMap; 241de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.HashSet; 251de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.List; 261de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Map; 271de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 281de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa/** 291de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Represents vCard's property, or logical "one line" of each vCard entry. 301de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 311de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * e.g. 321de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Given a vCard below, objects for <code>N:name</code>, <code>TEL:1111111111</code> are 331de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * "property". 341de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 351de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * <code> 361de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * BEGIN:VCARD 371de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * N:name 381de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * TEL:1111111111 391de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * END:VCARD 401de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * </code> 411de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 421de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * vCard's property has three elements: name, parameter (or param), and value. Name is the name 431de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * of each property. Parameter or param is additional information for the property. Value is one 441de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * or multiple values representing the parameter. 451de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 461de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * e.g. 471de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * <code>N;CHARSET=UTF-8:Joe;Due;M.;Mr.;Ph.D.</code>, has "N" for name, "CHALSET=UTF-8" for param, 481de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * and "Joe;Due;M.;Mr.;Ph.D." for value. 491de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 501de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Usually params are represented as "key=value" pair, but not always 511de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * (The property <code>TEL;WORK;VOICE:(111) 555-1212</code> has two params without key "TYPE", 521de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * which are same as "TYPE=WORK" and "TYPE=VOICE". In vCard 3.0, we can even express them as 531de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * "TYPE=WORK,VOICE"). 541de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * 551de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * Sometimes (not always) value can be separated by semi-colon. In the example above "Joe;Due;;;" 561de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * should be interpreted as five strings: "Joe" (for family name), "Due" (for given name), "M." 571de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * (for middle name), "Mr." (for prefix), and "Ph.D." (for suffix). Whether the value is 581de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa * separable or not is specified by vCard specs. 591de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa */ 601de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawapublic class VCardProperty { 611de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private static final String LOG_TAG = VCardConstants.LOG_TAG; 621de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private String mName; 631de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private List<String> mGroupList; 641de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 651de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private Map<String, Collection<String>> mParameterMap = 661de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa new HashMap<String, Collection<String>>(); 671de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private String mRawValue; 681de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 691de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private List<String> mValueList; 701de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private byte[] mByteValue; 711de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 721de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void setName(String name) { 731de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (mName != null) { 741de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa Log.w(LOG_TAG, String.format("Property name is re-defined " + 751de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa "(existing: %s, requested: %s", mName, name)); 761de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 771de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mName = name; 781de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 791de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 801de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void addGroup(String group) { 811de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (mGroupList == null) { 821de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mGroupList = new ArrayList<String>(); 831de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 841de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mGroupList.add(group); 851de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 861de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 871de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void setParameter(final String paramName, final String paramValue) { 881de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mParameterMap.clear(); 891de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa addParameter(paramName, paramValue); 901de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 911de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 921de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void addParameter(final String paramName, final String paramValue) { 931de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa Collection<String> values; 941de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (!mParameterMap.containsKey(paramName)) { 951de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (paramName.equals("TYPE")) { 961de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa values = new HashSet<String>(); 971de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 981de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa values = new ArrayList<String>(); 991de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1001de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mParameterMap.put(paramName, values); 1011de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 1021de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa values = mParameterMap.get(paramName); 1031de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1041de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa values.add(paramValue); 1051de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1061de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1071de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void setRawValue(String rawValue) { 1081de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mRawValue = rawValue; 1091de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1101de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1111de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa // TODO: would be much better to have translateRawValue() functionality instead of forcing 1121de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa // VCardParserImpl does this job. 1131de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1141de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void setValues(String... propertyValues) { 1151de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mValueList = Arrays.asList(propertyValues); 1161de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1171de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1181de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void setValues(List<String> propertyValueList) { 1191de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mValueList = propertyValueList; 1201de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1211de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1221de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void addValues(String... propertyValues) { 1231de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (mValueList == null) { 1241de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mValueList = Arrays.asList(propertyValues); 1251de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 1261de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mValueList.addAll(Arrays.asList(propertyValues)); 1271de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1281de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1291de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1301de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void addValues(List<String> propertyValueList) { 1311de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (mValueList == null) { 1321de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mValueList = new ArrayList<String>(propertyValueList); 1331de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 1341de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mValueList.addAll(propertyValueList); 1351de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1361de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1371de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1381de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void setByteValue(byte[] byteValue) { 1391de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mByteValue = byteValue; 1401de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1411de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1421de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public String getName() { 1431de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mName; 1441de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1451de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1461de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public List<String> getGroupList() { 1471de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mGroupList; 1481de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1491de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1501de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public Map<String, Collection<String>> getParameterMap() { 1511de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mParameterMap; 1521de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1531de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1541de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public Collection<String> getParameters(String type) { 1551de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mParameterMap.get(type); 1561de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1571de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1581de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public String getRawValue() { 1591de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mRawValue; 1601de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1611de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1621de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public List<String> getValueList() { 1631de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mValueList; 1641de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1651de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1661de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public byte[] getByteValue() { 1671de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return mByteValue; 1681de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1691de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa} 1701de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 1711de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 172