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.Log;
264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.io.UnsupportedEncodingException;
284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.nio.ByteBuffer;
294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.nio.charset.Charset;
304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList;
311de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Collection;
324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List;
331de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawaimport java.util.Map;
344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/**
364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p>
374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The class storing the parse result to custom datastruct:
384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * {@link VNode}, and {@link PropertyNode}.
394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Maybe several vcard instance, so use vNodeList to store.
404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p>
414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p>
424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * This is called VNode, not VCardNode, since it was used for expressing vCalendar (iCal).
434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p>
444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
451680191a2a208fd61123810a88ce9def83e222baDaisuke Miyakawapublic class VNodeBuilder implements VCardInterpreter {
4648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    private static String LOG_TAG = "VNodeBuilder";
4748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
4848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    private List<VNode> mVNodeList = new ArrayList<VNode>();
494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private VNode mCurrentVNode;
504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * The charset using which VParser parses the text.
534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mSourceCharset;
554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * The charset with which byte array is encoded to String.
584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mTargetCharset;
6048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private boolean mStrictLineBreakParsing;
6248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VNodeBuilder() {
644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(VCardConfig.DEFAULT_IMPORT_CHARSET, false);
654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VNodeBuilder(String targetCharset, boolean strictLineBreakParsing) {
684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mSourceCharset = VCardConfig.DEFAULT_INTERMEDIATE_CHARSET;
694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (targetCharset != null) {
704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mTargetCharset = targetCharset;
714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mTargetCharset = VCardConfig.DEFAULT_IMPORT_CHARSET;
734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mStrictLineBreakParsing = strictLineBreakParsing;
754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    @Override
781de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa    public void onVCardStarted() {
794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    @Override
821de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa    public void onVCardEnded() {
834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    @Override
861de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa    public void onEntryStarted() {
8748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        mCurrentVNode = new VNode();
8848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        mVNodeList.add(mCurrentVNode);
894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    @Override
921de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa    public void onEntryEnded() {
9348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        int lastIndex = mVNodeList.size() - 1;
9448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        mVNodeList.remove(lastIndex--);
9548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        mCurrentVNode = lastIndex >= 0 ? mVNodeList.get(lastIndex) : null;
964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    @Override
991de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa    public void onPropertyCreated(VCardProperty property) {
1001de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        // TODO: remove PropertyNode.
1011de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        PropertyNode propNode = new PropertyNode();
1021de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        propNode.propName = property.getName();
1031de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        List<String> groupList = property.getGroupList();
1041de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        if (groupList != null) {
1051de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propGroupSet.addAll(groupList);
1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1071de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        Map<String, Collection<String>> propertyParameterMap = property.getParameterMap();
1081de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        for (String paramType : propertyParameterMap.keySet()) {
1091de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            Collection<String> paramValueList = propertyParameterMap.get(paramType);
1101de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            if (paramType.equalsIgnoreCase("TYPE")) {
1111de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa                propNode.paramMap_TYPE.addAll(paramValueList);
1121de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            } else {
1131de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa                for (String paramValue : paramValueList) {
1141de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa                    propNode.paramMap.put(paramType, paramValue);
1151de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa                }
1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
1191de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        // TODO: just redundant
12048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
1211de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        if (property.getRawValue() == null) {
1221de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue_bytes = null;
1231de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue_vector.clear();
1241de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue_vector.add("");
1251de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue = "";
1261de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            return;
1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
1291de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        final List<String> values = property.getValueList();
1301de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        if (values == null || values.size() == 0) {
1311de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue_vector.clear();
1321de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue_vector.add("");
1331de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue = "";
1341de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        } else {
1351de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue_vector.addAll(values);
1361de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa            propNode.propValue = listToString(propNode.propValue_vector);
1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1381de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        propNode.propValue_bytes = property.getByteValue();
1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1401de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa        mCurrentVNode.propList.add(propNode);
1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String listToString(List<String> list){
1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size = list.size();
1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 1) {
1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder typeListB = new StringBuilder();
1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String type : list) {
1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                typeListB.append(type).append(";");
1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int len = typeListB.length();
1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (len > 0 && typeListB.charAt(len - 1) == ';') {
1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return typeListB.substring(0, len - 1);
1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return typeListB.toString();
1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (size == 1) {
1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return list.get(0);
1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return "";
1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getResult(){
1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        throw new RuntimeException("Not supported");
1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
16648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public List<VNode> getVNodeList() {
16748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return mVNodeList;
16848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
16948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
17048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public VNode getCurrentVNode() {
17148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return mCurrentVNode;
17248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}
174