FileDocCategorySizeDatePackage
ICalendar.javaAPI DocAndroid 5.1 API22768Thu Mar 12 22:22:50 GMT 2015com.android.calendarcommon2

ICalendar

public class ICalendar extends Object
Parses RFC 2445 iCalendar objects.

Fields Summary
private static final String
TAG
Constructors Summary
private ICalendar()

    
Methods Summary
private static com.android.calendarcommon2.ICalendar$ParameterextractParameter(com.android.calendarcommon2.ICalendar$ParserState state)
Extracts the next parameter from the line, if any. If there are no more parameters, returns null.

        String text = state.line;
        int len = text.length();
        Parameter parameter = null;
        int startIndex = -1;
        int equalIndex = -1;
        while (state.index < len) {
            char c = text.charAt(state.index);
            if (c == ':") {
                if (parameter != null) {
                    if (equalIndex == -1) {
                        throw new FormatException("Expected '=' within "
                                + "parameter in " + text);
                    }
                    parameter.value = text.substring(equalIndex + 1,
                                                     state.index);
                }
                return parameter; // may be null
            } else if (c == ';") {
                if (parameter != null) {
                    if (equalIndex == -1) {
                        throw new FormatException("Expected '=' within "
                                + "parameter in " + text);
                    }
                    parameter.value = text.substring(equalIndex + 1,
                                                     state.index);
                    return parameter;
                } else {
                    parameter = new Parameter();
                    startIndex = state.index;
                }
            } else if (c == '=") {
                equalIndex = state.index;
                if ((parameter == null) || (startIndex == -1)) {
                    throw new FormatException("Expected ';' before '=' in "
                            + text);
                }
                parameter.name = text.substring(startIndex + 1, equalIndex);
            } else if (c == '"") {
                if (parameter == null) {
                    throw new FormatException("Expected parameter before '\"' in " + text);
                }
                if (equalIndex == -1) {
                    throw new FormatException("Expected '=' within parameter in " + text);
                }
                if (state.index > equalIndex + 1) {
                    throw new FormatException("Parameter value cannot contain a '\"' in " + text);
                }
                final int endQuote = text.indexOf('"", state.index + 1);
                if (endQuote < 0) {
                    throw new FormatException("Expected closing '\"' in " + text);
                }
                parameter.value = text.substring(state.index + 1, endQuote);
                state.index = endQuote + 1;
                return parameter;
            }
            ++state.index;
        }
        throw new FormatException("Expected ':' before end of line in " + text);
    
private static java.lang.StringextractValue(com.android.calendarcommon2.ICalendar$ParserState state)
Extracts the value ":..." on the current line. The first character must be a ':'.

        String line = state.line;
        if (state.index >= line.length() || line.charAt(state.index) != ':") {
            throw new FormatException("Expected ':' before end of line in "
                    + line);
        }
        String value = line.substring(state.index + 1);
        state.index = line.length() - 1;
        return value;
    
private static java.lang.StringnormalizeText(java.lang.String text)

        // it's supposed to be \r\n, but not everyone does that
        text = text.replaceAll("\r\n", "\n");
        text = text.replaceAll("\r", "\n");

        // we deal with line folding, by replacing all "\n " strings
        // with nothing.  The RFC specifies "\r\n " to be folded, but
        // we handle "\n " and "\r " too because we can get those.
        text = text.replaceAll("\n ", "");

        return text;
    
public static com.android.calendarcommon2.ICalendar$ComponentparseCalendar(java.lang.String text)
Parses the provided text into an iCalendar object. The top-level component must be of type VCALENDAR.

param
text The text to be parsed.
return
The top-level VCALENDAR component.
throws
FormatException Thrown if the text could not be parsed into an iCalendar VCALENDAR object.

        Component calendar = parseComponent(null, text);
        if (calendar == null || !Component.VCALENDAR.equals(calendar.getName())) {
            throw new FormatException("Expected " + Component.VCALENDAR);
        }
        return calendar;
    
public static com.android.calendarcommon2.ICalendar$ComponentparseComponent(com.android.calendarcommon2.ICalendar$Component component, java.lang.String text)
Parses the provided text, adding to the provided component.

param
component The component to which the parsed iCalendar data should be added.
param
text The text to be parsed.
return
The top-level component.
throws
FormatException Thrown if the text could not be parsed as an iCalendar object.

        text = normalizeText(text);
        return parseComponentImpl(component, text);
    
public static com.android.calendarcommon2.ICalendar$ComponentparseComponent(java.lang.String text)
Parses the provided text into an iCalendar component.

param
text The text to be parsed.
return
The top-level component.
throws
FormatException Thrown if the text could not be parsed into an iCalendar component.

        return parseComponent(null, text);
    
private static com.android.calendarcommon2.ICalendar$ComponentparseComponentImpl(com.android.calendarcommon2.ICalendar$Component component, java.lang.String text)
Parses text into an iCalendar component. Parses into the provided component, if not null, or parses into a new component. In the latter case, expects a BEGIN as the first line. Returns the provided or newly created top-level component.

        Component current = component;
        ParserState state = new ParserState();
        state.index = 0;

        // split into lines
        String[] lines = text.split("\n");

        // each line is of the format:
        // name *(";" param) ":" value
        for (String line : lines) {
            try {
                current = parseLine(line, state, current);
                // if the provided component was null, we will return the root
                // NOTE: in this case, if the first line is not a BEGIN, a
                // FormatException will get thrown.   
                if (component == null) {
                    component = current;
                }
            } catch (FormatException fe) {
                if (false) {
                    Log.v(TAG, "Cannot parse " + line, fe);
                }
                // for now, we ignore the parse error.  Google Calendar seems
                // to be emitting some misformatted iCalendar objects.
            }
            continue;
        }
        return component;
    
public static com.android.calendarcommon2.ICalendar$ComponentparseEvent(java.lang.String text)
Parses the provided text into an iCalendar event. The top-level component must be of type VEVENT.

param
text The text to be parsed.
return
The top-level VEVENT component.
throws
FormatException Thrown if the text could not be parsed into an iCalendar VEVENT.

        Component event = parseComponent(null, text);
        if (event == null || !Component.VEVENT.equals(event.getName())) {
            throw new FormatException("Expected " + Component.VEVENT);
        }
        return event;
    
private static com.android.calendarcommon2.ICalendar$ComponentparseLine(java.lang.String line, com.android.calendarcommon2.ICalendar$ParserState state, com.android.calendarcommon2.ICalendar$Component component)
Parses a line into the provided component. Creates a new component if the line is a BEGIN, adding the newly created component to the provided parent. Returns whatever component is the current one (to which new properties will be added) in the parse.

        state.line = line;
        int len = state.line.length();

        // grab the name
        char c = 0;
        for (state.index = 0; state.index < len; ++state.index) {
            c = line.charAt(state.index);
            if (c == ';" || c == ':") {
                break;
            }
        }
        String name = line.substring(0, state.index);

        if (component == null) {
            if (!Component.BEGIN.equals(name)) {
                throw new FormatException("Expected BEGIN");
            }
        }

        Property property;
        if (Component.BEGIN.equals(name)) {
            // start a new component
            String componentName = extractValue(state);
            Component child = new Component(componentName, component);
            if (component != null) {
                component.addChild(child);
            }
            return child;
        } else if (Component.END.equals(name)) {
            // finish the current component
            String componentName = extractValue(state);
            if (component == null ||
                    !componentName.equals(component.getName())) {
                throw new FormatException("Unexpected END " + componentName);
            }
            return component.getParent();
        } else {
            property = new Property(name);
        }

        if (c == ';") {
            Parameter parameter = null;
            while ((parameter = extractParameter(state)) != null) {
                property.addParameter(parameter);
            }
        }
        String value = extractValue(state);
        property.setValue(value);
        component.addProperty(property);
        return component;