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