VNodeBuilder.java revision 4199c54c527330ac01699b176e7bca186a3aa3a4
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 */
164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapackage com.android.vcard.tests.test_utils;
174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentValues;
194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Base64;
204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.CharsetUtils;
214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Log;
224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport com.android.vcard.VCardConfig;
244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport com.android.vcard.VCardInterpreter;
254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport com.android.vcard.VCardUtils;
264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.io.UnsupportedEncodingException;
284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.nio.ByteBuffer;
294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.nio.charset.Charset;
304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList;
314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List;
324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/**
344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p>
354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The class storing the parse result to custom datastruct:
364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * {@link VNode}, and {@link PropertyNode}.
374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Maybe several vcard instance, so use vNodeList to store.
384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p>
394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p>
404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * This is called VNode, not VCardNode, since it was used for expressing vCalendar (iCal).
414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p>
424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/* package */ class VNodeBuilder implements VCardInterpreter {
444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    static private String LOG_TAG = "VNodeBuilder";
454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public List<VNode> vNodeList = new ArrayList<VNode>();
474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private int mNodeListPos = 0;
484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private VNode mCurrentVNode;
494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private PropertyNode mCurrentPropNode;
504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mCurrentParamType;
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;
614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private boolean mStrictLineBreakParsing;
634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke 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
784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void start() {
794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void end() {
824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Note: I guess that this code assumes the Record may nest like this:
854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // START:VPOS
864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // ...
874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // START:VPOS2
884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // ...
894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // END:VPOS2
904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // ...
914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // END:VPOS
924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    //
934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // However the following code has a bug.
944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // When error occurs after calling startRecord(), the entry which is probably
954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // the cause of the error remains to be in vNodeList, while endRecord() is not called.
964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    //
974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // I leave this code as is since I'm not familiar with vcalendar specification.
984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // But I believe we should refactor this code in the future.
994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Until this, the last entry has to be removed when some error occurs.
1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void startEntry() {
1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        VNode vnode = new VNode();
1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        vnode.parseStatus = 1;
1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        vnode.VName = "VCARD";
1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // I feel this should be done in endRecord(), but it cannot be done because of
1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // the reason above.
1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        vNodeList.add(vnode);
1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNodeListPos = vNodeList.size() - 1;
1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentVNode = vNodeList.get(mNodeListPos);
1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void endEntry() {
1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        VNode endNode = vNodeList.get(mNodeListPos);
1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        endNode.parseStatus = 0;
1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        while(mNodeListPos > 0){
1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNodeListPos--;
1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if((vNodeList.get(mNodeListPos)).parseStatus == 1)
1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentVNode = vNodeList.get(mNodeListPos);
1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void startProperty() {
1234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentPropNode = new PropertyNode();
1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void endProperty() {
1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentVNode.propList.add(mCurrentPropNode);
1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void propertyName(String name) {
1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentPropNode.propName = name;
1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void propertyGroup(String group) {
1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentPropNode.propGroupSet.add(group);
1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void propertyParamType(String type) {
1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentParamType = type;
1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void propertyParamValue(String value) {
1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mCurrentParamType == null ||
1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mCurrentParamType.equalsIgnoreCase("TYPE")) {
1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.paramMap_TYPE.add(value);
1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.paramMap.put(mCurrentParamType, value);
1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentParamType = null;
1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String encodeString(String originalString, String targetCharset) {
1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mSourceCharset.equalsIgnoreCase(targetCharset)) {
1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return originalString;
1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        Charset charset = Charset.forName(mSourceCharset);
1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ByteBuffer byteBuffer = charset.encode(originalString);
1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // byteBuffer.array() "may" return byte array which is larger than
1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // byteBuffer.remaining(). Here, we keep on the safe side.
1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        byte[] bytes = new byte[byteBuffer.remaining()];
1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        byteBuffer.get(bytes);
1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        try {
1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return new String(bytes, targetCharset);
1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } catch (UnsupportedEncodingException e) {
1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return null;
1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String handleOneValue(String value, String targetCharset, String encoding) {
1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (encoding != null) {
1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            encoding = encoding.toUpperCase();
1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (encoding.equals("BASE64") || encoding.equals("B")) {
1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Assume BASE64 is used only when the number of values is 1.
1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mCurrentPropNode.propValue_bytes = Base64.decode(value.getBytes(), Base64.NO_WRAP);
1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return value;
1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else if (encoding.equals("QUOTED-PRINTABLE")) {
1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return VCardUtils.parseQuotedPrintable(
1804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        value, mStrictLineBreakParsing, mSourceCharset, targetCharset);
1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Unknown encoding. Fall back to default.
1834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return encodeString(value, targetCharset);
1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void propertyValues(List<String> values) {
1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (values == null || values.size() == 0) {
1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.propValue_bytes = null;
1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.propValue_vector.clear();
1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.propValue_vector.add("");
1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.propValue = "";
1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ContentValues paramMap = mCurrentPropNode.paramMap;
1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        String targetCharset = CharsetUtils.nameForDefaultVendor(paramMap.getAsString("CHARSET"));
1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        String encoding = paramMap.getAsString("ENCODING");
2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (targetCharset == null || targetCharset.length() == 0) {
2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            targetCharset = mTargetCharset;
2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (String value : values) {
2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mCurrentPropNode.propValue_vector.add(
2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    handleOneValue(value, targetCharset, encoding));
2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mCurrentPropNode.propValue = listToString(mCurrentPropNode.propValue_vector);
2114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String listToString(List<String> list){
2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size = list.size();
2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 1) {
2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder typeListB = new StringBuilder();
2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String type : list) {
2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                typeListB.append(type).append(";");
2194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int len = typeListB.length();
2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (len > 0 && typeListB.charAt(len - 1) == ';') {
2224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return typeListB.substring(0, len - 1);
2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return typeListB.toString();
2254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (size == 1) {
2264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return list.get(0);
2274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
2284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return "";
2294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getResult(){
2334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        throw new RuntimeException("Not supported");
2344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}
236