14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/* 24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2009 The Android Open Source Project 34199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * 44199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License"); 54199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * you may not use this file except in compliance with the License. 64199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * You may obtain a copy of the License at 74199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * 84199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * http://www.apache.org/licenses/LICENSE-2.0 94199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * 104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software 114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS, 124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * See the License for the specific language governing permissions and 144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * limitations under the License. 154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 16677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawapackage com.android.vcard.tests.testutils; 174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentValues; 194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport com.android.vcard.VCardEntry; 214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList; 234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Arrays; 244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashSet; 254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List; 264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Set; 274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/** 294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The class representing one property (e.g. "N;ENCODING=UTF-8:family:given:middle:prefix:suffix"). 314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Previously used in main vCard handling code but now exists only for testing. 344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Especially useful for testing parser code (VCardParser), since all properties can be 374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * checked via this class unlike {@link VCardEntry}, which only emits the result of 384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * interpretation of the content of each vCard. We cannot know whether vCard parser or 394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * {@link VCardEntry} is wrong without this class. 404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapublic class PropertyNode { 434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public String propName; 444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public String propValue; 454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public List<String> propValue_vector; 464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** Store value as byte[],after decode. 484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Used when propValue is encoded by something like BASE64, QUOTED-PRINTABLE, etc. 494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public byte[] propValue_bytes; 514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** 534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * param store: key=paramType, value=paramValue 544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Note that currently PropertyNode class does not support multiple param-values 554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * defined in vCard 3.0 (See also RFC 2426). multiple-values are stored as 564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * one String value like "A,B", not ["A", "B"]... 574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * TODO: fix this. 584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public ContentValues paramMap; 604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** Only for TYPE=??? param store. */ 624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public Set<String> paramMap_TYPE; 634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** Store group values. Used only in VCard. */ 654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public Set<String> propGroupSet; 664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public PropertyNode() { 684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa propName = ""; 694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa propValue = ""; 704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa propValue_vector = new ArrayList<String>(); 714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa paramMap = new ContentValues(); 724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa paramMap_TYPE = new HashSet<String>(); 734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa propGroupSet = new HashSet<String>(); 744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public PropertyNode( 774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa String propName, String propValue, List<String> propValue_vector, 784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa byte[] propValue_bytes, ContentValues paramMap, Set<String> paramMap_TYPE, 794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Set<String> propGroupSet) { 804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propName != null) { 814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propName = propName; 824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propName = ""; 844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propValue != null) { 864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propValue = propValue; 874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propValue = ""; 894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propValue_vector != null) { 914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propValue_vector = propValue_vector; 924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propValue_vector = new ArrayList<String>(); 944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propValue_bytes = propValue_bytes; 964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (paramMap != null) { 974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.paramMap = paramMap; 984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.paramMap = new ContentValues(); 1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (paramMap_TYPE != null) { 1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.paramMap_TYPE = paramMap_TYPE; 1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.paramMap_TYPE = new HashSet<String>(); 1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propGroupSet != null) { 1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propGroupSet = propGroupSet; 1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this.propGroupSet = new HashSet<String>(); 1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa @Override 1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public int hashCode() { 1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // vCard may contain more than one same line in one entry, while HashSet or any other 1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // library which utilize hashCode() does not honor that, so intentionally throw an 1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Exception. 1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa throw new UnsupportedOperationException( 1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa "PropertyNode does not provide hashCode() implementation intentionally."); 1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa @Override 1234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public boolean equals(Object obj) { 1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!(obj instanceof PropertyNode)) { 1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa PropertyNode node = (PropertyNode)obj; 1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propName == null || !propName.equals(node.propName)) { 1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (!paramMap_TYPE.equals(node.paramMap_TYPE)) { 1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (!paramMap_TYPE.equals(node.paramMap_TYPE)) { 1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (!propGroupSet.equals(node.propGroupSet)) { 1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propValue_bytes != null && Arrays.equals(propValue_bytes, node.propValue_bytes)) { 1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return true; 1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!propValue.equals(node.propValue)) { 1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // The value in propValue_vector is not decoded even if it should be 1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // decoded by BASE64 or QUOTED-PRINTABLE. When the size of propValue_vector 1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // is 1, the encoded value is stored in propValue, so we do not have to 1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // check it. 1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return (propValue_vector.equals(node.propValue_vector) || 1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa propValue_vector.size() == 1 || 1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa node.propValue_vector.size() == 1); 1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa @Override 1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public String toString() { 1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa StringBuilder builder = new StringBuilder(); 1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("propName: "); 1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(propName); 1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", paramMap: "); 1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(paramMap.toString()); 1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", paramMap_TYPE: ["); 1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa boolean first = true; 1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (String elem : paramMap_TYPE) { 1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (first) { 1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa first = false; 1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", "); 1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append('"'); 1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(elem); 1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append('"'); 1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("]"); 1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!propGroupSet.isEmpty()) { 1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", propGroupSet: ["); 1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa first = true; 1804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (String elem : propGroupSet) { 1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (first) { 1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa first = false; 1834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", "); 1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append('"'); 1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(elem); 1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append('"'); 1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("]"); 1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propValue_vector != null && propValue_vector.size() > 1) { 1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", propValue_vector size: "); 1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(propValue_vector.size()); 1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (propValue_bytes != null) { 1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", propValue_bytes size: "); 1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(propValue_bytes.length); 1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(", propValue: \""); 2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(propValue); 2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("\""); 2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return builder.toString(); 2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa} 206