All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.ical.values.IcalParseUtil Maven / Gradle / Ivy

The newest version!
// Copyright (C) 2006 Google Inc.
//
// 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 com.google.ical.values;

import com.google.ical.util.DTBuilder;
import com.google.ical.util.TimeUtils;
import java.text.ParseException;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * static functions for parsing ical values.
 *
 * @author [email protected] (Mike Samuel)
 */
public final class IcalParseUtil {

  private static final Pattern DATE_VALUE = Pattern.compile(
      "(\\d{4,})(\\d\\d)(\\d\\d)" +
      "(?:T([0-1]\\d|2[0-3])([0-5]\\d)([0-5]\\d)(Z)?)?");

  /** parses a date of the form yyyymmdd or yyyymmdd'T'hhMMss */
  public static DateValue parseDateValue(String s) throws ParseException {
    return parseDateValue(s, null);
  }

  /**
   * parses a date of the form yyyymmdd or yyyymmdd'T'hhMMss converting from
   * the given timezone to UTC.
   */
  public static DateValue parseDateValue(String s, TimeZone tzid)
      throws ParseException {
    Matcher m = DATE_VALUE.matcher(s);
    if (!m.matches()) { throw new ParseException(s, 0); }
    int year = Integer.parseInt(m.group(1)),
      month = Integer.parseInt(m.group(2)),
      day = Integer.parseInt(m.group(3));
    if (null != m.group(4)) {
      int hour = Integer.parseInt(m.group(4)),
        minute = Integer.parseInt(m.group(5)),
        second = Integer.parseInt(m.group(6));
      boolean utc = null != m.group(7);

      DateValue dv = new DTBuilder(
          year, month, day, hour, minute, second).toDateTime();
      if (!utc && null != tzid) {
        dv = TimeUtils.toUtc(dv, tzid);
      }
      return dv;
    } else {
      return new DTBuilder(year, month, day).toDate();
    }
  }

  /**
   * parse a period value of the form <start>/<end>.
   * This does not yet recognize the <start>/<duration> form.
   */
  public static PeriodValue  parsePeriodValue(String s) throws ParseException {
    return parsePeriodValue(s, null);
  }

  /**
   * parse a period value of the form <start>/<end>, converting
   * from the given timezone to UTC.
   * This does not yet recognize the <start>/<duration> form.
   */
  public static PeriodValue  parsePeriodValue(String s, TimeZone tzid)
      throws ParseException {
    int sep = s.indexOf('/');
    if (sep < 0) { throw new ParseException(s, s.length()); }
    DateValue start = parseDateValue(s.substring(0, sep), tzid),
                end = parseDateValue(s.substring(sep + 1), tzid);
    if ((start instanceof TimeValue) != (end instanceof TimeValue)) {
      throw new ParseException(s, 0);
    }
    try {
      return PeriodValueImpl.create(start, end);
    } catch (IllegalArgumentException ex) {
      throw (ParseException) new ParseException(s, sep + 1).initCause(ex);
    }
  }

  /**
   * unfolds ical content lines as per RFC 2445 section 4.1.
   *
   * 

4.1 Content Lines

* *

The iCalendar object is organized into individual lines of text, called * content lines. Content lines are delimited by a line break, which is a CRLF * sequence (US-ASCII decimal 13, followed by US-ASCII decimal 10). * *

Lines of text SHOULD NOT be longer than 75 octets, excluding the line * break. Long content lines SHOULD be split into a multiple line * representations using a line "folding" technique. That is, a long line can * be split between any two characters by inserting a CRLF immediately * followed by a single linear white space character (i.e., SPACE, US-ASCII * decimal 32 or HTAB, US-ASCII decimal 9). Any sequence of CRLF followed * immediately by a single linear white space character is ignored (i.e., * removed) when processing the content type. */ public static String unfoldIcal(String foldedContentLines) { return IGNORABLE_ICAL_WHITESPACE.matcher(foldedContentLines).replaceAll(""); } private static final Pattern IGNORABLE_ICAL_WHITESPACE = Pattern.compile("(?:\\r\\n?|\\n)[ \t]"); private IcalParseUtil() { // uninstantiable. } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy