FileDocCategorySizeDatePackage
VCalParser_V20.javaAPI DocAndroid 1.5 API7018Wed May 06 22:41:56 BST 2009android.syncml.pim.vcalendar

VCalParser_V20

public class VCalParser_V20 extends VCalParser_V10

Fields Summary
private static final String
V10LINEBREAKER
private static final HashSet
acceptableComponents
private static final HashSet
acceptableV20Props
private boolean
hasTZ
private String[]
lines
private int
index
Constructors Summary
Methods Summary
public booleanparse(java.io.InputStream is, java.lang.String encoding, android.syncml.pim.VBuilder builder)


    
           
              
        // get useful info for android calendar, and alter to vcal 1.0
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
        String scStr = new String(bytes);
        StringBuilder v10str = new StringBuilder("");

        lines = splitProperty(scStr);
        index = 0;

        if ("BEGIN:VCALENDAR".equals(lines[index]))
            v10str.append("BEGIN:VCALENDAR" + V10LINEBREAKER);
        else
            return false;
        index++;
        if (false == parseV20Calbody(lines, v10str)
                || index > lines.length - 1)
            return false;

        if (lines.length - 1 == index && "END:VCALENDAR".equals(lines[index]))
            v10str.append("END:VCALENDAR" + V10LINEBREAKER);
        else
            return false;

        return super.parse(
                // use vCal 1.0 parser
                new ByteArrayInputStream(v10str.toString().getBytes()),
                encoding, builder);
    
private booleanparseV20Calbody(java.lang.String[] lines, java.lang.StringBuilder buffer)
Parse and pick acceptable iCalendar body and translate it to calendarV1.0 format.

param
lines iCalendar components/properties line list.
param
buffer calendarV10 format string buffer
return
true for success, or false

        try {
            while (!"VERSION:2.0".equals(lines[index]))
                index++;
            buffer.append("VERSION:1.0" + V10LINEBREAKER);

            index++;
            for (; index < lines.length - 1; index++) {
                String[] keyAndValue = lines[index].split(":", 2);
                String key = keyAndValue[0];
                String value = keyAndValue[1];

                if ("BEGIN".equals(key.trim())) {
                    if (!key.equals(key.trim()))
                        return false; // MUST be "BEGIN:componentname"
                    index++;
                    if (false == parseV20Component(value, buffer))
                        return false;
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            return false;
        }

        return true;
    
private booleanparseV20Component(java.lang.String compName, java.lang.StringBuilder buffer)
Parse and pick acceptable calendar V2.0's component and translate it to V1.0 format.

param
compName component name
param
buffer calendarV10 format string buffer
return
true for success, or false
throws
ArrayIndexOutOfBoundsException

        String endTag = "END:" + compName;
        String[] propAndValue;
        String propName, value;

        if (acceptableComponents.contains(compName)) {
            if ("VEVENT".equals(compName) || "VTODO".equals(compName)) {
                buffer.append("BEGIN:" + compName + V10LINEBREAKER);
                while (!endTag.equals(lines[index])) {
                    propAndValue = lines[index].split(":", 2);
                    propName = propAndValue[0].split(";", 2)[0];
                    value = propAndValue[1];

                    if ("".equals(lines[index]))
                        buffer.append(V10LINEBREAKER);
                    else if (acceptableV20Props.contains(propName)) {
                        buffer.append(propName + ":" + value + V10LINEBREAKER);
                    } else if ("BEGIN".equals(propName.trim())) {
                        // MUST be BEGIN:VALARM
                        if (propName.equals(propName.trim())
                                && "VALARM".equals(value)) {
                            buffer.append("AALARM:default" + V10LINEBREAKER);
                            while (!"END:VALARM".equals(lines[index]))
                                index++;
                        } else
                            return false;
                    }
                    index++;
                } // end while
                buffer.append(endTag + V10LINEBREAKER);
            } else if ("VALARM".equals(compName)) { // VALARM component MUST
                // only appear within either VEVENT or VTODO
                return false;
            } else if ("VTIMEZONE".equals(compName)) {
                do {
                    if (false == hasTZ) {// MUST only have 1 time TZ property
                        propAndValue = lines[index].split(":", 2);
                        propName = propAndValue[0].split(";", 2)[0];

                        if ("TZOFFSETFROM".equals(propName)) {
                            value = propAndValue[1];
                            buffer.append("TZ" + ":" + value + V10LINEBREAKER);
                            hasTZ = true;
                        }
                    }
                    index++;
                } while (!endTag.equals(lines[index]));
            } else
                return false;
        } else {
            while (!endTag.equals(lines[index]))
                index++;
        }

        return true;
    
private java.lang.String[]splitProperty(java.lang.String scStr)
split ever property line to String[], not split folding line.

        /*
         * Property splitted by \n, and unfold folding lines by removing
         * CRLF+LWSP-char
         */
        scStr = scStr.replaceAll("\r\n", "\n").replaceAll("\n ", "")
                .replaceAll("\n\t", "");
        String[] strs = scStr.split("\n");
        return strs;