/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.syncml.pim.vcard;
import android.syncml.pim.VDataBuilder;
import android.syncml.pim.VParser;
import android.util.Config;
import android.util.Log;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class VCardParser {
// TODO: fix this.
VCardParser_V21 mParser = null;
public final static String VERSION_VCARD21 = "vcard2.1";
public final static String VERSION_VCARD30 = "vcard3.0";
final public static int VERSION_VCARD21_INT = 1;
final public static int VERSION_VCARD30_INT = 2;
String mVersion = null;
static final private String TAG = "VCardParser";
public VCardParser() {
}
/**
* If version not given. Search from vcard string of the VERSION property.
* Then instance mParser to appropriate parser.
*
* @param vcardStr
* the content of vcard data
*/
private void judgeVersion(String vcardStr) {
if (mVersion == null) {// auto judge
int verIdx = vcardStr.indexOf("\nVERSION:");
if (verIdx == -1) // if not have VERSION, v2.1 default
mVersion = VERSION_VCARD21;
else {
String verStr = vcardStr.substring(verIdx, vcardStr.indexOf(
"\n", verIdx + 1));
if (verStr.indexOf("2.1") > 0)
mVersion = VERSION_VCARD21;
else if (verStr.indexOf("3.0") > 0)
mVersion = VERSION_VCARD30;
else
mVersion = VERSION_VCARD21;
}
}
if (mVersion.equals(VERSION_VCARD21))
mParser = new VCardParser_V21();
if (mVersion.equals(VERSION_VCARD30))
mParser = new VCardParser_V30();
}
/**
* To make sure the vcard string has proper wrap character
*
* @param vcardStr
* the string to be checked
* @return string after verified
*/
private String verifyVCard(String vcardStr) {
this.judgeVersion(vcardStr);
// -- indent line:
vcardStr = vcardStr.replaceAll("\r\n", "\n");
String[] strlist = vcardStr.split("\n");
StringBuilder v21str = new StringBuilder("");
for (int i = 0; i < strlist.length; i++) {
if (strlist[i].indexOf(":") < 0) {
if (strlist[i].length() == 0 && strlist[i + 1].indexOf(":") > 0)
v21str.append(strlist[i]).append("\r\n");
else
v21str.append(" ").append(strlist[i]).append("\r\n");
} else
v21str.append(strlist[i]).append("\r\n");
}
return v21str.toString();
}
/**
* Set current version
*
* @param version
* the new version
*/
private void setVersion(String version) {
this.mVersion = version;
}
/**
* Parse the given vcard string
*
* @param vcardStr
* to content to be parsed
* @param builder
* the data builder to hold data
* @return true if the string is successfully parsed, else return false
* @throws VCardException
* @throws IOException
*/
public boolean parse(String vcardStr, VDataBuilder builder)
throws VCardException, IOException {
vcardStr = this.verifyVCard(vcardStr);
boolean isSuccess = mParser.parse(new ByteArrayInputStream(vcardStr
.getBytes()), "US-ASCII", builder);
if (!isSuccess) {
if (mVersion.equals(VERSION_VCARD21)) {
if (Config.LOGD)
Log.d(TAG, "Parse failed for vCard 2.1 parser."
+ " Try to use 3.0 parser.");
this.setVersion(VERSION_VCARD30);
return this.parse(vcardStr, builder);
}
throw new VCardException("parse failed.(even use 3.0 parser)");
}
return true;
}
}
|