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 181de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport com.android.vcard.VCardConfig; 191de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport com.android.vcard.VCardInterpreter; 201de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport com.android.vcard.VCardProperty; 211de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport com.android.vcard.VCardUtils; 221de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentValues; 244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Base64; 254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.CharsetUtils; 264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Log; 274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.io.UnsupportedEncodingException; 294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.nio.ByteBuffer; 304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.nio.charset.Charset; 314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList; 321de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Collection; 334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List; 341de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Map; 354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/** 374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The class storing the parse result to custom datastruct: 394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * {@link VNode}, and {@link PropertyNode}. 404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Maybe several vcard instance, so use vNodeList to store. 414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * This is called VNode, not VCardNode, since it was used for expressing vCalendar (iCal). 444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 461680191a2a208fd61123810a88ce9def83e222baDaisuke Miyakawapublic class VNodeBuilder implements VCardInterpreter { 4748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa private static String LOG_TAG = "VNodeBuilder"; 4848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 4948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa private List<VNode> mVNodeList = new ArrayList<VNode>(); 504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private VNode mCurrentVNode; 514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** 534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The charset using which VParser parses the text. 544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private String mSourceCharset; 564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** 584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The charset with which byte array is encoded to String. 594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private String mTargetCharset; 6148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private boolean mStrictLineBreakParsing; 6348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public VNodeBuilder() { 654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa this(VCardConfig.DEFAULT_IMPORT_CHARSET, false); 664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public VNodeBuilder(String targetCharset, boolean strictLineBreakParsing) { 694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mSourceCharset = VCardConfig.DEFAULT_INTERMEDIATE_CHARSET; 704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (targetCharset != null) { 714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mTargetCharset = targetCharset; 724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mTargetCharset = VCardConfig.DEFAULT_IMPORT_CHARSET; 744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mStrictLineBreakParsing = strictLineBreakParsing; 764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 7848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa @Override 791de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void onVCardStarted() { 804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 8248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa @Override 831de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void onVCardEnded() { 844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 8648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa @Override 871de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void onEntryStarted() { 8848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa mCurrentVNode = new VNode(); 8948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa mVNodeList.add(mCurrentVNode); 904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 9248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa @Override 931de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void onEntryEnded() { 9448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa int lastIndex = mVNodeList.size() - 1; 9548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa mVNodeList.remove(lastIndex--); 9648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa mCurrentVNode = lastIndex >= 0 ? mVNodeList.get(lastIndex) : null; 974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 9948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa @Override 1001de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa public void onPropertyCreated(VCardProperty property) { 1011de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa // TODO: remove PropertyNode. 1021de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa PropertyNode propNode = new PropertyNode(); 1031de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propName = property.getName(); 1041de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa List<String> groupList = property.getGroupList(); 1051de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (groupList != null) { 1061de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propGroupSet.addAll(groupList); 1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1081de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa Map<String, Collection<String>> propertyParameterMap = property.getParameterMap(); 1091de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa for (String paramType : propertyParameterMap.keySet()) { 1101de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa Collection<String> paramValueList = propertyParameterMap.get(paramType); 1111de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (paramType.equalsIgnoreCase("TYPE")) { 1121de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.paramMap_TYPE.addAll(paramValueList); 1131de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 1141de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa for (String paramValue : paramValueList) { 1151de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.paramMap.put(paramType, paramValue); 1161de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } 1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 11948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 1201de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa // TODO: just redundant 12148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 1221de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (property.getRawValue() == null) { 1231de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_bytes = null; 1241de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_vector.clear(); 1251de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_vector.add(""); 1261de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue = ""; 1271de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa return; 1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 12948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 1301de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa final List<String> values = property.getValueList(); 1311de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (values == null || values.size() == 0) { 1321de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_vector.clear(); 1331de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_vector.add(""); 1341de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue = ""; 1351de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 1361de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_vector.addAll(values); 1371de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue = listToString(propNode.propValue_vector); 1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1391de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa propNode.propValue_bytes = property.getByteValue(); 1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1411de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mCurrentVNode.propList.add(propNode); 1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private String listToString(List<String> list){ 1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa int size = list.size(); 1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (size > 1) { 1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa StringBuilder typeListB = new StringBuilder(); 1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (String type : list) { 1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa typeListB.append(type).append(";"); 1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa int len = typeListB.length(); 1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (len > 0 && typeListB.charAt(len - 1) == ';') { 1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return typeListB.substring(0, len - 1); 1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return typeListB.toString(); 1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (size == 1) { 1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return list.get(0); 1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return ""; 1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 16248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public String getResult(){ 1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa throw new RuntimeException("Not supported"); 1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 16648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 16748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa public List<VNode> getVNodeList() { 16848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa return mVNodeList; 16948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa } 17048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa 17148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa public VNode getCurrentVNode() { 17248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa return mCurrentVNode; 17348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa } 1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa} 175