diff --git a/CHANGELOG.md b/CHANGELOG.md index 2463ae7a70..9b3b272bb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product= * Replaced [javadns](https://github.com/dnsjava/dnsjava) by [MiniDNS](https://github.com/MiniDNS/minidns) * Added account/identity options to enforce DNSSEC and/or DANE, see [the FAQ](https://github.com/M66B/FairEmail/blob/master/FAQ.md#faq202) * Small improvements and minor bug fixes +* Updated [biweekly](https://github.com/mangstadt/biweekly) * Updated [translations](https://crowdin.com/project/open-source-email) Preview/test versions are [available here](https://bitbucket.org/M66B/fairemail-test/downloads/). diff --git a/app/build.gradle b/app/build.gradle index c2fcaf5dcc..9c1cd74f6f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -553,7 +553,7 @@ dependencies { def openpgp_version = "12.0" def badge_version = "1.1.22" def bugsnag_version = "6.1.0" - def biweekly_version = "0.6.7" + def biweekly_version = "0.6.8" def vcard_version = "0.12.1" def relinker_version = "1.4.5" def markwon_version = "4.6.2" @@ -742,12 +742,12 @@ dependencies { // https://github.com/mangstadt/biweekly // https://mvnrepository.com/artifact/net.sf.biweekly/biweekly - //implementation("net.sf.biweekly:biweekly:$biweekly_version") { - // exclude group: 'com.fasterxml.jackson.core', module: 'jackson-core' - // exclude group: 'com.fasterxml.jackson.core', module: 'jackson-databind' - //} - api "com.fasterxml.jackson.core:jackson-core:2.14.2" - api "com.fasterxml.jackson.core:jackson-databind:2.14.2" + implementation("net.sf.biweekly:biweekly:$biweekly_version") { + exclude group: 'com.fasterxml.jackson.core', module: 'jackson-core' + exclude group: 'com.fasterxml.jackson.core', module: 'jackson-databind' + } + //api "com.fasterxml.jackson.core:jackson-core:2.14.2" + //api "com.fasterxml.jackson.core:jackson-databind:2.14.2" // https://github.com/mangstadt/ez-vcard implementation("com.googlecode.ez-vcard:ez-vcard:$vcard_version") { diff --git a/app/src/main/assets/CHANGELOG.md b/app/src/main/assets/CHANGELOG.md index 2463ae7a70..9b3b272bb3 100644 --- a/app/src/main/assets/CHANGELOG.md +++ b/app/src/main/assets/CHANGELOG.md @@ -12,6 +12,7 @@ For support you can use [the contact form](https://contact.faircode.eu/?product= * Replaced [javadns](https://github.com/dnsjava/dnsjava) by [MiniDNS](https://github.com/MiniDNS/minidns) * Added account/identity options to enforce DNSSEC and/or DANE, see [the FAQ](https://github.com/M66B/FairEmail/blob/master/FAQ.md#faq202) * Small improvements and minor bug fixes +* Updated [biweekly](https://github.com/mangstadt/biweekly) * Updated [translations](https://crowdin.com/project/open-source-email) Preview/test versions are [available here](https://bitbucket.org/M66B/fairemail-test/downloads/). diff --git a/app/src/main/java/biweekly/Biweekly.java b/app/src/main/java/biweekly/Biweekly.java deleted file mode 100644 index ef00b5d5de..0000000000 --- a/app/src/main/java/biweekly/Biweekly.java +++ /dev/null @@ -1,443 +0,0 @@ -package biweekly; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.util.Arrays; -import java.util.Collection; -import java.util.Properties; - -import org.w3c.dom.Document; - -import biweekly.io.chain.ChainingJsonParser; -import biweekly.io.chain.ChainingJsonStringParser; -import biweekly.io.chain.ChainingJsonWriter; -import biweekly.io.chain.ChainingTextParser; -import biweekly.io.chain.ChainingTextStringParser; -import biweekly.io.chain.ChainingTextWriter; -import biweekly.io.chain.ChainingXmlMemoryParser; -import biweekly.io.chain.ChainingXmlParser; -import biweekly.io.chain.ChainingXmlWriter; -import biweekly.io.json.JCalReader; -import biweekly.io.json.JCalWriter; -import biweekly.io.text.ICalReader; -import biweekly.io.text.ICalWriter; -import biweekly.io.xml.XCalDocument; -import biweekly.util.IOUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Contains static chaining factory methods for reading/writing iCalendar - * objects. - *

- * - *

- * Writing an iCalendar object - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * //string
- * String icalString = Biweekly.write(ical).go();
- * 
- * //file
- * File file = new File("meeting.ics");
- * Biweekly.write(ical).go(file);
- * 
- * //output stream
- * OutputStream out = ...
- * Biweekly.write(ical).go(out);
- * out.close();
- * 
- * //writer (should be configured to use UTF-8 encoding)
- * Writer writer = ...
- * Biweekly.write(ical).go(writer);
- * writer.close();
- * 
- * - *

- * Writing multiple iCalendar objects - *

- * - *
- * ICalendar ical1 = new ICalendar();
- * ICalendar ical2 = new ICalendar();
- * 
- * String icalString = Biweekly.write(ical1, ical2).go();
- * 
- * - *

- * Writing an XML-encoded iCalendar object (xCal) - *

- * - *
- * //Call writeXml() instead of write()
- * ICalendar ical = new ICalendar();
- * String xml = Biweekly.writeXml(ical).indent(2).go();
- * 
- * - *

- * Writing a JSON-encoded iCalendar object (jCal) - *

- * - *
- * //Call writeJson() instead of write()
- * ICalendar ical = new ICalendar();
- * String json = Biweekly.writeJson(ical).go();
- * 
- * - *

- * Reading an iCalendar object - *

- * - *
- * ICalendar ical;
- * 
- * //string
- * String icalStr = ...
- * ical = Biweekly.parse(icalStr).first();
- * 
- * //file
- * File file = new File("meeting.ics");
- * ical = Biweekly.parse(file).first();
- * 
- * //input stream
- * InputStream in = ...
- * ical = Biweekly.parse(in).first();
- * in.close();  
- * 
- * //reader (should be configured to read UTF-8)
- * Reader reader = ...
- * ical = Biweekly.parse(reader).first();
- * reader.close();
- * 
- * - *

- * Reading multiple iCalendar objects - *

- * - *
- * String icalStr = ...
- * List<ICalendar> icals = Biweekly.parse(icalStr).all();
- * 
- * - *

- * Reading an XML-encoded iCalendar object (xCal) - *

- * - *
- * //Call parseXml() instead of parse()
- * String xml = ...
- * ICalendar ical = Biweekly.parseXml(xml).first();
- * 
- * - *

- * Reading a JSON-encoded iCalendar object (Cal) - *

- * - *
- * //Call parseJson() instead of parse()
- * String json = ...
- * ICalendar ical = Biweekly.parseJson(json).first();
- * 
- * - *

- * Retrieving parser warnings - *

- * - *
- * String icalStr = ...
- * List<List<String>> warnings = new ArrayList<List<String>>();
- * List<ICalendar> icals = Biweekly.parse(icalStr).warnings(warnings).all();
- * int i = 0;
- * for (List<String> icalWarnings : warnings) {
- *   System.out.println("iCal #" + (i++) + " warnings:");
- *   for (String warning : icalWarnings) {
- *     System.out.println(warning);
- *   }
- * }
- * 
- * - *

- * The methods in this class make use of the following classes. These classes - * can be used if greater control over the read/write operation is required: - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Classes used by this class
ClassesSupports
- * streaming?
Text{@link ICalReader} / {@link ICalWriter}yes
XML{@link XCalDocument}no
JSON{@link JCalReader} / {@link JCalWriter}yes
- * @author Michael Angstadt - */ -public final class Biweekly { - /** - * The version of the library. - */ - public static final String VERSION; - - /** - * The Maven group ID. - */ - public static final String GROUP_ID; - - /** - * The Maven artifact ID. - */ - public static final String ARTIFACT_ID; - - /** - * The project webpage. - */ - public static final String URL; - - static { - InputStream in = null; - try { - in = Biweekly.class.getResourceAsStream("/biweekly/biweekly.properties"); - Properties props = new Properties(); - props.load(in); - - VERSION = props.getProperty("version"); - GROUP_ID = props.getProperty("groupId"); - ARTIFACT_ID = props.getProperty("artifactId"); - URL = props.getProperty("url"); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - IOUtils.closeQuietly(in); - } - } - - /** - * Parses an iCalendar object string. - * @param ical the iCalendar data - * @return chainer object for completing the parse operation - */ - public static ChainingTextStringParser parse(String ical) { - return new ChainingTextStringParser(ical); - } - - /** - * Parses an iCalendar file. - * @param file the iCalendar file - * @return chainer object for completing the parse operation - */ - public static ChainingTextParser> parse(File file) { - return new ChainingTextParser>(file); - } - - /** - * Parses an iCalendar data stream. - * @param in the input stream - * @return chainer object for completing the parse operation - */ - public static ChainingTextParser> parse(InputStream in) { - return new ChainingTextParser>(in); - } - - /** - * Parses an iCalendar data stream. - * @param reader the reader - * @return chainer object for completing the parse operation - */ - public static ChainingTextParser> parse(Reader reader) { - return new ChainingTextParser>(reader); - } - - /** - * Writes multiple iCalendar objects to a data stream. - * @param icals the iCalendar objects to write - * @return chainer object for completing the write operation - */ - public static ChainingTextWriter write(ICalendar... icals) { - return write(Arrays.asList(icals)); - } - - /** - * Writes multiple iCalendar objects to a data stream. - * @param icals the iCalendar objects to write - * @return chainer object for completing the write operation - */ - public static ChainingTextWriter write(Collection icals) { - return new ChainingTextWriter(icals); - } - - /** - * Parses an xCal document (XML-encoded iCalendar objects) from a string. - * @param xml the XML string - * @return chainer object for completing the parse operation - */ - public static ChainingXmlMemoryParser parseXml(String xml) { - return new ChainingXmlMemoryParser(xml); - } - - /** - * Parses an xCal document (XML-encoded iCalendar objects) from a file. - * @param file the XML file - * @return chainer object for completing the parse operation - */ - public static ChainingXmlParser> parseXml(File file) { - return new ChainingXmlParser>(file); - } - - /** - * Parses an xCal document (XML-encoded iCalendar objects) from an input - * stream. - * @param in the input stream - * @return chainer object for completing the parse operation - */ - public static ChainingXmlParser> parseXml(InputStream in) { - return new ChainingXmlParser>(in); - } - - /** - *

- * Parses an xCal document (XML-encoded iCalendar objects) from a reader. - *

- *

- * Note that use of this method is discouraged. It ignores the character - * encoding that is defined within the XML document itself, and should only - * be used if the encoding is undefined or if the encoding needs to be - * ignored for whatever reason. The {@link #parseXml(InputStream)} method - * should be used instead, since it takes the XML document's character - * encoding into account when parsing. - *

- * @param reader the reader - * @return chainer object for completing the parse operation - */ - public static ChainingXmlParser> parseXml(Reader reader) { - return new ChainingXmlParser>(reader); - } - - /** - * Parses an xCal document (XML-encoded iCalendar objects). - * @param document the XML document - * @return chainer object for completing the parse operation - */ - public static ChainingXmlMemoryParser parseXml(Document document) { - return new ChainingXmlMemoryParser(document); - } - - /** - * Writes an xCal document (XML-encoded iCalendar objects). - * @param icals the iCalendar object(s) to write - * @return chainer object for completing the write operation - */ - public static ChainingXmlWriter writeXml(ICalendar... icals) { - return writeXml(Arrays.asList(icals)); - } - - /** - * Writes an xCal document (XML-encoded iCalendar objects). - * @param icals the iCalendar objects to write - * @return chainer object for completing the write operation - */ - public static ChainingXmlWriter writeXml(Collection icals) { - return new ChainingXmlWriter(icals); - } - - /** - * Parses a jCal data stream (JSON-encoded iCalendar objects). - * @param json the JSON data - * @return chainer object for completing the parse operation - */ - public static ChainingJsonStringParser parseJson(String json) { - return new ChainingJsonStringParser(json); - } - - /** - * Parses a jCal data stream (JSON-encoded iCalendar objects). - * @param file the JSON file - * @return chainer object for completing the parse operation - */ - public static ChainingJsonParser> parseJson(File file) { - return new ChainingJsonParser>(file); - } - - /** - * Parses a jCal data stream (JSON-encoded iCalendar objects). - * @param in the input stream - * @return chainer object for completing the parse operation - */ - public static ChainingJsonParser> parseJson(InputStream in) { - return new ChainingJsonParser>(in); - } - - /** - * Parses a jCal data stream (JSON-encoded iCalendar objects). - * @param reader the reader - * @return chainer object for completing the parse operation - */ - public static ChainingJsonParser> parseJson(Reader reader) { - return new ChainingJsonParser>(reader); - } - - /** - * Writes an xCal document (XML-encoded iCalendar objects). - * @param icals the iCalendar object(s) to write - * @return chainer object for completing the write operation - */ - public static ChainingJsonWriter writeJson(ICalendar... icals) { - return writeJson(Arrays.asList(icals)); - } - - /** - * Writes an xCal document (XML-encoded iCalendar objects). - * @param icals the iCalendar objects to write - * @return chainer object for completing the write operation - */ - public static ChainingJsonWriter writeJson(Collection icals) { - return new ChainingJsonWriter(icals); - } - - private Biweekly() { - //hide - } -} diff --git a/app/src/main/java/biweekly/ICalDataType.java b/app/src/main/java/biweekly/ICalDataType.java deleted file mode 100644 index d0960ca94b..0000000000 --- a/app/src/main/java/biweekly/ICalDataType.java +++ /dev/null @@ -1,222 +0,0 @@ -package biweekly; - -import java.util.Collection; - -import biweekly.util.CaseClasses; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the data type of a property's value. - * @author Michael Angstadt - * @see RFC 5545 - * p.29-50 - */ -public class ICalDataType { - private static final CaseClasses enums = new CaseClasses(ICalDataType.class) { - @Override - protected ICalDataType create(String value) { - return new ICalDataType(value); - } - - @Override - protected boolean matches(ICalDataType dataType, String value) { - return dataType.name.equalsIgnoreCase(value); - } - }; - - /** - * Binary data (such as an image or word-processing document). - * @see RFC 5545 - * p.30-1 - * @see vCal 1.0 p.18 - */ - public static final ICalDataType BINARY = new ICalDataType("BINARY"); - - /** - * Boolean value ("true" or "false"). - * @see RFC 5545 - * p.31 - */ - public static final ICalDataType BOOLEAN = new ICalDataType("BOOLEAN"); - - /** - * A URI containing a calendar user address (typically, a "mailto" URI). - * @see RFC 5545 - * p.30-1 - */ - public static final ICalDataType CAL_ADDRESS = new ICalDataType("CAL-ADDRESS"); - - /** - * The property value is located in a separate MIME entity (vCal 1.0 only). - * @see vCal 1.0 p.17 - */ - public static final ICalDataType CONTENT_ID = new ICalDataType("CONTENT-ID"); //1.0 only - - /** - * A date (for example, "2014-03-12"). - * @see RFC 5545 - * p.32 - * @see vCal 1.0 p.16-7 - */ - public static final ICalDataType DATE = new ICalDataType("DATE"); - - /** - * A date/time value (for example, "2014-03-12 13:30:00"). - * @see RFC 5545 - * p.32-4 - * @see vCal 1.0 p.16-7 - */ - public static final ICalDataType DATE_TIME = new ICalDataType("DATE-TIME"); - - /** - * A duration of time (for example, "2 hours, 30 minutes"). - * @see RFC 5545 - * p.35-6 - * @see vCal 1.0 p.17 - */ - public static final ICalDataType DURATION = new ICalDataType("DURATION"); - - /** - * A floating point value (for example, "3.14") - * @see RFC 5545 - * p.36 - */ - public static final ICalDataType FLOAT = new ICalDataType("FLOAT"); - - /** - * An integer value (for example, "42") - * @see RFC 5545 - * p.37 - */ - public static final ICalDataType INTEGER = new ICalDataType("INTEGER"); - - /** - * A period of time (for example, "October 3 through October 5"). - * @see RFC 5545 - * p.37-8 - */ - public static final ICalDataType PERIOD = new ICalDataType("PERIOD"); - - /** - * A recurrence rule (for example, "every Monday at 2pm"). - * @see RFC 5545 - * p.38-45 - * @see vCal 1.0 p.18-23 - */ - public static final ICalDataType RECUR = new ICalDataType("RECUR"); - - /** - * A plain text value. - * @see RFC 5545 - * p.45-6 - */ - public static final ICalDataType TEXT = new ICalDataType("TEXT"); - - /** - * A time value (for example, "2pm"). - * @see RFC 5545 - * p.47-8 - */ - public static final ICalDataType TIME = new ICalDataType("TIME"); - - /** - * A URI value. - * @see RFC 5545 - * p.49 - */ - public static final ICalDataType URI = new ICalDataType("URI"); - - /** - * A URL (for example, "http://example.com/picture.jpg") (vCal 1.0 only). - * @see vCal 1.0 p.17-8 - */ - public static final ICalDataType URL = new ICalDataType("URL"); - - /** - * A UTC-offset (for example, "+0500"). - * @see RFC 5545 - * p.49-50 - */ - public static final ICalDataType UTC_OFFSET = new ICalDataType("UTC-OFFSET"); - - private final String name; - - private ICalDataType(String name) { - this.name = name; - } - - /** - * Gets the name of the data type. - * @return the name of the data type (e.g. "TEXT") - */ - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static ICalDataType find(String value) { - if ("CID".equalsIgnoreCase(value)) { - //"CID" is an alias for "CONTENT-ID" (vCal 1.0, p.17) - return CONTENT_ID; - } - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static ICalDataType get(String value) { - if ("CID".equalsIgnoreCase(value)) { - //"CID" is an alias for "CONTENT-ID" (vCal 1.0, p.17) - return CONTENT_ID; - } - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/ICalVersion.java b/app/src/main/java/biweekly/ICalVersion.java deleted file mode 100644 index 885f4ae609..0000000000 --- a/app/src/main/java/biweekly/ICalVersion.java +++ /dev/null @@ -1,104 +0,0 @@ -package biweekly; - -import com.github.mangstadt.vinnie.SyntaxStyle; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines all supported versions of the iCalendar standard. - * @author Michael Angstadt - */ -public enum ICalVersion { - /** - * The original vCalendar specification. - * @see 1.0 specs - */ - V1_0("1.0", SyntaxStyle.OLD), - - /** - * An older, deprecated version of the iCalendar specification (very similar - * to {@link #V2_0}). - * @see RFC 2445 - */ - V2_0_DEPRECATED("2.0", SyntaxStyle.NEW), - - /** - * The latest iCalendar specification. - * @see RFC 5545 - */ - V2_0("2.0", SyntaxStyle.NEW); - - private final String version; - private final SyntaxStyle syntaxStyle; - - /** - * @param version the version number - */ - ICalVersion(String version, SyntaxStyle syntaxStyle) { - this.version = version; - this.syntaxStyle = syntaxStyle; - } - - /** - * Gets the text representation of this version. - * @return the text representation - */ - public String getVersion() { - return version; - } - - /** - * Gets the syntax style used by this version when writing to a plain-text - * data stream. - * @return the syntax style - */ - public SyntaxStyle getSyntaxStyle() { - return syntaxStyle; - } - - /** - * Gets a {@link ICalVersion} instance based on the given version number. - * @param version the version number (e.g. "2.0") - * @return the object or null if not found - */ - public static ICalVersion get(String version) { - if (V1_0.version.equals(version)) { - return V1_0; - } - if (V2_0.version.equals(version)) { - return V2_0; - } - return null; - } - - @Override - public String toString() { - if (this == V2_0_DEPRECATED) { - return version + " (obsoleted)"; - } - return version; - } -} diff --git a/app/src/main/java/biweekly/ICalendar.java b/app/src/main/java/biweekly/ICalendar.java deleted file mode 100644 index 0fdb72e1a4..0000000000 --- a/app/src/main/java/biweekly/ICalendar.java +++ /dev/null @@ -1,1263 +0,0 @@ -package biweekly; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.xml.transform.TransformerException; - -import biweekly.ValidationWarnings.WarningsGroup; -import biweekly.component.ICalComponent; -import biweekly.component.VEvent; -import biweekly.component.VFreeBusy; -import biweekly.component.VJournal; -import biweekly.component.VTodo; -import biweekly.io.TimezoneInfo; -import biweekly.io.json.JCalWriter; -import biweekly.io.text.ICalWriter; -import biweekly.io.xml.XCalDocument; -import biweekly.io.xml.XCalWriter; -import biweekly.property.CalendarScale; -import biweekly.property.Categories; -import biweekly.property.Color; -import biweekly.property.Description; -import biweekly.property.Geo; -import biweekly.property.ICalProperty; -import biweekly.property.Image; -import biweekly.property.LastModified; -import biweekly.property.Method; -import biweekly.property.Name; -import biweekly.property.ProductId; -import biweekly.property.RefreshInterval; -import biweekly.property.Source; -import biweekly.property.Uid; -import biweekly.property.Url; -import biweekly.util.Duration; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Represents an iCalendar object. - *

- * - *

- * Examples: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * VEvent event = new VEvent();
- * event.setSummary("Team Meeting");
- * Date start = ...;
- * event.setDateStart(start);
- * Date end = ...;
- * event.setDateEnd(end);
- * ical.addEvent(event);
- * 
- * - *

- * Getting timezone information from parsed iCalendar objects: - *

- * - *
- * //The timezone information associated with an ICalendar object is stored in its TimezoneInfo object.
- * ICalReader reader = ...
- * ICalendar ical = reader.readNext();
- * TimezoneInfo tzinfo = ical.getTimezoneInfo();
- * 
- * //You can use this object to get the VTIMEZONE components that were parsed from the input stream.
- * //Note that the VTIMEZONE components will NOT be in the ICalendar object itself
- * Collection<VTimezone> vtimezones = tzinfo.getComponents();
- * 
- * //You can also get the timezone that a specific property was originally formatted in.
- * DateStart dtstart = ical.getEvents().get(0).getDateStart();
- * TimeZone tz = tzinfo.getTimezone(dtstart).getTimeZone();
- * 
- * //This is useful for calculating recurrence rule dates.
- * RecurrenceRule rrule = ical.getEvents(0).getRecurrenceRule();
- * DateIterator it = rrule.getDateIterator(dtstart.getValue(), tz);
- * 
- * - *

- * Setting timezone information when writing iCalendar objects: - *

- * - *
- * //The TimezoneInfo field is used to determine what timezone to format each date-time value in when the ICalendar object is written.
- * //Appropriate VTIMEZONE components are automatically added to the written iCalendar object.
- * ICalendar ical = ...
- * TimezoneInfo tzinfo = ical.getTimezoneInfo();
- * 
- * //biweekly uses the TimezoneAssignment class to define timezones.
- * //This class groups together a Java TimeZone object, which is used to format/parse the date-time values, and its equivalent VTIMEZONE component definition.
- * 
- * //biweekly can auto-generate the VTIMEZONE definitions by downloading them from tzurl.org.
- * //If you want the generated VTIMEZONE components to be tailored for Microsoft Outlook email clients, pass "true" into this method.
- * TimezoneAssignment timezone = TimezoneAssignment.download(TimeZone.getTimeZone("America/New_York"), true);
- * 
- * //Using the TimezoneAssignment class, you can specify what timezone you'd like to format all date-time values in.
- * tzinfo.setDefaultTimezone(timezone);
- * 
- * //You can also specify what timezone to use for individual properties if you want.
- * DateStart dtstart = ical.getEvents(0).getDateStart();
- * TimezoneAssignment losAngeles = TimezoneAssignment.download(TimeZone.getTimeZone("America/Los_Angeles"), true);
- * tzinfo.setTimezone(dtstart, losAngeles);
- * 
- * //The writer object will use this information to determine what timezone to format each date-time value in.
- * //Date-time values are formatted in UTC by default.
- * ICalWriter writer = ...
- * writer.write(ical);
- * 
- * - *

- * For more information on working with timezones, see this page: https://github. - * com/mangstadt/biweekly/wiki/Timezones - *

- * @author Michael Angstadt - * @see RFC 5545 - * @see RFC 2445 - * @see vCal 1.0 - * @see draft-ietf-calext-extensions-01 - */ -public class ICalendar extends ICalComponent { - private ICalVersion version; - private TimezoneInfo tzinfo = new TimezoneInfo(); - - /** - *

- * Creates a new iCalendar object. - *

- *

- * The following properties are added to the component when it is created: - *

- *
    - *
  • {@link ProductId}: Set to a value that represents this library.
  • - *
- */ - public ICalendar() { - setProductId(ProductId.biweekly()); - } - - /** - * Copy constructor. - * @param original the iCalendar object to make a copy of - */ - public ICalendar(ICalendar original) { - super(original); - version = original.version; - } - - /** - * Gets the version of this iCalendar object. - * @return the version - */ - public ICalVersion getVersion() { - return version; - } - - /** - * Sets the version of this iCalendar object. - * @param version the version - */ - public void setVersion(ICalVersion version) { - this.version = version; - } - - /** - *

- * Gets the timezone information associated with this iCalendar object. - *

- *

- * When an iCalendar object is parsed from an input stream, the - * {@link TimezoneInfo} object remembers the original timezone definitions - * that each property was associated with. One use for this is when you want - * to calculate the dates in a recurrence rule. The recurrence rule needs to - * know what timezone its associated date values were originally formatted - * in in order to work correctly. - *

- *

- * When an {@link ICalendar} object is written to an output stream, its - * {@link TimezoneInfo} object tells the writer what timezone to format each - * property in. - *

- * @return the timezone info - */ - public TimezoneInfo getTimezoneInfo() { - return tzinfo; - } - - /** - *

- * Sets the timezone information associated with this iCalendar object. - *

- *

- * When an iCalendar object is parsed from an input stream, the - * {@link TimezoneInfo} object remembers the original timezone definitions - * that each property was associated with. One use for this is when you want - * to calculate the dates in a recurrence rule. The recurrence rule needs to - * know what timezone its associated date values were originally formatted - * in in order to work correctly. - *

- *

- * When an {@link ICalendar} object is written to an output stream, its - * {@link TimezoneInfo} object tells the writer what timezone to format each - * property in. - *

- * @param tzinfo the timezone info (cannot be null) - * @throws NullPointerException if the timezone info object is null - */ - public void setTimezoneInfo(TimezoneInfo tzinfo) { - if (tzinfo == null) { - throw new NullPointerException(); - } - this.tzinfo = tzinfo; - } - - /** - * Gets the name of the application that created the iCalendar object. All - * {@link ICalendar} objects are initialized with a product ID representing - * this library. - * @return the property instance or null if not set - * @see RFC 5545 - * p.78-9 - * @see RFC 2445 - * p.75-6 - * @see vCal 1.0 p.24 - */ - public ProductId getProductId() { - return getProperty(ProductId.class); - } - - /** - * Sets the name of the application that created the iCalendar object. All - * {@link ICalendar} objects are initialized with a product ID representing - * this library. - * @param prodId the property instance or null to remove - * @see RFC 5545 - * p.78-9 - * @see RFC 2445 - * p.75-6 - * @see vCal 1.0 p.24 - */ - public void setProductId(ProductId prodId) { - setProperty(ProductId.class, prodId); - } - - /** - * Sets the application that created the iCalendar object. All - * {@link ICalendar} objects are initialized with a product ID representing - * this library. - * @param prodId a unique string representing the application (e.g. - * "-//Company//Application//EN") or null to remove - * @return the property that was created - * @see RFC 5545 - * p.78-9 - * @see RFC 2445 - * p.75-6 - * @see vCal 1.0 p.24 - */ - public ProductId setProductId(String prodId) { - ProductId property = (prodId == null) ? null : new ProductId(prodId); - setProductId(property); - return property; - } - - /** - * Gets the calendar system that this iCalendar object uses. If none is - * specified, then the calendar is assumed to be in Gregorian format. - * @return the calendar system or null if not set - * @see RFC 5545 - * p.76-7 - * @see RFC 2445 - * p.73-4 - */ - public CalendarScale getCalendarScale() { - return getProperty(CalendarScale.class); - } - - /** - * Sets the calendar system that this iCalendar object uses. If none is - * specified, then the calendar is assumed to be in Gregorian format. - * @param calendarScale the calendar system or null to remove - * @see RFC 5545 - * p.76-7 - * @see RFC 2445 - * p.73-4 - */ - public void setCalendarScale(CalendarScale calendarScale) { - setProperty(CalendarScale.class, calendarScale); - } - - /** - * Gets the type of iTIP - * request that this iCalendar object represents, or the value of the - * "Content-Type" header's "method" parameter if the iCalendar object is - * defined as a MIME message entity. - * @return the property or null if not set - * @see RFC 5546 - * @see RFC 5545 - * p.77-8 - * @see RFC 2445 - * p.74-5 - */ - public Method getMethod() { - return getProperty(Method.class); - } - - /** - * Sets the type of iTIP - * request that this iCalendar object represents, or the value of the - * "Content-Type" header's "method" parameter if the iCalendar object is - * defined as a MIME message entity. - * @param method the property or null to remove - * @see RFC 5546 - * @see RFC 5545 - * p.77-8 - * @see RFC 2445 - * p.74-5 - */ - public void setMethod(Method method) { - setProperty(Method.class, method); - } - - /** - * Sets the type of iTIP - * request that this iCalendar object represents, or the value of the - * "Content-Type" header's "method" parameter if the iCalendar object is - * defined as a MIME message entity. - * @param method the method or null to remove - * @return the property that was created - * @see RFC 5546 - * @see RFC 5545 - * p.77-8 - * @see RFC 2445 - * p.74-5 - */ - public Method setMethod(String method) { - Method property = (method == null) ? null : new Method(method); - setMethod(property); - return property; - } - - /** - *

- * Gets the human-readable name of the calendar as a whole. - *

- *

- * An iCalendar object can only have one name, but multiple {@link Name} - * properties can exist in order to specify the name in multiple languages. - * In this case, each property instance must be assigned a LANGUAGE - * parameter. - *

- * @return the names (any changes made this list will affect the parent - * component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.5 - */ - public List getNames() { - return getProperties(Name.class); - } - - /** - * Sets the human-readable name of the calendar as a whole. - * @param name the name or null to remove - * @see draft-ietf-calext-extensions-01 - * p.5 - */ - public void setName(Name name) { - setProperty(Name.class, name); - } - - /** - * Sets the human-readable name of the calendar as a whole. - * @param name the name or null to remove - * @return the property that was created - * @see draft-ietf-calext-extensions-01 - * p.5 - */ - public Name setName(String name) { - Name property = (name == null) ? null : new Name(name); - setName(property); - return property; - } - - /** - *

- * Assigns a human-readable name to the calendar as a whole. - *

- *

- * An iCalendar object can only have one name, but multiple {@link Name} - * properties can exist in order to specify the name in multiple languages. - * In this case, each property instance must be assigned a LANGUAGE - * parameter. - *

- * @param name the name - * @see draft-ietf-calext-extensions-01 - * p.5 - */ - public void addName(Name name) { - addProperty(name); - } - - /** - *

- * Assigns a human-readable name to the calendar as a whole. - *

- *

- * An iCalendar object can only have one name, but multiple {@link Name} - * properties can exist in order to specify the name in multiple languages. - * In this case, each property instance must be assigned a LANGUAGE - * parameter. - *

- * @param name the name (e.g. "Company Vacation Days") - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.5 - */ - public Name addName(String name) { - Name property = new Name(name); - addProperty(property); - return property; - } - - /** - *

- * Gets the human-readable description of the calendar as a whole. - *

- *

- * An iCalendar object can only have one description, but multiple - * {@link Description} properties can exist in order to specify the - * description in multiple languages. In this case, each property instance - * must be assigned a LANGUAGE parameter. - *

- * @return the descriptions (any changes made this list will affect the - * parent component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public List getDescriptions() { - return getProperties(Description.class); - } - - /** - * Sets the human-readable description of the calendar as a whole. - * @param description the description or null to remove - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public void setDescription(Description description) { - setProperty(Description.class, description); - } - - /** - * Sets the human-readable description of the calendar as a whole. - * @param description the description or null to remove - * @return the property that was created - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public Description setDescription(String description) { - Description property = (description == null) ? null : new Description(description); - setDescription(property); - return property; - } - - /** - *

- * Assigns a human-readable description to the calendar as a whole. - *

- *

- * An iCalendar object can only have one description, but multiple - * {@link Description} properties can exist in order to specify the - * description in multiple languages. In this case, each property instance - * must be assigned a LANGUAGE parameter. - *

- * @param description the description - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public void addDescription(Description description) { - addProperty(description); - } - - /** - *

- * Assigns a human-readable description to the calendar as a whole. - *

- *

- * An iCalendar object can only have one description, but multiple - * {@link Description} properties can exist in order to specify the - * description in multiple languages. In this case, each property instance - * must be assigned a LANGUAGE parameter. - *

- * @param description the description - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public Description addDescription(String description) { - Description property = new Description(description); - addProperty(property); - return property; - } - - /** - * Gets the calendar's unique identifier. - * @return the unique identifier or null if not set - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public Uid getUid() { - return getProperty(Uid.class); - } - - /** - * Sets the calendar's unique identifier. - * @param uid the unique identifier or null to remove - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public void setUid(Uid uid) { - setProperty(Uid.class, uid); - } - - /** - * Sets the calendar's unique identifier. - * @param uid the unique identifier or null to remove - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.6 - */ - public Uid setUid(String uid) { - Uid property = (uid == null) ? null : new Uid(uid); - setUid(property); - return property; - } - - /** - * Gets the date and time that the information in this calendar object was - * last revised. - * @return the last modified time or null if not set - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public LastModified getLastModified() { - return getProperty(LastModified.class); - } - - /** - * Sets the date and time that the information in this calendar object was - * last revised. - * @param lastModified the last modified time or null to remove - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public void setLastModified(LastModified lastModified) { - setProperty(LastModified.class, lastModified); - } - - /** - * Sets the date and time that the information in this calendar object was - * last revised. - * @param lastModified the date and time or null to remove - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public LastModified setLastModified(Date lastModified) { - LastModified property = (lastModified == null) ? null : new LastModified(lastModified); - setLastModified(property); - return property; - } - - /** - * Gets the location of a more dynamic, alternate representation of the - * calendar (such as a website that allows you to interact with the calendar - * data). - * @return the URL or null if not set - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public Url getUrl() { - return getProperty(Url.class); - } - - /** - * Sets the location of a more dynamic, alternate representation of the - * calendar (such as a website that allows you to interact with the calendar - * data). - * @param url the URL or null to remove - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public void setUrl(Url url) { - setProperty(Url.class, url); - } - - /** - * Sets the location of a more dynamic, alternate representation of the - * calendar (such as a website that allows you to interact with the calendar - * data). - * @param url the URL or null to remove - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public Url setUrl(String url) { - Url property = (url == null) ? null : new Url(url); - setUrl(property); - return property; - } - - /** - * Gets the keywords that describe the calendar. - * @return the categories (any changes made this list will affect the parent - * component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public List getCategories() { - return getProperties(Categories.class); - } - - /** - * Adds a list of keywords that describe the calendar. - * @param categories the categories to add - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public void addCategories(Categories categories) { - addProperty(categories); - } - - /** - * Adds a list of keywords that describe the calendar. - * @param categories the categories to add - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public Categories addCategories(String... categories) { - Categories prop = new Categories(categories); - addProperty(prop); - return prop; - } - - /** - * Gets the suggested minimum polling interval for checking for updates to - * the calendar data. - * @return the refresh interval or null if not set - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public RefreshInterval getRefreshInterval() { - return getProperty(RefreshInterval.class); - } - - /** - * Sets the suggested minimum polling interval for checking for updates to - * the calendar data. - * @param refreshInterval the refresh interval or null to remove - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public void setRefreshInterval(RefreshInterval refreshInterval) { - setProperty(RefreshInterval.class, refreshInterval); - } - - /** - * Sets the suggested minimum polling interval for checking for updates to - * the calendar data. - * @param refreshInterval the refresh interval or null to remove - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.7 - */ - public RefreshInterval setRefreshInterval(Duration refreshInterval) { - RefreshInterval property = (refreshInterval == null) ? null : new RefreshInterval(refreshInterval); - setRefreshInterval(property); - return property; - } - - /** - * Gets the location that the calendar data can be refreshed from. - * @return the source or null if not set - * @see draft-ietf-calext-extensions-01 - * p.8 - */ - public Source getSource() { - return getProperty(Source.class); - } - - /** - * Sets the location that the calendar data can be refreshed from. - * @param source the source or null to remove - * @see draft-ietf-calext-extensions-01 - * p.8 - */ - public void setSource(Source source) { - setProperty(Source.class, source); - } - - /** - * Sets the location that the calendar data can be refreshed from. - * @param url the source or null to remove - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.8 - */ - public Source setSource(String url) { - Source property = (url == null) ? null : new Source(url); - setSource(property); - return property; - } - - /** - * Gets the color that clients may use when displaying the calendar (for - * example, a background color). - * @return the color or null if not set - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color getColor() { - return getProperty(Color.class); - } - - /** - * Sets the color that clients may use when displaying the calendar (for - * example, a background color). - * @param color the color or null to remove - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public void setColor(Color color) { - setProperty(Color.class, color); - } - - /** - * Sets the color that clients may use when displaying the calendar (for - * example, a background color). - * @param color the color name (case insensitive) or null to remove. - * Acceptable values are defined in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color setColor(String color) { - Color property = (color == null) ? null : new Color(color); - setColor(property); - return property; - } - - /** - * Gets the images that are associated with the calendar. - * @return the images (any changes made this list will affect the parent - * component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public List getImages() { - return getProperties(Image.class); - } - - /** - * Adds an image that is associated with the calendar. - * @param image the image - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public void addImage(Image image) { - addProperty(image); - } - - /** - * Gets the calendar's events. - * @return the events (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.52-5 - * @see RFC 2445 - * p.52-4 - * @see vCal 1.0 p.13 - */ - public List getEvents() { - return getComponents(VEvent.class); - } - - /** - * Adds an event to the calendar. - * @param event the event - * @see RFC 5545 - * p.52-5 - * @see RFC 2445 - * p.52-4 - * @see vCal 1.0 p.13 - */ - public void addEvent(VEvent event) { - addComponent(event); - } - - /** - * Gets the calendar's to-do tasks. - * @return the to-do tasks (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.55-7 - * @see RFC 2445 - * p.55-6 - * @see vCal 1.0 p.14 - */ - public List getTodos() { - return getComponents(VTodo.class); - } - - /** - * Adds a to-do task to the calendar. - * @param todo the to-do task - * @see RFC 5545 - * p.55-7 - * @see RFC 2445 - * p.55-6 - * @see vCal 1.0 p.14 - */ - public void addTodo(VTodo todo) { - addComponent(todo); - } - - /** - * Gets the calendar's journal entries. - * @return the journal entries (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.57-9 - * @see RFC 2445 - * p.56-7 - */ - public List getJournals() { - return getComponents(VJournal.class); - } - - /** - * Adds a journal entry to the calendar. - * @param journal the journal entry - * @see RFC 5545 - * p.57-9 - * @see RFC 2445 - * p.56-7 - */ - public void addJournal(VJournal journal) { - addComponent(journal); - } - - /** - * Gets the calendar's free/busy entries. - * @return the free/busy entries (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.59-62 - * @see RFC 2445 - * p.58-60 - */ - public List getFreeBusies() { - return getComponents(VFreeBusy.class); - } - - /** - * Adds a free/busy entry to the calendar. - * @param freeBusy the free/busy entry - * @see RFC 5545 - * p.59-62 - * @see RFC 2445 - * p.58-60 - */ - public void addFreeBusy(VFreeBusy freeBusy) { - addComponent(freeBusy); - } - - /** - *

- * Checks this iCalendar object for data consistency problems or deviations - * from the specifications. - *

- *

- * The existence of validation warnings will not prevent the iCalendar - * object from being written to a data stream. Syntactically-correct output - * will still be produced. However, the consuming application may have - * trouble interpreting some of the data due to the presence of these - * warnings. - *

- *

- * These problems can largely be avoided by reading the Javadocs of the - * component and property classes, or by being familiar with the iCalendar - * standard. - *

- * @param version the version to validate against - * @return the validation warnings - */ - public ValidationWarnings validate(ICalVersion version) { - List warnings = validate(new ArrayList(0), version); - return new ValidationWarnings(warnings); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version != ICalVersion.V1_0) { - checkRequiredCardinality(warnings, ProductId.class); - - if (this.components.isEmpty()) { - warnings.add(new ValidationWarning(4)); - } - - if (getProperty(Geo.class) != null) { - warnings.add(new ValidationWarning(44)); - } - } - - checkOptionalCardinality(warnings, Uid.class, LastModified.class, Url.class, RefreshInterval.class, Color.class, Source.class); - checkUniqueLanguages(warnings, Name.class); - checkUniqueLanguages(warnings, Description.class); - } - - private void checkUniqueLanguages(List warnings, Class clazz) { - List properties = getProperties(clazz); - if (properties.size() <= 1) { - return; - } - - Set languages = new HashSet(properties.size()); - for (ICalProperty property : properties) { - String language = property.getParameters().getLanguage(); - if (language != null) { - language = language.toLowerCase(); - } - - boolean added = languages.add(language); - if (!added) { - warnings.add(new ValidationWarning(55, clazz.getSimpleName())); - break; - } - } - } - - /** - *

- * Marshals this iCalendar object to its traditional, plain-text - * representation. - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link ICalWriter} classes - * instead in order to register the scribe classes. - *

- * @return the plain text representation - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - */ - public String write() { - ICalVersion version = (this.version == null) ? ICalVersion.V2_0 : this.version; - return Biweekly.write(this).version(version).go(); - } - - /** - *

- * Marshals this iCalendar object to its traditional, plain-text - * representation. - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link ICalWriter} classes - * instead in order to register the scribe classes. - *

- * @param file the file to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws IOException if there's an problem writing to the file - */ - public void write(File file) throws IOException { - ICalVersion version = (this.version == null) ? ICalVersion.V2_0 : this.version; - Biweekly.write(this).version(version).go(file); - } - - /** - *

- * Marshals this iCalendar object to its traditional, plain-text - * representation. - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link ICalWriter} classes - * instead in order to register the scribe classes. - *

- * @param out the output stream to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws IOException if there's a problem writing to the output stream - */ - public void write(OutputStream out) throws IOException { - ICalVersion version = (this.version == null) ? ICalVersion.V2_0 : this.version; - Biweekly.write(this).version(version).go(out); - } - - /** - *

- * Marshals this iCalendar object to its traditional, plain-text - * representation. - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link ICalWriter} classes - * instead in order to register the scribe classes. - *

- * @param writer the writer to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws IOException if there's a problem writing to the writer - */ - public void write(Writer writer) throws IOException { - ICalVersion version = (this.version == null) ? ICalVersion.V2_0 : this.version; - Biweekly.write(this).version(version).go(writer); - } - - /** - *

- * Marshals this iCalendar object to its XML representation (xCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly}, {@link XCalWriter}, or - * {@link XCalDocument} classes instead in order to register the scribe - * classes. - *

- * @return the XML document - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - */ - public String writeXml() { - return Biweekly.writeXml(this).indent(2).go(); - } - - /** - *

- * Marshals this iCalendar object to its XML representation (xCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly}, {@link XCalWriter}, or - * {@link XCalDocument} classes instead in order to register the scribe - * classes. - *

- * @param file the file to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws TransformerException if there's a problem writing to the file - * @throws IOException if there's a problem opening the file - */ - public void writeXml(File file) throws TransformerException, IOException { - Biweekly.writeXml(this).indent(2).go(file); - } - - /** - *

- * Marshals this iCalendar object to its XML representation (xCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly}, {@link XCalWriter}, or - * {@link XCalDocument} classes instead in order to register the scribe - * classes. - *

- * @param out the output stream to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws TransformerException if there's a problem writing to the output - * stream - */ - public void writeXml(OutputStream out) throws TransformerException { - Biweekly.writeXml(this).indent(2).go(out); - } - - /** - *

- * Marshals this iCalendar object to its XML representation (xCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly}, {@link XCalWriter}, or - * {@link XCalDocument} classes instead in order to register the scribe - * classes. - *

- * @param writer the writer to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws TransformerException if there's a problem writing to the writer - */ - public void writeXml(Writer writer) throws TransformerException { - Biweekly.writeXml(this).indent(2).go(writer); - } - - /** - *

- * Marshals this iCalendar object to its JSON representation (jCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link JCalWriter} classes - * instead in order to register the scribe classes. - *

- * @return the JSON string - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - */ - public String writeJson() { - return Biweekly.writeJson(this).go(); - } - - /** - *

- * Marshals this iCalendar object to its JSON representation (jCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link JCalWriter} classes - * instead in order to register the scribe classes. - *

- * @param file the file to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws IOException if there's a problem writing to the file - */ - public void writeJson(File file) throws IOException { - Biweekly.writeJson(this).go(file); - } - - /** - *

- * Marshals this iCalendar object to its JSON representation (jCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link JCalWriter} classes - * instead in order to register the scribe classes. - *

- * @param out the output stream to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws IOException if there's a problem writing to the output stream - */ - public void writeJson(OutputStream out) throws IOException { - Biweekly.writeJson(this).go(out); - } - - /** - *

- * Marshals this iCalendar object to its JSON representation (jCal). - *

- *

- * If this iCalendar object contains user-defined property or component - * objects, you must use the {@link Biweekly} or {@link JCalWriter} classes - * instead in order to register the scribe classes. - *

- * @param writer the writer to write to - * @throws IllegalArgumentException if this iCalendar object contains - * user-defined property or component objects - * @throws IOException if there's a problem writing to the writer - */ - public void writeJson(Writer writer) throws IOException { - Biweekly.writeJson(this).go(writer); - } - - @Override - protected Map toStringValues() { - Map fields = new HashMap(); - fields.put("version", version); - return fields; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((version == null) ? 0 : version.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) return false; - ICalendar other = (ICalendar) obj; - if (version != other.version) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/Messages.java b/app/src/main/java/biweekly/Messages.java deleted file mode 100644 index e40ae8d06b..0000000000 --- a/app/src/main/java/biweekly/Messages.java +++ /dev/null @@ -1,100 +0,0 @@ -package biweekly; - -import java.text.MessageFormat; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Singleton for accessing the i18n resource bundle. - * @author Michael Angstadt - */ -public enum Messages { - INSTANCE; - - private final transient ResourceBundle messages; - - Messages() { - messages = ResourceBundle.getBundle("biweekly.messages"); - } - - /** - * Gets a validation warning message. - * @param code the message code - * @param args the message arguments - * @return the message - */ - public String getValidationWarning(int code, Object... args) { - return getMessage("validate." + code, args); - } - - /** - * Gets a parser warning message. - * @param code the message code - * @param args the message arguments - * @return the message - */ - public String getParseMessage(int code, Object... args) { - return getMessage("parse." + code, args); - } - - /** - * Gets an exception message. - * @param code the message code - * @param args the message arguments - * @return the message or null if not found - */ - public String getExceptionMessage(int code, Object... args) { - return getMessage("exception." + code, args); - } - - /** - * Builds an {@link IllegalArgumentException} from an exception message. - * @param code the message code - * @param args the message arguments - * @return the exception or null if the message was not found - */ - public IllegalArgumentException getIllegalArgumentException(int code, Object... args) { - String message = getExceptionMessage(code, args); - return (message == null) ? null : new IllegalArgumentException(message); - } - - /** - * Gets a message. - * @param key the message key - * @param args the message arguments - * @return the message or null if not found - */ - public String getMessage(String key, Object... args) { - try { - String message = messages.getString(key); - return MessageFormat.format(message, args); - } catch (MissingResourceException e) { - return null; - } - } -} diff --git a/app/src/main/java/biweekly/ValidationWarning.java b/app/src/main/java/biweekly/ValidationWarning.java deleted file mode 100644 index 6ef1639740..0000000000 --- a/app/src/main/java/biweekly/ValidationWarning.java +++ /dev/null @@ -1,78 +0,0 @@ -package biweekly; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a validation warning. - * @author Michael Angstadt - */ -public class ValidationWarning { - private final Integer code; - private final String message; - - /** - * Creates a new validation warning. - * @param code the warning message code - * @param args the warning message arguments - */ - public ValidationWarning(int code, Object... args) { - this.code = code; - this.message = Messages.INSTANCE.getValidationWarning(code, args); - } - - /** - * Creates a new validation warning. - * @param message the warning message - */ - public ValidationWarning(String message) { - this.code = null; - this.message = message; - } - - /** - * Gets the validation warning code. - * @return the warning code or null if no code was specified - */ - public Integer getCode() { - return code; - } - - /** - * Gets the validation warning message. - * @return the warning message - */ - public String getMessage() { - return message; - } - - @Override - public String toString() { - if (code == null) { - return message; - } - return "(" + code + ") " + message; - } -} diff --git a/app/src/main/java/biweekly/ValidationWarnings.java b/app/src/main/java/biweekly/ValidationWarnings.java deleted file mode 100644 index 2048d97a4e..0000000000 --- a/app/src/main/java/biweekly/ValidationWarnings.java +++ /dev/null @@ -1,289 +0,0 @@ -package biweekly; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import biweekly.ValidationWarnings.WarningsGroup; -import biweekly.component.ICalComponent; -import biweekly.property.ICalProperty; -import biweekly.util.StringUtils; -import biweekly.util.StringUtils.JoinCallback; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Holds the validation warnings of an iCalendar object. - *

- *

- * Examples: - *

- * - *
- * //validate an iCalendar object
- * ValidationWarnings warnings = ical.validate();
- * 
- * //print all warnings to a string:
- * System.out.println(warnings.toString());
- * //sample output:
- * //[ICalendar]: ProductId is not set (it is a required property).
- * //[ICalendar > VEvent > DateStart]: DateStart must come before DateEnd.
- * //[ICalendar > VEvent > VAlarm]: The trigger must specify which date field its duration is relative to.
- * 
- * //iterate over each warnings group
- * //this gives you access to the property/component object and its parent components
- * for (WarningsGroup group : warnings) {
- * ICalProperty prop = group.getProperty();
- *   if (prop == null) {
- *     //then it was a component that caused the warnings
- *     ICalComponent comp = group.getComponent();
- *   }
- * 
- *   //get parent components
- *   List<ICalComponent> hierarchy = group.getComponentHierarchy();
- * 
- *   //get warning messages
- *   List<String> messages = group.getMessages();
- * }
- * 
- * //you can also get the warnings of specific properties/components
- * List<WarningsGroup> dtstartWarnings = warnings.getByProperty(DateStart.class);
- * List<WarningsGroup> veventWarnings = warnings.getByComponent(VEvent.class);
- * 
- * @author Michael Angstadt - * @see ICalendar#validate(ICalVersion) - */ -public class ValidationWarnings implements Iterable { - private final List warnings; - - /** - * Creates a new validation warnings list. - * @param warnings the validation warnings - */ - public ValidationWarnings(List warnings) { - this.warnings = warnings; - } - - /** - * Gets all validation warnings of a given property. - * @param propertyClass the property (e.g. {@code DateStart.class}) - * @return the validation warnings - */ - public List getByProperty(Class propertyClass) { - List warnings = new ArrayList(); - for (WarningsGroup group : this.warnings) { - ICalProperty property = group.getProperty(); - if (property == null) { - continue; - } - - if (propertyClass == property.getClass()) { - warnings.add(group); - } - } - return warnings; - } - - /** - * Gets all validation warnings of a given component. - * @param componentClass the component (e.g. {@code VEvent.class}) - * @return the validation warnings - */ - public List getByComponent(Class componentClass) { - List warnings = new ArrayList(); - for (WarningsGroup group : this.warnings) { - ICalComponent component = group.getComponent(); - if (component == null) { - continue; - } - - if (componentClass == component.getClass()) { - warnings.add(group); - } - } - return warnings; - } - - /** - * Gets all the validation warnings. - * @return the validation warnings - */ - public List getWarnings() { - return warnings; - } - - /** - * Determines whether there are any validation warnings. - * @return true if there are none, false if there are one or more - */ - public boolean isEmpty() { - return warnings.isEmpty(); - } - - /** - *

- * Outputs all validation warnings as a newline-delimited string. For - * example: - *

- * - *
-	 * [ICalendar]: ProductId is not set (it is a required property).
-	 * [ICalendar > VEvent > DateStart]: DateStart must come before DateEnd.
-	 * [ICalendar > VEvent > VAlarm]: The trigger must specify which date field its duration is relative to.
-	 * 
- */ - @Override - public String toString() { - return StringUtils.join(warnings, StringUtils.NEWLINE); - } - - /** - * Iterates over each warning group (same as calling - * {@code getWarnings().iterator()}). - * @return the iterator - */ - public Iterator iterator() { - return warnings.iterator(); - } - - /** - * Holds the validation warnings of a property or component. - * @author Michael Angstadt - */ - public static class WarningsGroup { - private final ICalProperty property; - private final ICalComponent component; - private final List componentHierarchy; - private final List warnings; - - /** - * Creates a new set of validation warnings for a property. - * @param property the property that caused the warnings - * @param componentHierarchy the hierarchy of components that the - * property belongs to - * @param warning the warnings - */ - public WarningsGroup(ICalProperty property, List componentHierarchy, List warning) { - this(null, property, componentHierarchy, warning); - } - - /** - * Creates a new set of validation warnings for a component. - * @param component the component that caused the warnings - * @param componentHierarchy the hierarchy of components that the - * component belongs to - * @param warning the warnings - */ - public WarningsGroup(ICalComponent component, List componentHierarchy, List warning) { - this(component, null, componentHierarchy, warning); - } - - private WarningsGroup(ICalComponent component, ICalProperty property, List componentHierarchy, List warning) { - this.component = component; - this.property = property; - this.componentHierarchy = componentHierarchy; - this.warnings = warning; - } - - /** - * Gets the property object that caused the validation warnings. - * @return the property object or null if a component caused the - * warnings. - */ - public ICalProperty getProperty() { - return property; - } - - /** - * Gets the component object that caused the validation warnings. - * @return the component object or null if a property caused the - * warnings. - */ - public ICalComponent getComponent() { - return component; - } - - /** - * Gets the hierarchy of components that the property or component - * belongs to. - * @return the component hierarchy - */ - public List getComponentHierarchy() { - return componentHierarchy; - } - - /** - * Gets the warnings that belong to the property or component. - * @return the warnings - */ - public List getWarnings() { - return warnings; - } - - /** - *

- * Outputs each message in this warnings group as a newline-delimited - * string. Each line includes the component hierarchy and the name of - * the property/component. For example: - *

- * - *
-		 * [ICalendar > VEvent > VAlarm]: Email alarms must have at least one attendee.
-		 * [ICalendar > VEvent > VAlarm]: The trigger must specify which date field its duration is relative to.
-		 * 
- */ - @Override - public String toString() { - final String prefix = "[" + buildPath() + "]: "; - return StringUtils.join(warnings, StringUtils.NEWLINE, new JoinCallback() { - public void handle(StringBuilder sb, ValidationWarning warning) { - sb.append(prefix).append(warning); - } - }); - } - - private String buildPath() { - StringBuilder sb = new StringBuilder(); - - if (!componentHierarchy.isEmpty()) { - String delimitor = " > "; - - StringUtils.join(componentHierarchy, delimitor, sb, new JoinCallback() { - public void handle(StringBuilder sb, ICalComponent component) { - sb.append(component.getClass().getSimpleName()); - } - }); - sb.append(delimitor); - } - - Object obj = (property == null) ? component : property; - sb.append(obj.getClass().getSimpleName()); - - return sb.toString(); - } - } -} diff --git a/app/src/main/java/biweekly/biweekly.license b/app/src/main/java/biweekly/biweekly.license deleted file mode 100644 index 7df0740991..0000000000 --- a/app/src/main/java/biweekly/biweekly.license +++ /dev/null @@ -1,22 +0,0 @@ - Copyright (c) 2013-2021, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/app/src/main/java/biweekly/commons-codec.license b/app/src/main/java/biweekly/commons-codec.license deleted file mode 100644 index 75b52484ea..0000000000 --- a/app/src/main/java/biweekly/commons-codec.license +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/app/src/main/java/biweekly/component/DaylightSavingsTime.java b/app/src/main/java/biweekly/component/DaylightSavingsTime.java deleted file mode 100644 index 787c3188a4..0000000000 --- a/app/src/main/java/biweekly/component/DaylightSavingsTime.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.component; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the date range of a timezone's daylight savings time. - *

- *

- * Examples: - *

- * - *
- * VTimezone timezone = new VTimezone("Eastern Standard Time");
- * DaylightSavingsTime daylight = new DaylightSavingsTime();
- * DateTimeComponents components = new DateTimeComponents(1999, 4, 4, 2, 0, 0, false);
- * daylight.setDateStart(components);
- * daylight.setTimezoneOffsetFrom(-5, 0);
- * daylight.setTimezoneOffsetTo(-4, 0);
- * timezone.addDaylightSavingsTime(daylight);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 p.60-7 - */ -public class DaylightSavingsTime extends Observance { - public DaylightSavingsTime() { - //empty - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public DaylightSavingsTime(DaylightSavingsTime original) { - super(original); - } - - @Override - public DaylightSavingsTime copy() { - return new DaylightSavingsTime(this); - } -} diff --git a/app/src/main/java/biweekly/component/ICalComponent.java b/app/src/main/java/biweekly/component/ICalComponent.java deleted file mode 100644 index 2081899635..0000000000 --- a/app/src/main/java/biweekly/component/ICalComponent.java +++ /dev/null @@ -1,833 +0,0 @@ -package biweekly.component; - -import java.lang.reflect.Constructor; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.Messages; -import biweekly.ValidationWarnings.WarningsGroup; -import biweekly.ValidationWarning; -import biweekly.property.ICalProperty; -import biweekly.property.RawProperty; -import biweekly.property.Status; -import biweekly.util.ListMultimap; -import biweekly.util.StringUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Base class for all iCalendar component classes. - * @author Michael Angstadt - */ -public abstract class ICalComponent { - protected final ListMultimap, ICalComponent> components; - protected final ListMultimap, ICalProperty> properties; - - public ICalComponent() { - components = new ListMultimap, ICalComponent>(); - properties = new ListMultimap, ICalProperty>(); - } - - /** - * Copy constructor. Performs a deep copy of the given component's - * properties and sub-components. - * @param original the component to make a copy of - */ - protected ICalComponent(ICalComponent original) { - this(); - for (ICalProperty property : original.properties.values()) { - addProperty(property.copy()); - } - for (ICalComponent component : original.components.values()) { - addComponent(component.copy()); - } - } - - /** - * Gets the first property of a given class. - * @param clazz the property class - * @param the property class - * @return the property or null if not found - */ - public T getProperty(Class clazz) { - return clazz.cast(properties.first(clazz)); - } - - /** - * Gets all properties of a given class. Changes to the returned list will - * update the {@link ICalComponent} object, and vice versa. - * @param clazz the property class - * @param the property class - * @return the properties - */ - public List getProperties(Class clazz) { - return new ICalPropertyList(clazz); - } - - /** - * Gets all the properties associated with this component. - * @return the properties - */ - public ListMultimap, ICalProperty> getProperties() { - return properties; - } - - /** - * Adds a property to this component. - * @param property the property to add - */ - public void addProperty(ICalProperty property) { - properties.put(property.getClass(), property); - } - - /** - * Replaces all existing properties of the given property instance's class - * with the given property instance. - * @param property the property - * @return the replaced properties (this list is immutable) - */ - public List setProperty(ICalProperty property) { - return properties.replace(property.getClass(), property); - } - - /** - * Replaces all existing properties of the given class with a single - * property instance. If the property instance is null, then all instances - * of that property will be removed. - * @param clazz the property class (e.g. "DateStart.class") - * @param property the property or null to remove all properties of the - * given class - * @param the property class - * @return the replaced properties (this list is immutable) - */ - public List setProperty(Class clazz, T property) { - List replaced = properties.replace(clazz, property); - return castList(replaced, clazz); - } - - /** - * Removes a specific property instance from this component. - * @param property the property to remove - * @param the property class - * @return true if it was removed, false if it wasn't found - */ - public boolean removeProperty(T property) { - return properties.remove(property.getClass(), property); - } - - /** - * Removes all properties of a given class from this component. - * @param clazz the class of the properties to remove (e.g. - * "DateStart.class") - * @param the property class - * @return the removed properties (this list is immutable) - */ - public List removeProperties(Class clazz) { - List removed = properties.removeAll(clazz); - return castList(removed, clazz); - } - - /** - * Removes a specific sub-component instance from this component. - * @param component the component to remove - * @param the component class - * @return true if it was removed, false if it wasn't found - */ - public boolean removeComponent(T component) { - return components.remove(component.getClass(), component); - } - - /** - * Removes all sub-components of the given class from this component. - * @param clazz the class of the components to remove (e.g. "VEvent.class") - * @param the component class - * @return the removed components (this list is immutable) - */ - public List removeComponents(Class clazz) { - List removed = components.removeAll(clazz); - return castList(removed, clazz); - } - - /** - * Gets the first experimental property with a given name. - * @param name the property name (case insensitive, e.g. "X-ALT-DESC") - * @return the experimental property or null if none were found - */ - public RawProperty getExperimentalProperty(String name) { - for (RawProperty raw : getExperimentalProperties()) { - if (raw.getName().equalsIgnoreCase(name)) { - return raw; - } - } - return null; - } - - /** - * Gets all experimental properties with a given name. - * @param name the property name (case insensitive, e.g. "X-ALT-DESC") - * @return the experimental properties (this list is immutable) - */ - public List getExperimentalProperties(String name) { - /* - * Note: The returned list is not backed by the parent component because - * this would allow RawProperty objects without the specified name to be - * added to the list. - */ - List toReturn = new ArrayList(); - for (RawProperty property : getExperimentalProperties()) { - if (property.getName().equalsIgnoreCase(name)) { - toReturn.add(property); - } - } - return Collections.unmodifiableList(toReturn); - } - - /** - * Gets all experimental properties associated with this component. Changes - * to the returned list will update the {@link ICalComponent} object, and - * vice versa. - * @return the experimental properties - */ - public List getExperimentalProperties() { - return getProperties(RawProperty.class); - } - - /** - * Adds an experimental property to this component. - * @param name the property name (e.g. "X-ALT-DESC") - * @param value the property value - * @return the property object that was created - */ - public RawProperty addExperimentalProperty(String name, String value) { - return addExperimentalProperty(name, null, value); - } - - /** - * Adds an experimental property to this component. - * @param name the property name (e.g. "X-ALT-DESC") - * @param dataType the property's data type or null if unknown - * @param value the property value - * @return the property object that was created - */ - public RawProperty addExperimentalProperty(String name, ICalDataType dataType, String value) { - RawProperty raw = new RawProperty(name, dataType, value); - addProperty(raw); - return raw; - } - - /** - * Adds an experimental property to this component, removing all existing - * properties that have the same name. - * @param name the property name (e.g. "X-ALT-DESC") - * @param value the property value - * @return the property object that was created - */ - public RawProperty setExperimentalProperty(String name, String value) { - return setExperimentalProperty(name, null, value); - } - - /** - * Adds an experimental property to this component, removing all existing - * properties that have the same name. - * @param name the property name (e.g. "X-ALT-DESC") - * @param dataType the property's data type or null if unknown - * @param value the property value - * @return the property object that was created - */ - public RawProperty setExperimentalProperty(String name, ICalDataType dataType, String value) { - removeExperimentalProperties(name); - return addExperimentalProperty(name, dataType, value); - } - - /** - * Removes all experimental properties that have the given name. - * @param name the component name (e.g. "X-ALT-DESC") - * @return the removed properties (this list is immutable) - */ - public List removeExperimentalProperties(String name) { - List all = getExperimentalProperties(); - List toRemove = new ArrayList(); - for (RawProperty property : all) { - if (property.getName().equalsIgnoreCase(name)) { - toRemove.add(property); - } - } - - all.removeAll(toRemove); - return Collections.unmodifiableList(toRemove); - } - - /** - * Gets the first sub-component of a given class. - * @param clazz the component class - * @param the component class - * @return the sub-component or null if not found - */ - public T getComponent(Class clazz) { - return clazz.cast(components.first(clazz)); - } - - /** - * Gets all sub-components of a given class. Changes to the returned list - * will update the parent component object, and vice versa. - * @param clazz the component class - * @param the component class - * @return the sub-components - */ - public List getComponents(Class clazz) { - return new ICalComponentList(clazz); - } - - /** - * Gets all the sub-components associated with this component. - * @return the sub-components - */ - public ListMultimap, ICalComponent> getComponents() { - return components; - } - - /** - * Adds a sub-component to this component. - * @param component the component to add - */ - public void addComponent(ICalComponent component) { - components.put(component.getClass(), component); - } - - /** - * Replaces all sub-components of a given class with the given component. - * @param component the component - * @return the replaced sub-components (this list is immutable) - */ - public List setComponent(ICalComponent component) { - return components.replace(component.getClass(), component); - } - - /** - * Replaces all sub-components of a given class with the given component. If - * the component instance is null, then all instances of that component will - * be removed. - * @param clazz the component's class - * @param component the component or null to remove all components of the - * given class - * @param the component class - * @return the replaced sub-components (this list is immutable) - */ - public List setComponent(Class clazz, T component) { - List replaced = components.replace(clazz, component); - return castList(replaced, clazz); - } - - /** - * Gets the first experimental sub-component with a given name. - * @param name the component name (case insensitive, e.g. "X-PARTY") - * @return the experimental component or null if none were found - */ - public RawComponent getExperimentalComponent(String name) { - for (RawComponent component : getExperimentalComponents()) { - if (component.getName().equalsIgnoreCase(name)) { - return component; - } - } - return null; - } - - /** - * Gets all experimental sub-component with a given name. - * @param name the component name (case insensitive, e.g. "X-PARTY") - * @return the experimental components (this list is immutable) - */ - public List getExperimentalComponents(String name) { - /* - * Note: The returned list is not backed by the parent component because - * this would allow RawComponent objects without the specified name to - * be added to the list. - */ - List toReturn = new ArrayList(); - for (RawComponent component : getExperimentalComponents()) { - if (component.getName().equalsIgnoreCase(name)) { - toReturn.add(component); - } - } - return Collections.unmodifiableList(toReturn); - } - - /** - * Gets all experimental sub-components associated with this component. - * Changes to the returned list will update the parent {@link ICalComponent} - * object, and vice versa. - * @return the experimental components - */ - public List getExperimentalComponents() { - return getComponents(RawComponent.class); - } - - /** - * Adds an experimental sub-component to this component. - * @param name the component name (e.g. "X-PARTY") - * @return the component object that was created - */ - public RawComponent addExperimentalComponent(String name) { - RawComponent raw = new RawComponent(name); - addComponent(raw); - return raw; - } - - /** - * Adds an experimental sub-component to this component, removing all - * existing components that have the same name. - * @param name the component name (e.g. "X-PARTY") - * @return the component object that was created - */ - public RawComponent setExperimentalComponent(String name) { - removeExperimentalComponents(name); - return addExperimentalComponent(name); - } - - /** - * Removes all experimental sub-components that have the given name. - * @param name the component name (e.g. "X-PARTY") - * @return the removed sub-components (this list is immutable) - */ - public List removeExperimentalComponents(String name) { - List all = getExperimentalComponents(); - List toRemove = new ArrayList(); - for (RawComponent property : all) { - if (property.getName().equalsIgnoreCase(name)) { - toRemove.add(property); - } - } - - all.removeAll(toRemove); - return Collections.unmodifiableList(toRemove); - } - - /** - *

- * Checks this component for data consistency problems or deviations from - * the specifications. - *

- *

- * The existence of validation warnings will not prevent the component - * object from being written to a data stream. Syntactically-correct output - * will still be produced. However, the consuming application may have - * trouble interpreting some of the data due to the presence of these - * warnings. - *

- *

- * These problems can largely be avoided by reading the Javadocs of the - * component and property classes, or by being familiar with the iCalendar - * standard. - *

- * @param hierarchy the hierarchy of components that the component belongs - * to - * @param version the version to validate against - * @see ICalendar#validate(List, ICalVersion) - * @return a list of warnings or an empty list if no problems were found - */ - public final List validate(List hierarchy, ICalVersion version) { - List warnings = new ArrayList(); - - //validate this component - List warningsBuf = new ArrayList(0); - validate(hierarchy, version, warningsBuf); - if (!warningsBuf.isEmpty()) { - warnings.add(new WarningsGroup(this, hierarchy, warningsBuf)); - } - - //add this component to the hierarchy list - //copy the list so other validate() calls aren't effected - hierarchy = new ArrayList(hierarchy); - hierarchy.add(this); - - //validate properties - for (ICalProperty property : properties.values()) { - List propWarnings = property.validate(hierarchy, version); - if (!propWarnings.isEmpty()) { - warnings.add(new WarningsGroup(property, hierarchy, propWarnings)); - } - } - - //validate sub-components - for (ICalComponent component : components.values()) { - warnings.addAll(component.validate(hierarchy, version)); - } - - return warnings; - } - - /** - *

- * Checks the component for data consistency problems or deviations from the - * spec. - *

- *

- * This method should be overridden by child classes that wish to provide - * validation logic. The default implementation of this method does nothing. - *

- * @param components the hierarchy of components that the component belongs - * to - * @param version the version to validate against - * @param warnings the list to add the warnings to - */ - protected void validate(List components, ICalVersion version, List warnings) { - //do nothing - } - - /** - * Utility method for validating that there is exactly one instance of each - * of the given properties. - * @param warnings the list to add the warnings to - * @param classes the properties to check - */ - protected void checkRequiredCardinality(List warnings, Class... classes) { - for (Class clazz : classes) { - List props = getProperties(clazz); - - if (props.isEmpty()) { - warnings.add(new ValidationWarning(2, clazz.getSimpleName())); - continue; - } - - if (props.size() > 1) { - warnings.add(new ValidationWarning(3, clazz.getSimpleName())); - continue; - } - } - } - - /** - * Utility method for validating that there is no more than one instance of - * each of the given properties. - * @param warnings the list to add the warnings to - * @param classes the properties to check - */ - protected void checkOptionalCardinality(List warnings, Class... classes) { - for (Class clazz : classes) { - List props = getProperties(clazz); - - if (props.size() > 1) { - warnings.add(new ValidationWarning(3, clazz.getSimpleName())); - continue; - } - } - } - - /** - * Utility method for validating the {@link Status} property of a component. - * @param warnings the list to add the warnings to - * @param allowed the valid statuses - */ - protected void checkStatus(List warnings, Status... allowed) { - Status actual = getProperty(Status.class); - if (actual == null) { - return; - } - - List allowedValues = new ArrayList(allowed.length); - for (Status status : allowed) { - String value = status.getValue().toLowerCase(); - allowedValues.add(value); - } - - String actualValue = actual.getValue().toLowerCase(); - if (!allowedValues.contains(actualValue)) { - warnings.add(new ValidationWarning(13, actual.getValue(), allowedValues)); - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - toString(0, sb); - return sb.toString(); - } - - /** - *

- * Gets string representations of any additional fields the component has - * (other than sub-components and properties) for the {@link #toString} - * method. - *

- *

- * Meant to be overridden by child classes. The default implementation - * returns an empty map. - *

- * @return the values of the component's fields (key = field name, value = - * field value) - */ - protected Map toStringValues() { - return Collections.emptyMap(); - } - - private void toString(int depth, StringBuilder sb) { - StringUtils.repeat(' ', depth * 2, sb); - sb.append(getClass().getName()); - - Map fields = toStringValues(); - if (!fields.isEmpty()) { - sb.append(' ').append(fields.toString()); - } - - sb.append(StringUtils.NEWLINE); - - depth++; - for (ICalProperty property : properties.values()) { - StringUtils.repeat(' ', depth * 2, sb); - sb.append(property).append(StringUtils.NEWLINE); - } - for (ICalComponent component : components.values()) { - component.toString(depth, sb); - } - } - - /** - *

- * Creates a deep copy of this component object. - *

- *

- * The default implementation of this method uses reflection to look for a - * copy constructor. Child classes SHOULD override this method to avoid the - * performance overhead involved in using reflection. - *

- *

- * The child class's copy constructor, if present, MUST invoke the - * {@link #ICalComponent(ICalComponent)} super constructor to ensure that - * the component's properties and sub-components are copied. - *

- *

- * This method MUST be overridden by the child class if the child class does - * not have a copy constructor. Otherwise, an - * {@link UnsupportedOperationException} will be thrown when an attempt is - * made to copy the component (such as in the - * {@link ICalendar#ICalendar(ICalendar) ICalendar class's copy constructor} - * ). - *

- * @return the copy - * @throws UnsupportedOperationException if the class does not have a copy - * constructor or there is a problem invoking it - */ - public ICalComponent copy() { - Class clazz = getClass(); - - try { - Constructor copyConstructor = clazz.getConstructor(clazz); - return copyConstructor.newInstance(this); - } catch (Exception e) { - throw new UnsupportedOperationException(Messages.INSTANCE.getExceptionMessage(1, clazz.getName()), e); - } - } - - /** - * Casts all objects in the given list to the given class, adding the casted - * objects to a new list. - * @param list the list to cast - * @param castTo the class to cast to - * @param the class to cast to - * @return the new list (immutable) - */ - private static List castList(List list, Class castTo) { - List casted = new ArrayList(list.size()); - for (Object object : list) { - casted.add(castTo.cast(object)); - } - return Collections.unmodifiableList(casted); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - - int propertiesHash = 1; - for (ICalProperty property : properties.values()) { - propertiesHash += property.hashCode(); - } - result = prime * result + propertiesHash; - - int componentsHash = 1; - for (ICalComponent component : components.values()) { - componentsHash += component.hashCode(); - } - result = prime * result + componentsHash; - - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - ICalComponent other = (ICalComponent) obj; - - if (properties.size() != other.properties.size()) return false; - if (components.size() != other.components.size()) return false; - - if (!compareMultimaps(properties, other.properties)) return false; - if (!compareMultimaps(components, other.components)) return false; - - return true; - } - - private static boolean compareMultimaps(ListMultimap map1, ListMultimap map2) { - for (Map.Entry> entry : map1) { - K key = entry.getKey(); - List value = entry.getValue(); - List otherValue = map2.get(key); - - if (value.size() != otherValue.size()) { - return false; - } - - List otherValueCopy = new ArrayList(otherValue); - for (V property : value) { - if (!otherValueCopy.remove(property)) { - return false; - } - } - } - return true; - } - - /** - *

- * A list that automatically casts {@link ICalComponent} instances stored in - * this component to a given component class. - *

- *

- * This list is backed by the {@link ICalComponent} object. Any changes made - * to the list will affect the {@link ICalComponent} object and vice versa. - *

- * @param the component class - */ - private class ICalComponentList extends AbstractList { - protected final Class componentClass; - protected final List components; - - /** - * @param componentClass the component class - */ - public ICalComponentList(Class componentClass) { - this.componentClass = componentClass; - components = ICalComponent.this.components.get(componentClass); - } - - @Override - public void add(int index, T value) { - components.add(index, value); - } - - @Override - public T remove(int index) { - ICalComponent removed = components.remove(index); - return cast(removed); - } - - @Override - public T get(int index) { - ICalComponent property = components.get(index); - return cast(property); - } - - @Override - public T set(int index, T value) { - ICalComponent replaced = components.set(index, value); - return cast(replaced); - } - - @Override - public int size() { - return components.size(); - } - - protected T cast(ICalComponent value) { - return componentClass.cast(value); - } - } - - /** - *

- * A list that automatically casts {@link ICalProperty} instances stored in - * this component to a given property class. - *

- *

- * This list is backed by the {@link ICalComponent} object. Any changes made - * to the list will affect the {@link ICalComponent} object and vice versa. - *

- * @param the property class - */ - private class ICalPropertyList extends AbstractList { - protected final Class propertyClass; - protected final List properties; - - /** - * @param propertyClass the property class - */ - public ICalPropertyList(Class propertyClass) { - this.propertyClass = propertyClass; - properties = ICalComponent.this.properties.get(propertyClass); - } - - @Override - public void add(int index, T value) { - properties.add(index, value); - } - - @Override - public T remove(int index) { - ICalProperty removed = properties.remove(index); - return cast(removed); - } - - @Override - public T get(int index) { - ICalProperty property = properties.get(index); - return cast(property); - } - - @Override - public T set(int index, T value) { - ICalProperty replaced = properties.set(index, value); - return cast(replaced); - } - - @Override - public int size() { - return properties.size(); - } - - protected T cast(ICalProperty value) { - return propertyClass.cast(value); - } - } -} diff --git a/app/src/main/java/biweekly/component/Observance.java b/app/src/main/java/biweekly/component/Observance.java deleted file mode 100644 index 838983ebad..0000000000 --- a/app/src/main/java/biweekly/component/Observance.java +++ /dev/null @@ -1,409 +0,0 @@ -package biweekly.component; - -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.property.Comment; -import biweekly.property.DateStart; -import biweekly.property.ExceptionDates; -import biweekly.property.RecurrenceDates; -import biweekly.property.RecurrenceRule; -import biweekly.property.TimezoneName; -import biweekly.property.TimezoneOffsetFrom; -import biweekly.property.TimezoneOffsetTo; -import biweekly.util.DateTimeComponents; -import biweekly.util.ICalDate; -import biweekly.util.Recurrence; -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a timezone observance (i.e. "daylight savings" and "standard" - * times). - * @author Michael Angstadt - * @see DaylightSavingsTime - * @see StandardTime - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 p.60-7 - */ -/* - * Note: References to the vCal 1.0 spec are omitted from the property - * getter/setter method Javadocs because vCal does not use the VTIMEZONE - * component. - */ -public class Observance extends ICalComponent { - public Observance() { - //empty - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public Observance(Observance original) { - super(original); - } - - /** - * Gets the date that the timezone observance starts. - * @return the start date or null if not set - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart getDateStart() { - return getProperty(DateStart.class); - } - - /** - * Sets the date that the timezone observance starts. - * @param dateStart the start date or null to remove - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public void setDateStart(DateStart dateStart) { - setProperty(DateStart.class, dateStart); - } - - /** - * Sets the date that the timezone observance starts. - * @param date the start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart setDateStart(ICalDate date) { - DateStart prop = (date == null) ? null : new DateStart(date); - setDateStart(prop); - return prop; - } - - /** - * Sets the date that the timezone observance starts. - * @param rawComponents the start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart setDateStart(DateTimeComponents rawComponents) { - return setDateStart((rawComponents == null) ? null : new ICalDate(rawComponents, true)); - } - - /** - * Gets the UTC offset that the timezone observance transitions to. - * @return the UTC offset or null if not set - * @see RFC 5545 - * p.105-6 - * @see RFC 2445 - * p.100-1 - */ - public TimezoneOffsetTo getTimezoneOffsetTo() { - return getProperty(TimezoneOffsetTo.class); - } - - /** - * Sets the UTC offset that the timezone observance transitions to. - * @param timezoneOffsetTo the UTC offset or null to remove - * @see RFC 5545 - * p.105-6 - * @see RFC 2445 - * p.100-1 - */ - public void setTimezoneOffsetTo(TimezoneOffsetTo timezoneOffsetTo) { - setProperty(TimezoneOffsetTo.class, timezoneOffsetTo); - } - - /** - * Sets the UTC offset that the timezone observance transitions to. - * @param offset the offset - * @return the property that was created - * @see RFC 5545 - * p.105-6 - * @see RFC 2445 - * p.100-1 - */ - public TimezoneOffsetTo setTimezoneOffsetTo(UtcOffset offset) { - TimezoneOffsetTo prop = new TimezoneOffsetTo(offset); - setTimezoneOffsetTo(prop); - return prop; - } - - /** - * Gets the UTC offset that the timezone observance transitions from. - * @return the UTC offset or null if not set - * @see RFC 5545 - * p.104-5 - * @see RFC 2445 - * p.99-100 - */ - public TimezoneOffsetFrom getTimezoneOffsetFrom() { - return getProperty(TimezoneOffsetFrom.class); - } - - /** - * Sets the UTC offset that the timezone observance transitions from. - * @param timezoneOffsetFrom the UTC offset or null to remove - * @see RFC 5545 - * p.104-5 - * @see RFC 2445 - * p.99-100 - */ - public void setTimezoneOffsetFrom(TimezoneOffsetFrom timezoneOffsetFrom) { - setProperty(TimezoneOffsetFrom.class, timezoneOffsetFrom); - } - - /** - * Sets the UTC offset that the timezone observance transitions from. - * @param offset the offset - * @return the property that was created - * @see RFC 5545 - * p.104-5 - * @see RFC 2445 - * p.99-100 - */ - public TimezoneOffsetFrom setTimezoneOffsetFrom(UtcOffset offset) { - TimezoneOffsetFrom prop = new TimezoneOffsetFrom(offset); - setTimezoneOffsetFrom(prop); - return prop; - } - - /** - * Gets how often the timezone observance repeats. - * @return the recurrence rule or null if not set - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - */ - public RecurrenceRule getRecurrenceRule() { - return getProperty(RecurrenceRule.class); - } - - /** - * Sets how often the timezone observance repeats. - * @param recur the recurrence rule or null to remove - * @return the property that was created - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - */ - public RecurrenceRule setRecurrenceRule(Recurrence recur) { - RecurrenceRule prop = (recur == null) ? null : new RecurrenceRule(recur); - setRecurrenceRule(prop); - return prop; - } - - /** - * Sets how often the timezone observance repeats. - * @param recurrenceRule the recurrence rule or null to remove - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - */ - public void setRecurrenceRule(RecurrenceRule recurrenceRule) { - setProperty(RecurrenceRule.class, recurrenceRule); - } - - /** - * Gets the comments attached to the timezone observance. - * @return the comments (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public List getComments() { - return getProperties(Comment.class); - } - - /** - * Adds a comment to the timezone observance. - * @param comment the comment to add - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public void addComment(Comment comment) { - addProperty(comment); - } - - /** - * Adds a comment to the timezone observance. - * @param comment the comment to add - * @return the property that was created - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public Comment addComment(String comment) { - Comment prop = new Comment(comment); - addComment(prop); - return prop; - } - - /** - * Gets the list of dates/periods that help define the recurrence rule of - * this timezone observance (if one is defined). - * @return the recurrence dates (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - */ - public List getRecurrenceDates() { - return getProperties(RecurrenceDates.class); - } - - /** - * Adds a list of dates/periods that help define the recurrence rule of this - * timezone observance (if one is defined). - * @param recurrenceDates the recurrence dates - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - */ - public void addRecurrenceDates(RecurrenceDates recurrenceDates) { - addProperty(recurrenceDates); - } - - /** - * Gets the traditional, non-standard names for the timezone observance. - * @return the timezone observance names (any changes made this list will - * affect the parent component object and vice versa) - * @see RFC 5545 - * p.103-4 - * @see RFC 2445 - * p.98-9 - */ - public List getTimezoneNames() { - return getProperties(TimezoneName.class); - } - - /** - * Adds a traditional, non-standard name for the timezone observance. - * @param timezoneName the timezone observance name - * @see RFC 5545 - * p.103-4 - * @see RFC 2445 - * p.98-9 - */ - public void addTimezoneName(TimezoneName timezoneName) { - addProperty(timezoneName); - } - - /** - * Adds a traditional, non-standard name for the timezone observance. - * @param timezoneName the timezone observance name (e.g. "EST") - * @return the property that was created - * @see RFC 5545 - * p.103-4 - * @see RFC 2445 - * p.98-9 - */ - public TimezoneName addTimezoneName(String timezoneName) { - TimezoneName prop = new TimezoneName(timezoneName); - addTimezoneName(prop); - return prop; - } - - /** - * Gets the list of exceptions to the timezone observance. - * @return the list of exceptions (any changes made this list will affect - * the parent component object and vice versa) - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - */ - public List getExceptionDates() { - return getProperties(ExceptionDates.class); - } - - /** - * Adds a list of exceptions to the timezone observance. Note that this - * property can contain multiple dates. - * @param exceptionDates the list of exceptions - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - */ - public void addExceptionDates(ExceptionDates exceptionDates) { - addProperty(exceptionDates); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version == ICalVersion.V1_0) { - warnings.add(new ValidationWarning(48, version)); - } - - checkRequiredCardinality(warnings, DateStart.class, TimezoneOffsetTo.class, TimezoneOffsetFrom.class); - - //BYHOUR, BYMINUTE, and BYSECOND cannot be specified in RRULE if DTSTART's data type is "date" - //RFC 5545 p. 167 - DateStart dateStart = getDateStart(); - RecurrenceRule rrule = getRecurrenceRule(); - if (dateStart != null && rrule != null) { - ICalDate start = dateStart.getValue(); - Recurrence recur = rrule.getValue(); - if (start != null && recur != null) { - if (!start.hasTime() && (!recur.getByHour().isEmpty() || !recur.getByMinute().isEmpty() || !recur.getBySecond().isEmpty())) { - warnings.add(new ValidationWarning(5)); - } - } - } - - //there *should* be only 1 instance of RRULE - //RFC 5545 p. 167 - if (getProperties(RecurrenceRule.class).size() > 1) { - warnings.add(new ValidationWarning(6)); - } - } - - @Override - public Observance copy() { - return new Observance(this); - } -} diff --git a/app/src/main/java/biweekly/component/RawComponent.java b/app/src/main/java/biweekly/component/RawComponent.java deleted file mode 100644 index 0ce9db5f3e..0000000000 --- a/app/src/main/java/biweekly/component/RawComponent.java +++ /dev/null @@ -1,74 +0,0 @@ -package biweekly.component; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a component that does not have a scribe associated with it. - * @author Michael Angstadt - */ -public class RawComponent extends ICalComponent { - private final String name; - - public RawComponent(String name) { - this.name = name; - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public RawComponent(RawComponent original) { - super(original); - this.name = original.name; - } - - public String getName() { - return name; - } - - @Override - public RawComponent copy() { - return new RawComponent(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) return false; - RawComponent other = (RawComponent) obj; - if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/component/StandardTime.java b/app/src/main/java/biweekly/component/StandardTime.java deleted file mode 100644 index 24d46a334a..0000000000 --- a/app/src/main/java/biweekly/component/StandardTime.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.component; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the date range of a timezone's standard time. - *

- *

- * Examples: - *

- * - *
- * VTimezone timezone = new VTimezone("Eastern Standard Time");
- * StandardTime standard = new StandardTime();
- * DateTimeComponents components = new DateTimeComponents(1998, 10, 25, 2, 0, 0, false);
- * standard.setDateStart(components);
- * standard.setTimezoneOffsetFrom(-4, 0);
- * standard.setTimezoneOffsetTo(-5, 0);
- * timezone.addStandardTime(standard);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 p.60-7 - */ -public class StandardTime extends Observance { - public StandardTime() { - //empty - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public StandardTime(StandardTime original) { - super(original); - } - - @Override - public StandardTime copy() { - return new StandardTime(this); - } -} diff --git a/app/src/main/java/biweekly/component/VAlarm.java b/app/src/main/java/biweekly/component/VAlarm.java deleted file mode 100644 index 207cd557b5..0000000000 --- a/app/src/main/java/biweekly/component/VAlarm.java +++ /dev/null @@ -1,590 +0,0 @@ -package biweekly.component; - -import java.util.Arrays; -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.parameter.Related; -import biweekly.property.Action; -import biweekly.property.Attachment; -import biweekly.property.Attendee; -import biweekly.property.DateDue; -import biweekly.property.DateEnd; -import biweekly.property.DateStart; -import biweekly.property.Description; -import biweekly.property.DurationProperty; -import biweekly.property.Repeat; -import biweekly.property.Summary; -import biweekly.property.Trigger; -import biweekly.util.Duration; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a reminder for an event or to-do task. This class contains static - * factory methods to aid in the construction of valid alarms. - *

- *

- * Examples: - *

- * - *
- * //audio alarm
- * Trigger trigger = ...
- * Attachment sound = ...
- * VAlarm audio = VAlarm.audio(trigger, sound);
- * 
- * //display alarm
- * Trigger trigger = ...
- * String message = "Meeting at 1pm";
- * VAlarm display = VAlarm.display(trigger, message);
- * 
- * //email alarm
- * Trigger trigger = ...
- * String subject = "Reminder: Meeting at 1pm";
- * String body = "Team,\n\nThe team meeting scheduled for 1pm is about to start.  Snacks will be served!\n\nThanks,\nJohn";
- * List<String> to = Arrays.asList("janedoe@example.com", "bobsmith@example.com");
- * VAlarm email = VAlarm.email(trigger, subject, body, to);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.71-6 - * @see RFC 2445 - * p.67-73 - */ -/* - * Note: References to the vCal 1.0 spec are omitted from the property - * getter/setter method Javadocs because vCal does not use the VALARM component. - */ -public class VAlarm extends ICalComponent { - /** - * Creates a new alarm. Consider using one of the static factory methods - * instead. - * @param action the alarm action (e.g. "email") - * @param trigger the trigger - */ - public VAlarm(Action action, Trigger trigger) { - setAction(action); - setTrigger(trigger); - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public VAlarm(VAlarm original) { - super(original); - } - - /** - * Creates an audio alarm. - * @param trigger the trigger - * @return the alarm - */ - public static VAlarm audio(Trigger trigger) { - return audio(trigger, null); - } - - /** - * Creates an audio alarm. - * @param trigger the trigger - * @param sound a sound to play when the alarm triggers - * @return the alarm - */ - public static VAlarm audio(Trigger trigger, Attachment sound) { - VAlarm alarm = new VAlarm(Action.audio(), trigger); - if (sound != null) { - alarm.addAttachment(sound); - } - return alarm; - } - - /** - * Creates a display alarm. - * @param trigger the trigger - * @param displayText the display text - * @return the alarm - */ - public static VAlarm display(Trigger trigger, String displayText) { - VAlarm alarm = new VAlarm(Action.display(), trigger); - alarm.setDescription(displayText); - return alarm; - } - - /** - * Creates an email alarm. - * @param trigger the trigger - * @param subject the email subject - * @param body the email body - * @param recipients the email address(es) to send the alert to - * @return the alarm - */ - public static VAlarm email(Trigger trigger, String subject, String body, String... recipients) { - return email(trigger, subject, body, Arrays.asList(recipients)); - } - - /** - * Creates a procedure alarm (vCal 1.0 only). - * @param trigger the trigger - * @param path the path or name of the procedure - * @return the alarm - */ - public static VAlarm procedure(Trigger trigger, String path) { - VAlarm alarm = new VAlarm(Action.procedure(), trigger); - alarm.setDescription(path); - return alarm; - } - - /** - * Creates an email alarm. - * @param trigger the trigger - * @param subject the email subject - * @param body the email body - * @param recipients the email address(es) to send the alert to - * @return the alarm - */ - public static VAlarm email(Trigger trigger, String subject, String body, List recipients) { - VAlarm alarm = new VAlarm(Action.email(), trigger); - alarm.setSummary(subject); - alarm.setDescription(body); - for (String recipient : recipients) { - alarm.addAttendee(new Attendee(null, recipient)); - } - return alarm; - } - - /** - * Gets any attachments that are associated with the alarm. - * @return the attachments (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - */ - public List getAttachments() { - return getProperties(Attachment.class); - } - - /** - * Adds an attachment to the alarm. Note that AUDIO alarms should only have - * 1 attachment. - * @param attachment the attachment to add - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - */ - public void addAttachment(Attachment attachment) { - addProperty(attachment); - } - - /** - *

- * Gets a detailed description of the alarm. The description should be more - * detailed than the one provided by the {@link Summary} property. - *

- *

- * This property has different meanings, depending on the alarm action: - *

- *
    - *
  • DISPLAY - the display text
  • - *
  • EMAIL - the body of the email message
  • - *
  • all others - a general description of the alarm
  • - *
- * @return the description or null if not set - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - */ - public Description getDescription() { - return getProperty(Description.class); - } - - /** - *

- * Sets a detailed description of the alarm. The description should be more - * detailed than the one provided by the {@link Summary} property. - *

- *

- * This property has different meanings, depending on the alarm action: - *

- *
    - *
  • DISPLAY - the display text
  • - *
  • EMAIL - the body of the email message
  • - *
  • all others - a general description of the alarm
  • - *
- * @param description the description or null to remove - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - */ - public void setDescription(Description description) { - setProperty(Description.class, description); - } - - /** - *

- * Sets a detailed description of the alarm. The description should be more - * detailed than the one provided by the {@link Summary} property. - *

- *

- * This property has different meanings, depending on the alarm action: - *

- *
    - *
  • DISPLAY - the display text
  • - *
  • EMAIL - the body of the email message
  • - *
  • all others - a general description of the alarm
  • - *
- * @param description the description or null to remove - * @return the property that was created - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - */ - public Description setDescription(String description) { - Description prop = (description == null) ? null : new Description(description); - setDescription(prop); - return prop; - } - - /** - *

- * Gets the summary of the alarm. - *

- *

- * This property has different meanings, depending on the alarm action: - *

- *
    - *
  • EMAIL - the subject line of the email
  • - *
  • all others - a one-line summary of the alarm
  • - *
- * @return the summary or null if not set - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - */ - public Summary getSummary() { - return getProperty(Summary.class); - } - - /** - *

- * Sets the summary of the alarm. - *

- *

- * This property has different meanings, depending on the alarm action: - *

- *
    - *
  • EMAIL - the subject line of the email
  • - *
  • all others - a one-line summary of the alarm
  • - *
- * @param summary the summary or null to remove - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - */ - public void setSummary(Summary summary) { - setProperty(Summary.class, summary); - } - - /** - *

- * Sets the summary of the alarm. - *

- *

- * This property has different meanings, depending on the alarm action: - *

- *
    - *
  • EMAIL - the subject line of the email
  • - *
  • all others - a one-line summary of the alarm
  • - *
- * @param summary the summary or null to remove - * @return the property that was created - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - */ - public Summary setSummary(String summary) { - Summary prop = (summary == null) ? null : new Summary(summary); - setSummary(prop); - return prop; - } - - /** - * Gets the people who will be emailed when the alarm fires (only applicable - * for EMAIL alarms). - * @return the email recipients (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public List getAttendees() { - return getProperties(Attendee.class); - } - - /** - * Adds a person who will be emailed when the alarm fires (only applicable - * for EMAIL alarms). - * @param attendee the email recipient - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public void addAttendee(Attendee attendee) { - addProperty(attendee); - } - - /** - * Gets the type of action to invoke when the alarm is triggered. - * @return the action or null if not set - * @see RFC 5545 - * p.132-3 - * @see RFC 2445 - * p.126 - */ - public Action getAction() { - return getProperty(Action.class); - } - - /** - * Sets the type of action to invoke when the alarm is triggered. - * @param action the action or null to remove - * @see RFC 5545 - * p.132-3 - * @see RFC 2445 - * p.126 - */ - public void setAction(Action action) { - setProperty(Action.class, action); - } - - /** - * Gets the length of the pause between alarm repetitions. - * @return the duration or null if not set - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public DurationProperty getDuration() { - return getProperty(DurationProperty.class); - } - - /** - * Sets the length of the pause between alarm repetitions. - * @param duration the duration or null to remove - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public void setDuration(DurationProperty duration) { - setProperty(DurationProperty.class, duration); - } - - /** - * Sets the length of the pause between alarm repetitions. - * @param duration the duration or null to remove - * @return the property that was created - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public DurationProperty setDuration(Duration duration) { - DurationProperty prop = (duration == null) ? null : new DurationProperty(duration); - setDuration(prop); - return prop; - } - - /** - * Gets the number of times an alarm should be repeated after its initial - * trigger. - * @return the repeat count or null if not set - * @see RFC 5545 - * p.133 - * @see RFC 2445 - * p.126-7 - */ - public Repeat getRepeat() { - return getProperty(Repeat.class); - } - - /** - * Sets the number of times an alarm should be repeated after its initial - * trigger. - * @param repeat the repeat count or null to remove - * @see RFC 5545 - * p.133 - * @see RFC 2445 - * p.126-7 - */ - public void setRepeat(Repeat repeat) { - setProperty(Repeat.class, repeat); - } - - /** - * Sets the number of times an alarm should be repeated after its initial - * trigger. - * @param count the repeat count (e.g. "2" to repeat it two more times after - * it was initially triggered, for a total of three times) or null to remove - * @return the property that was created - * @see RFC 5545 - * p.133 - * @see RFC 2445 - * p.126-7 - */ - public Repeat setRepeat(Integer count) { - Repeat prop = (count == null) ? null : new Repeat(count); - setRepeat(prop); - return prop; - } - - /** - * Sets the repetition information for the alarm. - * @param count the repeat count (e.g. "2" to repeat it two more times after - * it was initially triggered, for a total of three times) - * @param pauseDuration the length of the pause between repeats - * @see RFC 5545 - * p.133 - * @see RFC 2445 - * p.126-7 - */ - public void setRepeat(int count, Duration pauseDuration) { - Repeat repeat = new Repeat(count); - DurationProperty duration = new DurationProperty(pauseDuration); - setRepeat(repeat); - setDuration(duration); - } - - /** - * Gets when the alarm will be triggered. - * @return the trigger time or null if not set - * @see RFC 5545 - * p.133-6 - * @see RFC 2445 - * p.127-9 - */ - public Trigger getTrigger() { - return getProperty(Trigger.class); - } - - /** - * Sets when the alarm will be triggered. - * @param trigger the trigger time or null to remove - * @see RFC 5545 - * p.133-6 - * @see RFC 2445 - * p.127-9 - */ - public void setTrigger(Trigger trigger) { - setProperty(Trigger.class, trigger); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - checkRequiredCardinality(warnings, Action.class, Trigger.class); - - Action action = getAction(); - if (action != null) { - //AUDIO alarms should not have more than 1 attachment - if (action.isAudio()) { - if (getAttachments().size() > 1) { - warnings.add(new ValidationWarning(7)); - } - } - - //DESCRIPTION is required for DISPLAY alarms - if (action.isDisplay()) { - checkRequiredCardinality(warnings, Description.class); - } - - if (action.isEmail()) { - //SUMMARY and DESCRIPTION is required for EMAIL alarms - checkRequiredCardinality(warnings, Summary.class, Description.class); - - //EMAIL alarms must have at least 1 ATTENDEE - if (getAttendees().isEmpty()) { - warnings.add(new ValidationWarning(8)); - } - } else { - //only EMAIL alarms can have ATTENDEEs - if (!getAttendees().isEmpty()) { - warnings.add(new ValidationWarning(9)); - } - } - - if (action.isProcedure()) { - checkRequiredCardinality(warnings, Description.class); - } - } - - Trigger trigger = getTrigger(); - if (trigger != null) { - Related related = trigger.getRelated(); - if (related != null) { - ICalComponent parent = components.get(components.size() - 1); - - //if the TRIGGER is relative to DTSTART, confirm that DTSTART exists - if (related == Related.START && parent.getProperty(DateStart.class) == null) { - warnings.add(new ValidationWarning(11)); - } - - //if the TRIGGER is relative to DTEND, confirm that DTEND (or DUE) exists - if (related == Related.END) { - boolean noEndDate = false; - - if (parent instanceof VEvent) { - noEndDate = (parent.getProperty(DateEnd.class) == null && (parent.getProperty(DateStart.class) == null || parent.getProperty(DurationProperty.class) == null)); - } else if (parent instanceof VTodo) { - noEndDate = (parent.getProperty(DateDue.class) == null && (parent.getProperty(DateStart.class) == null || parent.getProperty(DurationProperty.class) == null)); - } - - if (noEndDate) { - warnings.add(new ValidationWarning(12)); - } - } - } - } - } - - @Override - public VAlarm copy() { - return new VAlarm(this); - } -} diff --git a/app/src/main/java/biweekly/component/VEvent.java b/app/src/main/java/biweekly/component/VEvent.java deleted file mode 100644 index b6c3dcfba4..0000000000 --- a/app/src/main/java/biweekly/component/VEvent.java +++ /dev/null @@ -1,1726 +0,0 @@ -package biweekly.component; - -import static biweekly.property.ValuedProperty.getValue; - -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.property.Attachment; -import biweekly.property.Attendee; -import biweekly.property.Categories; -import biweekly.property.Classification; -import biweekly.property.Color; -import biweekly.property.Comment; -import biweekly.property.Conference; -import biweekly.property.Contact; -import biweekly.property.Created; -import biweekly.property.DateEnd; -import biweekly.property.DateStart; -import biweekly.property.DateTimeStamp; -import biweekly.property.Description; -import biweekly.property.DurationProperty; -import biweekly.property.ExceptionDates; -import biweekly.property.ExceptionRule; -import biweekly.property.Geo; -import biweekly.property.Image; -import biweekly.property.LastModified; -import biweekly.property.Location; -import biweekly.property.Method; -import biweekly.property.Organizer; -import biweekly.property.Priority; -import biweekly.property.RecurrenceDates; -import biweekly.property.RecurrenceId; -import biweekly.property.RecurrenceRule; -import biweekly.property.RelatedTo; -import biweekly.property.RequestStatus; -import biweekly.property.Resources; -import biweekly.property.Sequence; -import biweekly.property.Status; -import biweekly.property.Summary; -import biweekly.property.Transparency; -import biweekly.property.Uid; -import biweekly.property.Url; -import biweekly.util.Duration; -import biweekly.util.Google2445Utils; -import biweekly.util.ICalDate; -import biweekly.util.Period; -import biweekly.util.Recurrence; -import biweekly.util.com.google.ical.compat.javautil.DateIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a scheduled activity, such as a two hour meeting. - *

- *

- * Examples: - *

- * - *
- * VEvent event = new VEvent();
- * Date start = ...
- * event.setDateStart(start);
- * Date end = ...
- * event.setDateEnd(end);
- * event.setSummary("Team Meeting");
- * event.setLocation("Room 21C");
- * event.setCreated(new Date());
- * event.setRecurrenceRule(new Recurrence.Builder(Frequency.WEEKLY).build());
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.52-5 - * @see RFC 2445 p.52-4 - * @see vCal 1.0 p.13 - */ -public class VEvent extends ICalComponent { - /** - *

- * Creates a new event. - *

- *

- * The following properties are added to the component when it is created: - *

- *
    - *
  • {@link Uid}: Set to a UUID.
  • - *
  • {@link DateTimeStamp}: Set to the current time.
  • - *
- */ - public VEvent() { - setUid(Uid.random()); - setDateTimeStamp(new Date()); - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public VEvent(VEvent original) { - super(original); - } - - /** - * Gets the unique identifier for this event. This component object comes - * populated with a UID on creation. This is a required property. - * @return the UID or null if not set - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - */ - public Uid getUid() { - return getProperty(Uid.class); - } - - /** - * Sets the unique identifier for this event. This component object comes - * populated with a UID on creation. This is a required property. - * @param uid the UID or null to remove - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - */ - public void setUid(Uid uid) { - setProperty(Uid.class, uid); - } - - /** - * Sets the unique identifier for this event. This component object comes - * populated with a UID on creation. This is a required property. - * @param uid the UID or null to remove - * @return the property that was created - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - */ - public Uid setUid(String uid) { - Uid prop = (uid == null) ? null : new Uid(uid); - setUid(prop); - return prop; - } - - /** - * Gets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the event was - * last modified (the {@link LastModified} property also holds this - * information). This event object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @return the date time stamp or null if not set - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp getDateTimeStamp() { - return getProperty(DateTimeStamp.class); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the event was - * last modified (the {@link LastModified} property also holds this - * information). This event object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public void setDateTimeStamp(DateTimeStamp dateTimeStamp) { - setProperty(DateTimeStamp.class, dateTimeStamp); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the event was - * last modified (the {@link LastModified} property also holds this - * information). This event object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @return the property that was created - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp setDateTimeStamp(Date dateTimeStamp) { - DateTimeStamp prop = (dateTimeStamp == null) ? null : new DateTimeStamp(dateTimeStamp); - setDateTimeStamp(prop); - return prop; - } - - /** - * Gets the date that the event starts. - * @return the start date or null if not set - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public DateStart getDateStart() { - return getProperty(DateStart.class); - } - - /** - * Sets the date that the event starts (required if no {@link Method} - * property is defined). - * @param dateStart the start date or null to remove - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public void setDateStart(DateStart dateStart) { - setProperty(DateStart.class, dateStart); - } - - /** - * Sets the date that the event starts (required if no {@link Method} - * property is defined). - * @param dateStart the start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public DateStart setDateStart(Date dateStart) { - return setDateStart(dateStart, true); - } - - /** - * Sets the date that the event starts (required if no {@link Method} - * property is defined). - * @param dateStart the start date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public DateStart setDateStart(Date dateStart, boolean hasTime) { - DateStart prop = (dateStart == null) ? null : new DateStart(dateStart, hasTime); - setDateStart(prop); - return prop; - } - - /** - * Gets the level of sensitivity of the event data. If not specified, the - * data within the event should be considered "public". - * @return the classification level or null if not set - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ - public Classification getClassification() { - return getProperty(Classification.class); - } - - /** - * Sets the level of sensitivity of the event data. If not specified, the - * data within the event should be considered "public". - * @param classification the classification level or null to remove - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ - public void setClassification(Classification classification) { - setProperty(Classification.class, classification); - } - - /** - * Sets the level of sensitivity of the event data. If not specified, the - * data within the event should be considered "public". - * @param classification the classification level (e.g. "CONFIDENTIAL") or - * null to remove - * @return the property that was created - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ - public Classification setClassification(String classification) { - Classification prop = (classification == null) ? null : new Classification(classification); - setClassification(prop); - return prop; - } - - /** - * Gets a detailed description of the event. The description should be more - * detailed than the one provided by the {@link Summary} property. - * @return the description or null if not set - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - * @see vCal 1.0 p.30 - */ - public Description getDescription() { - return getProperty(Description.class); - } - - /** - * Sets a detailed description of the event. The description should be more - * detailed than the one provided by the {@link Summary} property. - * @param description the description or null to remove - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - * @see vCal 1.0 p.30 - */ - public void setDescription(Description description) { - setProperty(Description.class, description); - } - - /** - * Sets a detailed description of the event. The description should be more - * detailed than the one provided by the {@link Summary} property. - * @param description the description or null to remove - * @return the property that was created - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - * @see vCal 1.0 p.30 - */ - public Description setDescription(String description) { - Description prop = (description == null) ? null : new Description(description); - setDescription(prop); - return prop; - } - - /** - * Gets a set of geographical coordinates. - * @return the geographical coordinates or null if not set - * @see RFC 5545 - * p.85-7 - * @see RFC 2445 - * p.82-3 - */ - //Note: vCal 1.0 spec is omitted because GEO is not used in vCal 1.0 events - public Geo getGeo() { - return getProperty(Geo.class); - } - - /** - * Sets a set of geographical coordinates. - * @param geo the geographical coordinates or null to remove - * @see RFC 5545 - * p.85-7 - * @see RFC 2445 - * p.82-3 - */ - //Note: vCal 1.0 spec is omitted because GEO is not used in vCal 1.0 events - public void setGeo(Geo geo) { - setProperty(Geo.class, geo); - } - - /** - * Gets the physical location of the event. - * @return the location or null if not set - * @see RFC 5545 - * p.87-8 - * @see RFC 2445 - * p.84 - * @see vCal 1.0 p.32 - */ - public Location getLocation() { - return getProperty(Location.class); - } - - /** - * Sets the physical location of the event. - * @param location the location or null to remove - * @see RFC 5545 - * p.87-8 - * @see RFC 2445 - * p.84 - * @see vCal 1.0 p.32 - */ - public void setLocation(Location location) { - setProperty(Location.class, location); - } - - /** - * Sets the physical location of the event. - * @param location the location (e.g. "Room 101") or null to remove - * @return the property that was created - * @see RFC 5545 - * p.87-8 - * @see RFC 2445 - * p.84 - * @see vCal 1.0 p.32 - */ - public Location setLocation(String location) { - Location prop = (location == null) ? null : new Location(location); - setLocation(prop); - return prop; - } - - /** - * Gets the priority of the event. - * @return the priority or null if not set - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 - * p.85-7 - * @see vCal 1.0 p.33 - */ - public Priority getPriority() { - return getProperty(Priority.class); - } - - /** - * Sets the priority of the event. - * @param priority the priority or null to remove - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 - * p.85-7 - * @see vCal 1.0 p.33 - */ - public void setPriority(Priority priority) { - setProperty(Priority.class, priority); - } - - /** - * Sets the priority of the event. - * @param priority the priority ("0" is undefined, "1" is the highest, "9" - * is the lowest) or null to remove - * @return the property that was created - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 - * p.85-7 - * @see vCal 1.0 p.33 - */ - public Priority setPriority(Integer priority) { - Priority prop = (priority == null) ? null : new Priority(priority); - setPriority(prop); - return prop; - } - - /** - * Gets the status of the event. - * @return the status or null if not set - * @see RFC 5545 - * p.92-3 - * @see RFC 2445 - * p.88-9 - * @see vCal 1.0 p.35-6 - */ - public Status getStatus() { - return getProperty(Status.class); - } - - /** - *

- * Sets the status of the event. - *

- *

- * Valid event status codes are: - *

- *
    - *
  • TENTATIVE
  • - *
  • CONFIRMED
  • - *
  • CANCELLED
  • - *
- * @param status the status or null to remove - * @see RFC 5545 - * p.92-3 - * @see RFC 2445 - * p.88-9 - * @see vCal 1.0 p.35-6 - */ - public void setStatus(Status status) { - setProperty(Status.class, status); - } - - /** - * Gets the summary of the event. - * @return the summary or null if not set - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ - public Summary getSummary() { - return getProperty(Summary.class); - } - - /** - * Sets the summary of the event. - * @param summary the summary or null to remove - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ - public void setSummary(Summary summary) { - setProperty(Summary.class, summary); - } - - /** - * Sets the summary of the event. - * @param summary the summary or null to remove - * @return the property that was created - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ - public Summary setSummary(String summary) { - Summary prop = (summary == null) ? null : new Summary(summary); - setSummary(prop); - return prop; - } - - /** - * Gets whether an event is visible to free/busy time searches. If the event - * does not have this property, it should be considered visible ("opaque"). - * @return the transparency or null if not set - * @see RFC 5545 - * p.101-2 - * @see RFC 2445 - * p.96-7 - * @see vCal 1.0 p.36-7 - */ - public Transparency getTransparency() { - return getProperty(Transparency.class); - } - - /** - * Sets whether an event is visible to free/busy time searches. - * @param transparency the transparency or null to remove - * @see RFC 5545 - * p.101-2 - * @see RFC 2445 - * p.96-7 - * @see vCal 1.0 p.36-7 - */ - public void setTransparency(Transparency transparency) { - setProperty(Transparency.class, transparency); - } - - /** - * Sets whether an event is visible to free/busy time searches. - * @param transparent true to hide the event, false to make it visible it, - * or null to remove the property - * @return the property that was created - * @see RFC 5545 - * p.101-2 - * @see RFC 2445 - * p.96-7 - * @see vCal 1.0 p.36-7 - */ - public Transparency setTransparency(Boolean transparent) { - Transparency prop = null; - if (transparent != null) { - prop = transparent ? Transparency.transparent() : Transparency.opaque(); - } - setTransparency(prop); - return prop; - } - - /** - * Gets the organizer of the event. - * @return the organizer or null if not set - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer getOrganizer() { - return getProperty(Organizer.class); - } - - /** - * Sets the organizer of the event. - * @param organizer the organizer or null to remove - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public void setOrganizer(Organizer organizer) { - setProperty(Organizer.class, organizer); - } - - /** - * Sets the organizer of the event. - * @param email the organizer's email address (e.g. "johndoe@example.com") - * or null to remove - * @return the property that was created - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer setOrganizer(String email) { - Organizer prop = (email == null) ? null : new Organizer(null, email); - setOrganizer(prop); - return prop; - } - - /** - * Gets the original value of the {@link DateStart} property if the event is - * recurring and has been modified. Used in conjunction with the {@link Uid} - * and {@link Sequence} properties to uniquely identify a recurrence - * instance. - * @return the recurrence ID or null if not set - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public RecurrenceId getRecurrenceId() { - return getProperty(RecurrenceId.class); - } - - /** - * Sets the original value of the {@link DateStart} property if the event is - * recurring and has been modified. Used in conjunction with the {@link Uid} - * and {@link Sequence} properties to uniquely identify a recurrence - * instance. - * @param recurrenceId the recurrence ID or null to remove - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public void setRecurrenceId(RecurrenceId recurrenceId) { - setProperty(RecurrenceId.class, recurrenceId); - } - - /** - * Sets the original value of the {@link DateStart} property if the event is - * recurring and has been modified. Used in conjunction with the {@link Uid} - * and {@link Sequence} properties to uniquely identify a recurrence - * instance. - * @param originalStartDate the original start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public RecurrenceId setRecurrenceId(Date originalStartDate) { - RecurrenceId prop = (originalStartDate == null) ? null : new RecurrenceId(originalStartDate); - setRecurrenceId(prop); - return prop; - } - - /** - * Gets a URL to a resource that contains additional information about the - * event. - * @return the URL or null if not set - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - */ - public Url getUrl() { - return getProperty(Url.class); - } - - /** - * Sets a URL to a resource that contains additional information about the - * event. - * @param url the URL or null to remove - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - */ - public void setUrl(Url url) { - setProperty(Url.class, url); - } - - /** - * Sets a URL to a resource that contains additional information about the - * event. - * @param url the URL (e.g. "http://example.com/resource.ics") or null to - * remove - * @return the property that was created - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - */ - public Url setUrl(String url) { - Url prop = (url == null) ? null : new Url(url); - setUrl(prop); - return prop; - } - - /** - * Gets how often the event repeats. - * @return the recurrence rule or null if not set - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ - public RecurrenceRule getRecurrenceRule() { - return getProperty(RecurrenceRule.class); - } - - /** - * Sets how often the event repeats. - * @param recur the recurrence rule or null to remove - * @return the property that was created - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ - public RecurrenceRule setRecurrenceRule(Recurrence recur) { - RecurrenceRule prop = (recur == null) ? null : new RecurrenceRule(recur); - setRecurrenceRule(prop); - return prop; - } - - /** - * Sets how often the event repeats. - * @param recurrenceRule the recurrence rule or null to remove - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ - public void setRecurrenceRule(RecurrenceRule recurrenceRule) { - setProperty(RecurrenceRule.class, recurrenceRule); - } - - /** - * Gets the date that the event ends. - * @return the end date or null if not set - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - * @see vCal 1.0 p.31 - */ - public DateEnd getDateEnd() { - return getProperty(DateEnd.class); - } - - /** - * Sets the date that the event ends. This must NOT be set if a - * {@link DurationProperty} is defined. - * @param dateEnd the end date or null to remove - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - * @see vCal 1.0 p.31 - */ - public void setDateEnd(DateEnd dateEnd) { - setProperty(DateEnd.class, dateEnd); - } - - /** - * Sets the date that the event ends. This must NOT be set if a - * {@link DurationProperty} is defined. - * @param dateEnd the end date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - * @see vCal 1.0 p.31 - */ - public DateEnd setDateEnd(Date dateEnd) { - return setDateEnd(dateEnd, true); - } - - /** - * Sets the date that the event ends. This must NOT be set if a - * {@link DurationProperty} is defined. - * @param dateEnd the end date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - * @see vCal 1.0 p.31 - */ - public DateEnd setDateEnd(Date dateEnd, boolean hasTime) { - DateEnd prop = (dateEnd == null) ? null : new DateEnd(dateEnd, hasTime); - setDateEnd(prop); - return prop; - } - - /** - * Gets the duration of the event. - * @return the duration or null if not set - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public DurationProperty getDuration() { - return getProperty(DurationProperty.class); - } - - /** - * Sets the duration of the event. This must NOT be set if a {@link DateEnd} - * is defined. - * @param duration the duration or null to remove - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public void setDuration(DurationProperty duration) { - setProperty(DurationProperty.class, duration); - } - - /** - * Sets the duration of the event. This must NOT be set if a {@link DateEnd} - * is defined. - * @param duration the duration or null to remove - * @return the property that was created - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public DurationProperty setDuration(Duration duration) { - DurationProperty prop = (duration == null) ? null : new DurationProperty(duration); - setDuration(prop); - return prop; - } - - /** - * Gets the date-time that the event was initially created. - * @return the creation date-time or null if not set - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ - public Created getCreated() { - return getProperty(Created.class); - } - - /** - * Sets the date-time that the event was initially created. - * @param created the creation date-time or null to remove - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ - public void setCreated(Created created) { - setProperty(Created.class, created); - } - - /** - * Sets the date-time that the event was initially created. - * @param created the creation date-time or null to remove - * @return the property that was created - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ - public Created setCreated(Date created) { - Created prop = (created == null) ? null : new Created(created); - setCreated(prop); - return prop; - } - - /** - * Gets the date-time that the event was last changed. - * @return the last modified date or null if not set - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - * @see vCal 1.0 p.31 - */ - public LastModified getLastModified() { - return getProperty(LastModified.class); - } - - /** - * Sets the date-time that event was last changed. - * @param lastModified the last modified date or null to remove - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - * @see vCal 1.0 p.31 - */ - public void setLastModified(LastModified lastModified) { - setProperty(LastModified.class, lastModified); - } - - /** - * Sets the date-time that the event was last changed. - * @param lastModified the last modified date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - * @see vCal 1.0 p.31 - */ - public LastModified setLastModified(Date lastModified) { - LastModified prop = (lastModified == null) ? null : new LastModified(lastModified); - setLastModified(prop); - return prop; - } - - /** - * Gets the revision number of the event. The organizer can increment this - * number every time he or she makes a significant change. - * @return the sequence number - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public Sequence getSequence() { - return getProperty(Sequence.class); - } - - /** - * Sets the revision number of the event. The organizer can increment this - * number every time he or she makes a significant change. - * @param sequence the sequence number - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public void setSequence(Sequence sequence) { - setProperty(Sequence.class, sequence); - } - - /** - * Sets the revision number of the event. The organizer can increment this - * number every time he or she makes a significant change. - * @param sequence the sequence number - * @return the property that was created - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public Sequence setSequence(Integer sequence) { - Sequence prop = (sequence == null) ? null : new Sequence(sequence); - setSequence(prop); - return prop; - } - - /** - * Increments the revision number of the event. The organizer can increment - * this number every time he or she makes a significant change. - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public void incrementSequence() { - Sequence sequence = getSequence(); - if (sequence == null) { - setSequence(1); - } else { - sequence.increment(); - } - } - - /** - * Gets any attachments that are associated with the event. - * @return the attachments (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - * @see vCal 1.0 p.25 - */ - public List getAttachments() { - return getProperties(Attachment.class); - } - - /** - * Adds an attachment to the event. - * @param attachment the attachment to add - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - * @see vCal 1.0 p.25 - */ - public void addAttachment(Attachment attachment) { - addProperty(attachment); - } - - /** - * Gets the people who are attending the event. - * @return the attendees (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ - public List getAttendees() { - return getProperties(Attendee.class); - } - - /** - * Adds a person who is attending the event. - * @param attendee the attendee - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ - public void addAttendee(Attendee attendee) { - addProperty(attendee); - } - - /** - * Adds a person who is attending the event. - * @param email the attendee's email address - * @return the property that was created - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ - public Attendee addAttendee(String email) { - Attendee prop = new Attendee(null, email); - addAttendee(prop); - return prop; - } - - /** - * Gets a list of "tags" or "keywords" that describe the event. - * @return the categories (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public List getCategories() { - return getProperties(Categories.class); - } - - /** - * Adds a list of "tags" or "keywords" that describe the event. Note that a - * single property can hold multiple keywords. - * @param categories the categories to add - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public void addCategories(Categories categories) { - addProperty(categories); - } - - /** - * Adds a list of "tags" or "keywords" that describe the event. - * @param categories the categories to add - * @return the property that was created - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public Categories addCategories(String... categories) { - Categories prop = new Categories(categories); - addCategories(prop); - return prop; - } - - /** - * Adds a list of "tags" or "keywords" that describe the event. - * @param categories the categories to add - * @return the property that was created - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public Categories addCategories(List categories) { - Categories prop = new Categories(categories); - addCategories(prop); - return prop; - } - - /** - * Gets the comments attached to the event. - * @return the comments (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public List getComments() { - return getProperties(Comment.class); - } - - /** - * Adds a comment to the event. - * @param comment the comment to add - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public void addComment(Comment comment) { - addProperty(comment); - } - - /** - * Adds a comment to the event. - * @param comment the comment to add - * @return the property that was created - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public Comment addComment(String comment) { - Comment prop = new Comment(comment); - addComment(prop); - return prop; - } - - /** - * Gets the contacts associated with the event. - * @return the contacts (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public List getContacts() { - return getProperties(Contact.class); - } - - /** - * Adds a contact to the event. - * @param contact the contact - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public void addContact(Contact contact) { - addProperty(contact); - } - - /** - * Adds a contact to the event. - * @param contact the contact (e.g. "ACME Co - (123) 555-1234") - * @return the property that was created - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public Contact addContact(String contact) { - Contact prop = new Contact(contact); - addContact(prop); - return prop; - } - - /** - * Gets the list of exceptions to the recurrence rule defined in the event - * (if one is defined). - * @return the list of exceptions (any changes made this list will affect - * the parent component object and vice versa) - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - * @see vCal 1.0 p.31 - */ - public List getExceptionDates() { - return getProperties(ExceptionDates.class); - } - - /** - * Adds a list of exceptions to the recurrence rule defined in the event (if - * one is defined). Note that this property can contain multiple dates. - * @param exceptionDates the list of exceptions - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - * @see vCal 1.0 p.31 - */ - public void addExceptionDates(ExceptionDates exceptionDates) { - addProperty(exceptionDates); - } - - /** - * Gets the response to a scheduling request. - * @return the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public RequestStatus getRequestStatus() { - return getProperty(RequestStatus.class); - } - - /** - * Sets the response to a scheduling request. - * @param requestStatus the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public void setRequestStatus(RequestStatus requestStatus) { - setProperty(RequestStatus.class, requestStatus); - } - - /** - * Gets the components that the event is related to. - * @return the relationships (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ - public List getRelatedTo() { - return getProperties(RelatedTo.class); - } - - /** - * Adds a component that the event is related to. - * @param relatedTo the relationship - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ - public void addRelatedTo(RelatedTo relatedTo) { - //TODO create a method that accepts a component and make the RelatedTo property invisible to the user - //@formatter:off - /* - * addRelation(RelationshipType relType, ICalComponent component) { - * RelatedTo prop = new RelatedTo(component.getUid().getValue()); - * prop.setRelationshipType(relType); - * addProperty(prop); - * } - */ - //@formatter:on - addProperty(relatedTo); - } - - /** - * Adds a component that the event is related to. - * @param uid the UID of the other component - * @return the property that was created - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ - public RelatedTo addRelatedTo(String uid) { - RelatedTo prop = new RelatedTo(uid); - addRelatedTo(prop); - return prop; - } - - /** - * Gets the resources that are needed for the event. - * @return the resources (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public List getResources() { - return getProperties(Resources.class); - } - - /** - * Adds a list of resources that are needed for the event. Note that a - * single property can hold multiple resources. - * @param resources the resources to add - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public void addResources(Resources resources) { - addProperty(resources); - } - - /** - * Adds a list of resources that are needed for the event. - * @param resources the resources to add (e.g. "easel", "projector") - * @return the property that was created - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public Resources addResources(String... resources) { - Resources prop = new Resources(resources); - addResources(prop); - return prop; - } - - /** - * Adds a list of resources that are needed for the event. - * @param resources the resources to add (e.g. "easel", "projector") - * @return the property that was created - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public Resources addResources(List resources) { - Resources prop = new Resources(resources); - addResources(prop); - return prop; - } - - /** - * Gets the list of dates/periods that help define the recurrence rule of - * this event (if one is defined). - * @return the recurrence dates (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - * @see vCal 1.0 p.34 - */ - public List getRecurrenceDates() { - return getProperties(RecurrenceDates.class); - } - - /** - * Adds a list of dates/periods that help define the recurrence rule of this - * event (if one is defined). - * @param recurrenceDates the recurrence dates - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - * @see vCal 1.0 p.34 - */ - public void addRecurrenceDates(RecurrenceDates recurrenceDates) { - addProperty(recurrenceDates); - } - - /** - * Gets the alarms that are assigned to this event. - * @return the alarms (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.71-6 - * @see RFC 2445 - * p.67-73 - */ - public List getAlarms() { - return getComponents(VAlarm.class); - } - - /** - * Adds an alarm to this event. - * @param alarm the alarm - * @see RFC 5545 - * p.71-6 - * @see RFC 2445 - * p.67-73 - */ - public void addAlarm(VAlarm alarm) { - addComponent(alarm); - } - - /** - *

- * Gets the exceptions for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @return the exception rules (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ - public List getExceptionRules() { - return getProperties(ExceptionRule.class); - } - - /** - *

- * Adds an exception for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @param recur the exception rule to add - * @return the property that was created - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ - public ExceptionRule addExceptionRule(Recurrence recur) { - ExceptionRule prop = new ExceptionRule(recur); - addExceptionRule(prop); - return prop; - } - - /** - *

- * Adds an exception for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @param exceptionRule the exception rule to add - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ - public void addExceptionRule(ExceptionRule exceptionRule) { - addProperty(exceptionRule); - } - - /** - * Gets the color that clients may use when displaying the event (for - * example, a background color). - * @return the property or null if not set - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color getColor() { - return getProperty(Color.class); - } - - /** - * Sets the color that clients may use when displaying the event (for - * example, a background color). - * @param color the property or null to remove - * @see draft-ietf-calext-extensions-01 - * p.79 - */ - public void setColor(Color color) { - setProperty(Color.class, color); - } - - /** - * Sets the color that clients may use when displaying the event (for - * example, a background color). - * @param color the color name (case insensitive) or null to remove. - * Acceptable values are defined in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color setColor(String color) { - Color prop = (color == null) ? null : new Color(color); - setColor(prop); - return prop; - } - - /** - * Gets the images that are associated with the event. - * @return the images (any changes made this list will affect the parent - * component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public List getImages() { - return getProperties(Image.class); - } - - /** - * Adds an image that is associated with the event. - * @param image the image - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public void addImage(Image image) { - addProperty(image); - } - - /** - * Gets information related to the event's conference system. - * @return the conferences (any changes made this list will affect the - * parent component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.11 - */ - public List getConferences() { - return getProperties(Conference.class); - } - - /** - * Adds information related to the event's conference system. - * @param conference the conference - * @see draft-ietf-calext-extensions-01 - * p.11 - */ - public void addConference(Conference conference) { - addProperty(conference); - } - - /** - *

- * Creates an iterator that computes the dates defined by the - * {@link RecurrenceRule} and {@link RecurrenceDates} properties (if - * present), and excludes those dates which are defined by the - * {@link ExceptionRule} and {@link ExceptionDates} properties (if present). - *

- *

- * In order for {@link RecurrenceRule} and {@link ExceptionRule} properties - * to be included in this iterator, a {@link DateStart} property must be - * defined. - *

- *

- * {@link Period} values in {@link RecurrenceDates} properties are not - * supported and are ignored. - *

- * @param timezone the timezone to iterate in. This is needed in order to - * adjust for when the iterator passes over a daylight savings boundary. - * This parameter is ignored if the start date does not have a time - * component. - * @return the iterator - */ - public DateIterator getDateIterator(TimeZone timezone) { - return Google2445Utils.getDateIterator(this, timezone); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version != ICalVersion.V1_0) { - checkRequiredCardinality(warnings, Uid.class, DateTimeStamp.class); - checkOptionalCardinality(warnings, Classification.class, Created.class, Description.class, Geo.class, LastModified.class, Location.class, Organizer.class, Priority.class, Status.class, Summary.class, Transparency.class, Url.class, RecurrenceId.class); - } - - checkOptionalCardinality(warnings, Color.class); - - Status[] validStatuses; - switch (version) { - case V1_0: - validStatuses = new Status[] { Status.tentative(), Status.confirmed(), Status.declined(), Status.needsAction(), Status.sent(), Status.delegated() }; - break; - default: - validStatuses = new Status[] { Status.tentative(), Status.confirmed(), Status.cancelled() }; - break; - } - checkStatus(warnings, validStatuses); - - ICalDate dateStart = getValue(getDateStart()); - ICalDate dateEnd = getValue(getDateEnd()); - - //DTSTART is always required, unless there is a METHOD property at the iCal root - ICalComponent ical = components.get(0); - if (version != ICalVersion.V1_0 && dateStart == null && ical.getProperty(Method.class) == null) { - warnings.add(new ValidationWarning(14)); - } - - //DTSTART is required if DTEND exists - if (dateEnd != null && dateStart == null) { - warnings.add(new ValidationWarning(15)); - } - - if (dateStart != null && dateEnd != null) { - //DTSTART must come before DTEND - if (dateStart.compareTo(dateEnd) > 0) { - warnings.add(new ValidationWarning(16)); - } - - //DTSTART and DTEND must have the same data type - if (dateStart.hasTime() != dateEnd.hasTime()) { - warnings.add(new ValidationWarning(17)); - } - } - - //DTEND and DURATION cannot both exist - if (dateEnd != null && getDuration() != null) { - warnings.add(new ValidationWarning(18)); - } - - //DTSTART and RECURRENCE-ID must have the same data type - ICalDate recurrenceId = getValue(getRecurrenceId()); - if (recurrenceId != null && dateStart != null && dateStart.hasTime() != recurrenceId.hasTime()) { - warnings.add(new ValidationWarning(19)); - } - - //BYHOUR, BYMINUTE, and BYSECOND cannot be specified in RRULE if DTSTART's data type is "date" - //RFC 5545 p. 167 - Recurrence rrule = getValue(getRecurrenceRule()); - if (dateStart != null && rrule != null) { - if (!dateStart.hasTime() && (!rrule.getByHour().isEmpty() || !rrule.getByMinute().isEmpty() || !rrule.getBySecond().isEmpty())) { - warnings.add(new ValidationWarning(5)); - } - } - - //there *should* be only 1 instance of RRULE - //RFC 5545 p. 167 - if (getProperties(RecurrenceRule.class).size() > 1) { - warnings.add(new ValidationWarning(6)); - } - } - - @Override - public VEvent copy() { - return new VEvent(this); - } -} diff --git a/app/src/main/java/biweekly/component/VFreeBusy.java b/app/src/main/java/biweekly/component/VFreeBusy.java deleted file mode 100644 index c3afbba9e5..0000000000 --- a/app/src/main/java/biweekly/component/VFreeBusy.java +++ /dev/null @@ -1,655 +0,0 @@ -package biweekly.component; - -import static biweekly.property.ValuedProperty.getValue; - -import java.util.Date; -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.parameter.FreeBusyType; -import biweekly.property.Attendee; -import biweekly.property.Comment; -import biweekly.property.Contact; -import biweekly.property.DateEnd; -import biweekly.property.DateStart; -import biweekly.property.DateTimeStamp; -import biweekly.property.FreeBusy; -import biweekly.property.LastModified; -import biweekly.property.Method; -import biweekly.property.Organizer; -import biweekly.property.RequestStatus; -import biweekly.property.Uid; -import biweekly.property.Url; -import biweekly.util.Duration; -import biweekly.util.ICalDate; -import biweekly.util.Period; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a collection of time ranges that describe when a person is available - * and unavailable. - *

- *

- * Examples: - *

- * - *
- * VFreeBusy freebusy = new VFreeBusy();
- * 
- * Date start = ...
- * Date end = ...
- * freebusy.addFreeBusy(FreeBusyType.FREE, start, end);
- * 
- * start = ...
- * Duration duration = Duration.builder().hours(2).build();
- * freebusy.addFreeBusy(FreeBusyType.BUSY, start, duration);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.59-62 - * @see RFC 2445 - * p.58-60 - */ -/* - * Note: References to the vCal 1.0 spec are omitted from the property - * getter/setter method Javadocs because vCal does not use the VFREEBUSY - * component. - */ -public class VFreeBusy extends ICalComponent { - /** - *

- * Creates a new free/busy component. - *

- *

- * The following properties are added to the component when it is created: - *

- *
    - *
  • {@link Uid}: Set to a UUID.
  • - *
  • {@link DateTimeStamp}: Set to the current time.
  • - *
- */ - public VFreeBusy() { - setUid(Uid.random()); - setDateTimeStamp(new Date()); - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public VFreeBusy(VFreeBusy original) { - super(original); - } - - /** - * Gets the unique identifier for this free/busy entry. This component - * object comes populated with a UID on creation. This is a required - * property. - * @return the UID or null if not set - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - */ - public Uid getUid() { - return getProperty(Uid.class); - } - - /** - * Sets the unique identifier for this free/busy entry. This component - * object comes populated with a UID on creation. This is a required - * property. - * @param uid the UID or null to remove - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - */ - public void setUid(Uid uid) { - setProperty(Uid.class, uid); - } - - /** - * Sets the unique identifier for this free/busy entry. This component - * object comes populated with a UID on creation. This is a required - * property. - * @param uid the UID or null to remove - * @return the property that was created - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - */ - public Uid setUid(String uid) { - Uid prop = (uid == null) ? null : new Uid(uid); - setUid(prop); - return prop; - } - - /** - * Gets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the free/busy - * entry was last modified (the {@link LastModified} property also holds - * this information). This free/busy object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @return the date time stamp or null if not set - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp getDateTimeStamp() { - return getProperty(DateTimeStamp.class); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the free/busy - * entry was last modified (the {@link LastModified} property also holds - * this information). This free/busy object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public void setDateTimeStamp(DateTimeStamp dateTimeStamp) { - setProperty(DateTimeStamp.class, dateTimeStamp); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the free/busy - * entry was last modified (the {@link LastModified} property also holds - * this information). This free/busy object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @return the property that was created - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp setDateTimeStamp(Date dateTimeStamp) { - DateTimeStamp prop = (dateTimeStamp == null) ? null : new DateTimeStamp(dateTimeStamp); - setDateTimeStamp(prop); - return prop; - } - - /** - * Gets the contact associated with the free/busy entry. - * @return the contact or null if not set - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public Contact getContact() { - return getProperty(Contact.class); - } - - /** - * Sets the contact for the free/busy entry. - * @param contact the contact or null to remove - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public void setContact(Contact contact) { - setProperty(Contact.class, contact); - } - - /** - * Sets the contact for the free/busy entry. - * @param contact the contact (e.g. "ACME Co - (123) 555-1234") - * @return the property that was created - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public Contact addContact(String contact) { - Contact prop = new Contact(contact); - setContact(prop); - return prop; - } - - /** - * Gets the date that the free/busy entry starts. - * @return the start date or null if not set - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart getDateStart() { - return getProperty(DateStart.class); - } - - /** - * Sets the date that the free/busy entry starts. - * @param dateStart the start date or null to remove - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public void setDateStart(DateStart dateStart) { - setProperty(DateStart.class, dateStart); - } - - /** - * Sets the date that the free/busy entry starts. - * @param dateStart the start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart setDateStart(Date dateStart) { - return setDateStart(dateStart, true); - } - - /** - * Sets the date that the free/busy entry starts. - * @param dateStart the start date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart setDateStart(Date dateStart, boolean hasTime) { - DateStart prop = (dateStart == null) ? null : new DateStart(dateStart, hasTime); - setDateStart(prop); - return prop; - } - - /** - * Gets the date that the free/busy entry ends. - * @return the end date or null if not set - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - */ - public DateEnd getDateEnd() { - return getProperty(DateEnd.class); - } - - /** - * Sets the date that the free/busy entry ends. - * @param dateEnd the end date or null to remove - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - */ - public void setDateEnd(DateEnd dateEnd) { - setProperty(DateEnd.class, dateEnd); - } - - /** - * Sets the date that the free/busy entry ends. - * @param dateEnd the end date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - */ - public DateEnd setDateEnd(Date dateEnd) { - return setDateEnd(dateEnd, true); - } - - /** - * Sets the date that the free/busy entry ends. - * @param dateEnd the end date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.95-6 - * @see RFC 2445 - * p.91-2 - */ - public DateEnd setDateEnd(Date dateEnd, boolean hasTime) { - DateEnd prop = (dateEnd == null) ? null : new DateEnd(dateEnd, hasTime); - setDateEnd(prop); - return prop; - } - - /** - * Gets the person requesting the free/busy time. - * @return the person requesting the free/busy time or null if not set - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer getOrganizer() { - return getProperty(Organizer.class); - } - - /** - * Sets the person requesting the free/busy time. - * @param organizer the person requesting the free/busy time or null to - * remove - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public void setOrganizer(Organizer organizer) { - setProperty(Organizer.class, organizer); - } - - /** - * Sets the person requesting the free/busy time. - * @param email the email address of the person requesting the free/busy - * time (e.g. "johndoe@example.com") or null to remove - * @return the property that was created - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer setOrganizer(String email) { - Organizer prop = (email == null) ? null : new Organizer(null, email); - setOrganizer(prop); - return prop; - } - - /** - * Gets a URL to a resource that contains additional information about the - * free/busy entry. - * @return the URL or null if not set - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - */ - public Url getUrl() { - return getProperty(Url.class); - } - - /** - * Sets a URL to a resource that contains additional information about the - * free/busy entry. - * @param url the URL or null to remove - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - */ - public void setUrl(Url url) { - setProperty(Url.class, url); - } - - /** - * Sets a URL to a resource that contains additional information about the - * free/busy entry. - * @param url the URL (e.g. "http://example.com/resource.ics") or null to - * remove - * @return the property that was created - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - */ - public Url setUrl(String url) { - Url prop = (url == null) ? null : new Url(url); - setUrl(prop); - return prop; - } - - /** - * Gets the people who are involved in the free/busy entry. - * @return the attendees (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public List getAttendees() { - return getProperties(Attendee.class); - } - - /** - * Adds a person who is involved in the free/busy entry. - * @param attendee the attendee - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public void addAttendee(Attendee attendee) { - addProperty(attendee); - } - - /** - * Gets the comments attached to the free/busy entry. - * @return the comments (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public List getComments() { - return getProperties(Comment.class); - } - - /** - * Adds a comment to the free/busy entry. - * @param comment the comment to add - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public void addComment(Comment comment) { - addProperty(comment); - } - - /** - * Adds a comment to the free/busy entry. - * @param comment the comment to add - * @return the property that was created - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public Comment addComment(String comment) { - Comment prop = new Comment(comment); - addComment(prop); - return prop; - } - - /** - * Gets the person's availabilities over certain time periods (for example, - * "free" between 1pm-3pm, but "busy" between 3pm-4pm). - * @return the availabilities (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.100-1 - * @see RFC 2445 - * p.95-6 - */ - public List getFreeBusy() { - return getProperties(FreeBusy.class); - } - - /** - * Adds a list of time periods for which the person is free or busy (for - * example, "free" between 1pm-3pm and 4pm-5pm). Note that a - * {@link FreeBusy} property can contain multiple time periods, but only one - * availability type (e.g. "busy"). - * @param freeBusy the availabilities - * @see RFC 5545 - * p.100-1 - * @see RFC 2445 - * p.95-6 - */ - public void addFreeBusy(FreeBusy freeBusy) { - addProperty(freeBusy); - } - - /** - * Adds a single time period for which the person is free or busy (for - * example, "free" between 1pm-3pm). This method will look for an existing - * property that has the given {@link FreeBusyType} and add the time period - * to it, or create a new property is one cannot be found. - * @param type the availability type (e.g. "free" or "busy") - * @param start the start date-time - * @param end the end date-time - * @return the property that was created/modified - * @see RFC 5545 - * p.100-1 - * @see RFC 2445 - * p.95-6 - */ - public FreeBusy addFreeBusy(FreeBusyType type, Date start, Date end) { - FreeBusy found = findByFreeBusyType(type); - found.getValues().add(new Period(start, end)); - return found; - } - - /** - * Adds a single time period for which the person is free or busy (for - * example, "free" for 2 hours after 1pm). This method will look for an - * existing property that has the given {@link FreeBusyType} and add the - * time period to it, or create a new property is one cannot be found. - * @param type the availability type (e.g. "free" or "busy") - * @param start the start date-time - * @param duration the length of time - * @return the property that was created/modified - * @see RFC 5545 - * p.100-1 - * @see RFC 2445 - * p.95-6 - */ - public FreeBusy addFreeBusy(FreeBusyType type, Date start, Duration duration) { - FreeBusy found = findByFreeBusyType(type); - found.getValues().add(new Period(start, duration)); - return found; - } - - private FreeBusy findByFreeBusyType(FreeBusyType type) { - for (FreeBusy freeBusy : getFreeBusy()) { - if (freeBusy.getType() == type) { - return freeBusy; - } - } - - FreeBusy freeBusy = new FreeBusy(); - freeBusy.setType(type); - addFreeBusy(freeBusy); - return freeBusy; - } - - /** - * Gets the response to a scheduling request. - * @return the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public RequestStatus getRequestStatus() { - return getProperty(RequestStatus.class); - } - - /** - * Sets the response to a scheduling request. - * @param requestStatus the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public void setRequestStatus(RequestStatus requestStatus) { - setProperty(RequestStatus.class, requestStatus); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version == ICalVersion.V1_0) { - warnings.add(new ValidationWarning(48, version)); - } - - checkRequiredCardinality(warnings, Uid.class, DateTimeStamp.class); - checkOptionalCardinality(warnings, Contact.class, DateStart.class, DateEnd.class, Organizer.class, Url.class); - - ICalDate dateStart = getValue(getDateStart()); - ICalDate dateEnd = getValue(getDateEnd()); - - //DTSTART is required if DTEND exists - if (dateEnd != null && dateStart == null) { - warnings.add(new ValidationWarning(15)); - } - - //DTSTART and DTEND must contain a time component - if (dateStart != null && !dateStart.hasTime()) { - warnings.add(new ValidationWarning(20, DateStart.class.getSimpleName())); - } - if (dateEnd != null && !dateEnd.hasTime()) { - warnings.add(new ValidationWarning(20, DateEnd.class.getSimpleName())); - } - - //DTSTART must come before DTEND - if (dateStart != null && dateEnd != null && dateStart.compareTo(dateEnd) >= 0) { - warnings.add(new ValidationWarning(16)); - } - } - - @Override - public VFreeBusy copy() { - return new VFreeBusy(this); - } -} diff --git a/app/src/main/java/biweekly/component/VJournal.java b/app/src/main/java/biweekly/component/VJournal.java deleted file mode 100644 index 0ad587dff5..0000000000 --- a/app/src/main/java/biweekly/component/VJournal.java +++ /dev/null @@ -1,1259 +0,0 @@ -package biweekly.component; - -import static biweekly.property.ValuedProperty.getValue; - -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.property.Attachment; -import biweekly.property.Attendee; -import biweekly.property.Categories; -import biweekly.property.Classification; -import biweekly.property.Color; -import biweekly.property.Comment; -import biweekly.property.Contact; -import biweekly.property.Created; -import biweekly.property.DateStart; -import biweekly.property.DateTimeStamp; -import biweekly.property.Description; -import biweekly.property.ExceptionDates; -import biweekly.property.ExceptionRule; -import biweekly.property.Image; -import biweekly.property.LastModified; -import biweekly.property.Method; -import biweekly.property.Organizer; -import biweekly.property.RecurrenceDates; -import biweekly.property.RecurrenceId; -import biweekly.property.RecurrenceRule; -import biweekly.property.RelatedTo; -import biweekly.property.RequestStatus; -import biweekly.property.Sequence; -import biweekly.property.Status; -import biweekly.property.Summary; -import biweekly.property.Uid; -import biweekly.property.Url; -import biweekly.util.Google2445Utils; -import biweekly.util.ICalDate; -import biweekly.util.Period; -import biweekly.util.Recurrence; -import biweekly.util.com.google.ical.compat.javautil.DateIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a journal entry. - *

- *

- * Examples: - *

- * - *
- * VJournal journal = new VJournal();
- * journal.setSummary("Team Meeting");
- * journal.setDescription("The following items were discussed: ...");
- * byte[] slides = ...
- * journal.addAttachment(new Attachment("application/vnd.ms-powerpoint", slides));
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.57-9 - * @see RFC 2445 p.56-7 - */ -/* - * Note: References to the vCal 1.0 spec are omitted from the property - * getter/setter method Javadocs because vCal does not use the VJOURNAL - * component. - */ -public class VJournal extends ICalComponent { - /** - *

- * Creates a new journal entry. - *

- *

- * The following properties are added to the component when it is created: - *

- *
    - *
  • {@link Uid}: Set to a UUID.
  • - *
  • {@link DateTimeStamp}: Set to the current time.
  • - *
- */ - public VJournal() { - setUid(Uid.random()); - setDateTimeStamp(new Date()); - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public VJournal(VJournal original) { - super(original); - } - - /** - * Gets the unique identifier for this journal entry. This component object - * comes populated with a UID on creation. This is a required - * property. - * @return the UID or null if not set - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - */ - public Uid getUid() { - return getProperty(Uid.class); - } - - /** - * Sets the unique identifier for this journal entry. This component object - * comes populated with a UID on creation. This is a required - * property. - * @param uid the UID or null to remove - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - */ - public void setUid(Uid uid) { - setProperty(Uid.class, uid); - } - - /** - * Sets the unique identifier for this journal entry. This component object - * comes populated with a UID on creation. This is a required - * property. - * @param uid the UID or null to remove - * @return the property that was created - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - */ - public Uid setUid(String uid) { - Uid prop = (uid == null) ? null : new Uid(uid); - setUid(prop); - return prop; - } - - /** - * Gets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the journal - * entry was last modified (the {@link LastModified} property also holds - * this information). This journal entry object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @return the date time stamp or null if not set - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp getDateTimeStamp() { - return getProperty(DateTimeStamp.class); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the journal - * entry was last modified (the {@link LastModified} property also holds - * this information). This journal entry object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public void setDateTimeStamp(DateTimeStamp dateTimeStamp) { - setProperty(DateTimeStamp.class, dateTimeStamp); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the journal - * entry was last modified (the {@link LastModified} property also holds - * this information). This journal entry object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @return the property that was created - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp setDateTimeStamp(Date dateTimeStamp) { - DateTimeStamp prop = (dateTimeStamp == null) ? null : new DateTimeStamp(dateTimeStamp); - setDateTimeStamp(prop); - return prop; - } - - /** - * Gets the level of sensitivity of the journal entry. If not specified, the - * data within the journal entry should be considered "public". - * @return the classification level or null if not set - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - */ - public Classification getClassification() { - return getProperty(Classification.class); - } - - /** - * Sets the level of sensitivity of the journal entry. If not specified, the - * data within the journal entry should be considered "public". - * @param classification the classification level or null to remove - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - */ - public void setClassification(Classification classification) { - setProperty(Classification.class, classification); - } - - /** - * Sets the level of sensitivity of the journal entry. If not specified, the - * data within the journal entry should be considered "public". - * @param classification the classification level (e.g. "CONFIDENTIAL") or - * null to remove - * @return the property that was created - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - */ - public Classification setClassification(String classification) { - Classification prop = (classification == null) ? null : new Classification(classification); - setClassification(prop); - return prop; - } - - /** - * Gets the date-time that the journal entry was initially created. - * @return the creation date-time or null if not set - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - */ - public Created getCreated() { - return getProperty(Created.class); - } - - /** - * Sets the date-time that the journal entry was initially created. - * @param created the creation date-time or null to remove - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - */ - public void setCreated(Created created) { - setProperty(Created.class, created); - } - - /** - * Sets the date-time that the journal entry was initially created. - * @param created the creation date-time or null to remove - * @return the property that was created - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - */ - public Created setCreated(Date created) { - Created prop = (created == null) ? null : new Created(created); - setCreated(prop); - return prop; - } - - /** - * Gets the date that the journal entry starts. - * @return the start date or null if not set - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart getDateStart() { - return getProperty(DateStart.class); - } - - /** - * Sets the date that the journal entry starts. - * @param dateStart the start date or null to remove - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public void setDateStart(DateStart dateStart) { - setProperty(DateStart.class, dateStart); - } - - /** - * Sets the date that the journal entry starts. - * @param dateStart the start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart setDateStart(Date dateStart) { - return setDateStart(dateStart, true); - } - - /** - * Sets the date that the journal entry starts. - * @param dateStart the start date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - */ - public DateStart setDateStart(Date dateStart, boolean hasTime) { - DateStart prop = (dateStart == null) ? null : new DateStart(dateStart, hasTime); - setDateStart(prop); - return prop; - } - - /** - * Gets the date-time that the journal entry was last changed. - * @return the last modified date or null if not set - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - */ - public LastModified getLastModified() { - return getProperty(LastModified.class); - } - - /** - * Sets the date-time that the journal entry was last changed. - * @param lastModified the last modified date or null to remove - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - */ - public void setLastModified(LastModified lastModified) { - setProperty(LastModified.class, lastModified); - } - - /** - * Sets the date-time that the journal entry was last changed. - * @param lastModified the last modified date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - */ - public LastModified setLastModified(Date lastModified) { - LastModified prop = (lastModified == null) ? null : new LastModified(lastModified); - setLastModified(prop); - return prop; - } - - /** - * Gets the organizer of the journal entry. - * @return the organizer or null if not set - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer getOrganizer() { - return getProperty(Organizer.class); - } - - /** - * Sets the organizer of the journal entry. - * @param organizer the organizer or null to remove - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public void setOrganizer(Organizer organizer) { - setProperty(Organizer.class, organizer); - } - - /** - * Sets the organizer of the journal entry. - * @param email the organizer's email address (e.g. "johndoe@example.com") - * or null to remove - * @return the property that was created - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer setOrganizer(String email) { - Organizer prop = (email == null) ? null : new Organizer(null, email); - setOrganizer(prop); - return prop; - } - - /** - * Gets the original value of the {@link DateStart} property if the event is - * recurring and has been modified. Used in conjunction with the {@link Uid} - * and {@link Sequence} properties to uniquely identify a recurrence - * instance. - * @return the recurrence ID or null if not set - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public RecurrenceId getRecurrenceId() { - return getProperty(RecurrenceId.class); - } - - /** - * Sets the original value of the {@link DateStart} property if the event is - * recurring and has been modified. Used in conjunction with the {@link Uid} - * and {@link Sequence} properties to uniquely identify a recurrence - * instance. - * @param recurrenceId the recurrence ID or null to remove - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public void setRecurrenceId(RecurrenceId recurrenceId) { - setProperty(RecurrenceId.class, recurrenceId); - } - - /** - * Sets the original value of the {@link DateStart} property if the journal - * entry is recurring and has been modified. Used in conjunction with the - * {@link Uid} and {@link Sequence} properties to uniquely identify a - * recurrence instance. - * @param originalStartDate the original start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public RecurrenceId setRecurrenceId(Date originalStartDate) { - RecurrenceId prop = (originalStartDate == null) ? null : new RecurrenceId(originalStartDate); - setRecurrenceId(prop); - return prop; - } - - /** - * Gets the revision number of the journal entry. The organizer can - * increment this number every time he or she makes a significant change. - * @return the sequence number - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - */ - public Sequence getSequence() { - return getProperty(Sequence.class); - } - - /** - * Sets the revision number of the journal entry. The organizer can - * increment this number every time he or she makes a significant change. - * @param sequence the sequence number - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - */ - public void setSequence(Sequence sequence) { - setProperty(Sequence.class, sequence); - } - - /** - * Sets the revision number of the journal entry. The organizer can - * increment this number every time he or she makes a significant change. - * @param sequence the sequence number - * @return the property that was created - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - */ - public Sequence setSequence(Integer sequence) { - Sequence prop = (sequence == null) ? null : new Sequence(sequence); - setSequence(prop); - return prop; - } - - /** - * Increments the revision number of the journal entry. The organizer can - * increment this number every time he or she makes a significant change. - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - */ - public void incrementSequence() { - Sequence sequence = getSequence(); - if (sequence == null) { - setSequence(1); - } else { - sequence.increment(); - } - } - - /** - * Gets the status of the journal entry. - * @return the status or null if not set - * @see RFC 5545 - * p.92-3 - * @see RFC 2445 - * p.88-9 - */ - public Status getStatus() { - return getProperty(Status.class); - } - - /** - *

- * Sets the status of the journal entry. - *

- *

- * Valid journal status codes are: - *

- *
    - *
  • DRAFT
  • - *
  • FINAL
  • - *
  • CANCELLED
  • - *
- * @param status the status or null to remove - * @see RFC 5545 - * p.92-3 - * @see RFC 2445 - * p.88-9 - */ - public void setStatus(Status status) { - setProperty(Status.class, status); - } - - /** - * Gets the summary of the journal entry. - * @return the summary or null if not set - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - */ - public Summary getSummary() { - return getProperty(Summary.class); - } - - /** - * Sets the summary of the journal entry. - * @param summary the summary or null to remove - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - */ - public void setSummary(Summary summary) { - setProperty(Summary.class, summary); - } - - /** - * Sets the summary of the journal entry. - * @param summary the summary or null to remove - * @return the property that was created - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - */ - public Summary setSummary(String summary) { - Summary prop = (summary == null) ? null : new Summary(summary); - setSummary(prop); - return prop; - } - - /** - * Gets a URL to a resource that contains additional information about the - * journal entry. - * @return the URL or null if not set - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - */ - public Url getUrl() { - return getProperty(Url.class); - } - - /** - * Sets a URL to a resource that contains additional information about the - * journal entry. - * @param url the URL or null to remove - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - */ - public void setUrl(Url url) { - setProperty(Url.class, url); - } - - /** - * Sets a URL to a resource that contains additional information about the - * journal entry. - * @param url the URL (e.g. "http://example.com/resource.ics") or null to - * remove - * @return the property that was created - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - */ - public Url setUrl(String url) { - Url prop = (url == null) ? null : new Url(url); - setUrl(prop); - return prop; - } - - /** - * Gets how often the journal entry repeats. - * @return the recurrence rule or null if not set - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - */ - public RecurrenceRule getRecurrenceRule() { - return getProperty(RecurrenceRule.class); - } - - /** - * Sets how often the journal entry repeats. - * @param recur the recurrence rule or null to remove - * @return the property that was created - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - */ - public RecurrenceRule setRecurrenceRule(Recurrence recur) { - RecurrenceRule prop = (recur == null) ? null : new RecurrenceRule(recur); - setRecurrenceRule(prop); - return prop; - } - - /** - * Sets how often the journal entry repeats. - * @param recurrenceRule the recurrence rule or null to remove - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - */ - public void setRecurrenceRule(RecurrenceRule recurrenceRule) { - setProperty(RecurrenceRule.class, recurrenceRule); - } - - /** - * Gets any attachments that are associated with the journal entry. - * @return the attachments (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - */ - public List getAttachments() { - return getProperties(Attachment.class); - } - - /** - * Adds an attachment to the journal entry. - * @param attachment the attachment to add - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - */ - public void addAttachment(Attachment attachment) { - addProperty(attachment); - } - - /** - * Gets the people who are involved in the journal entry. - * @return the attendees (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public List getAttendees() { - return getProperties(Attendee.class); - } - - /** - * Adds a person who is involved in the journal entry. - * @param attendee the attendee - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public void addAttendee(Attendee attendee) { - addProperty(attendee); - } - - /** - * Adds a person who is involved in the journal entry. - * @param email the attendee's email address - * @return the property that was created - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - */ - public Attendee addAttendee(String email) { - Attendee prop = new Attendee(null, email); - addAttendee(prop); - return prop; - } - - /** - * Gets a list of "tags" or "keywords" that describe the journal entry. - * @return the categories (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - */ - public List getCategories() { - return getProperties(Categories.class); - } - - /** - * Adds a list of "tags" or "keywords" that describe the journal entry. Note - * that a single property can hold multiple keywords. - * @param categories the categories to add - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - */ - public void addCategories(Categories categories) { - addProperty(categories); - } - - /** - * Adds a list of "tags" or "keywords" that describe the journal entry. - * @param categories the categories to add - * @return the property that was created - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - */ - public Categories addCategories(String... categories) { - Categories prop = new Categories(categories); - addCategories(prop); - return prop; - } - - /** - * Adds a list of "tags" or "keywords" that describe the journal entry. - * @param categories the categories to add - * @return the property that was created - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - */ - public Categories addCategories(List categories) { - Categories prop = new Categories(categories); - addCategories(prop); - return prop; - } - - /** - * Gets the comments attached to the journal entry. - * @return the comments (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public List getComments() { - return getProperties(Comment.class); - } - - /** - * Adds a comment to the journal entry. - * @param comment the comment to add - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public void addComment(Comment comment) { - addProperty(comment); - } - - /** - * Adds a comment to the journal entry. - * @param comment the comment to add - * @return the property that was created - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public Comment addComment(String comment) { - Comment prop = new Comment(comment); - addComment(prop); - return prop; - } - - /** - * Gets the contacts associated with the journal entry. - * @return the contacts (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public List getContacts() { - return getProperties(Contact.class); - } - - /** - * Adds a contact to the journal entry. - * @param contact the contact - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public void addContact(Contact contact) { - addProperty(contact); - } - - /** - * Adds a contact to the journal entry. - * @param contact the contact (e.g. "ACME Co - (123) 555-1234") - * @return the property that was created - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public Contact addContact(String contact) { - Contact prop = new Contact(contact); - addContact(prop); - return prop; - } - - /** - * Gets the detailed descriptions to the journal entry. The descriptions - * should be a more detailed version of the one provided by the - * {@link Summary} property. - * @return the descriptions (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - */ - public List getDescriptions() { - return getProperties(Description.class); - } - - /** - * Adds a detailed description to the journal entry. The description should - * be a more detailed version of the one provided by the {@link Summary} - * property. - * @param description the description - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - */ - public void addDescription(Description description) { - addProperty(description); - } - - /** - * Adds a detailed description to the journal entry. The description should - * be a more detailed version of the one provided by the {@link Summary} - * property. - * @param description the description - * @return the property that was created - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - */ - public Description addDescription(String description) { - Description prop = new Description(description); - addDescription(prop); - return prop; - } - - /** - * Gets the list of exceptions to the recurrence rule defined in the journal - * entry (if one is defined). - * @return the list of exceptions (any changes made this list will affect - * the parent component object and vice versa) - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - */ - public List getExceptionDates() { - return getProperties(ExceptionDates.class); - } - - /** - * Adds a list of exceptions to the recurrence rule defined in the journal - * entry (if one is defined). Note that this property can contain multiple - * dates. - * @param exceptionDates the list of exceptions - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - */ - public void addExceptionDates(ExceptionDates exceptionDates) { - addProperty(exceptionDates); - } - - /** - * Gets the components that the journal entry is related to. - * @return the relationships (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - */ - public List getRelatedTo() { - return getProperties(RelatedTo.class); - } - - /** - * Adds a component that the journal entry is related to. - * @param relatedTo the relationship - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - */ - public void addRelatedTo(RelatedTo relatedTo) { - //TODO create a method that accepts a component and make the RelatedTo property invisible to the user - //@formatter:off - /* - * addRelation(RelationshipType relType, ICalComponent component) { - * RelatedTo prop = new RelatedTo(component.getUid().getValue()); - * prop.setRelationshipType(relType); - * addProperty(prop); - * } - */ - //@formatter:on - addProperty(relatedTo); - } - - /** - * Adds a component that the journal entry is related to. - * @param uid the UID of the other component - * @return the property that was created - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - */ - public RelatedTo addRelatedTo(String uid) { - RelatedTo prop = new RelatedTo(uid); - addRelatedTo(prop); - return prop; - } - - /** - * Gets the list of dates/periods that help define the recurrence rule of - * this journal entry (if one is defined). - * @return the recurrence dates (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - */ - public List getRecurrenceDates() { - return getProperties(RecurrenceDates.class); - } - - /** - * Adds a list of dates/periods that help define the recurrence rule of this - * journal entry (if one is defined). - * @param recurrenceDates the recurrence dates - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - */ - public void addRecurrenceDates(RecurrenceDates recurrenceDates) { - addProperty(recurrenceDates); - } - - /** - * Gets the response to a scheduling request. - * @return the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public RequestStatus getRequestStatus() { - return getProperty(RequestStatus.class); - } - - /** - * Sets the response to a scheduling request. - * @param requestStatus the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public void setRequestStatus(RequestStatus requestStatus) { - setProperty(RequestStatus.class, requestStatus); - } - - /** - *

- * Gets the exceptions for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @return the exception rules (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 2445 - * p.114-15 - */ - public List getExceptionRules() { - return getProperties(ExceptionRule.class); - } - - /** - *

- * Adds an exception for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @param recur the exception rule to add - * @return the property that was created - * @see RFC 2445 - * p.114-15 - */ - public ExceptionRule addExceptionRule(Recurrence recur) { - ExceptionRule prop = new ExceptionRule(recur); - addExceptionRule(prop); - return prop; - } - - /** - *

- * Adds an exception for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @param exceptionRule the exception rule to add - * @see RFC 2445 - * p.114-15 - */ - public void addExceptionRule(ExceptionRule exceptionRule) { - addProperty(exceptionRule); - } - - /** - * Gets the color that clients may use when displaying the journal entry - * (for example, a background color). - * @return the property or null if not set - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color getColor() { - return getProperty(Color.class); - } - - /** - * Sets the color that clients may use when displaying the journal entry - * (for example, a background color). - * @param color the property or null to remove - * @see draft-ietf-calext-extensions-01 - * p.79 - */ - public void setColor(Color color) { - setProperty(Color.class, color); - } - - /** - * Sets the color that clients may use when displaying the journal entry - * (for example, a background color). - * @param color the color name (case insensitive) or null to remove. - * Acceptable values are defined in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color setColor(String color) { - Color prop = (color == null) ? null : new Color(color); - setColor(prop); - return prop; - } - - /** - * Gets the images that are associated with the journal entry. - * @return the images (any changes made this list will affect the parent - * component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public List getImages() { - return getProperties(Image.class); - } - - /** - * Adds an image that is associated with the journal entry. - * @param image the property to add - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public void addImage(Image image) { - addProperty(image); - } - - /** - *

- * Creates an iterator that computes the dates defined by the - * {@link RecurrenceRule} and {@link RecurrenceDates} properties (if - * present), and excludes those dates which are defined by the - * {@link ExceptionRule} and {@link ExceptionDates} properties (if present). - *

- *

- * In order for {@link RecurrenceRule} and {@link ExceptionRule} properties - * to be included in this iterator, a {@link DateStart} property must be - * defined. - *

- *

- * {@link Period} values in {@link RecurrenceDates} properties are not - * supported and are ignored. - *

- * @param timezone the timezone to iterate in. This is needed in order to - * adjust for when the iterator passes over a daylight savings boundary. - * This parameter is ignored if the start date does not have a time - * component. - * @return the iterator - */ - public DateIterator getDateIterator(TimeZone timezone) { - return Google2445Utils.getDateIterator(this, timezone); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version == ICalVersion.V1_0) { - warnings.add(new ValidationWarning(48, version)); - } - - checkRequiredCardinality(warnings, Uid.class, DateTimeStamp.class); - checkOptionalCardinality(warnings, Classification.class, Created.class, DateStart.class, LastModified.class, Organizer.class, RecurrenceId.class, Sequence.class, Status.class, Summary.class, Url.class, Color.class); - checkStatus(warnings, Status.draft(), Status.final_(), Status.cancelled()); - - //DTSTART and RECURRENCE-ID must have the same data type - ICalDate recurrenceId = getValue(getRecurrenceId()); - ICalDate dateStart = getValue(getDateStart()); - if (recurrenceId != null && dateStart != null && dateStart.hasTime() != recurrenceId.hasTime()) { - warnings.add(new ValidationWarning(19)); - } - - //BYHOUR, BYMINUTE, and BYSECOND cannot be specified in RRULE if DTSTART's data type is "date" - //RFC 5545 p. 167 - Recurrence rrule = getValue(getRecurrenceRule()); - if (dateStart != null && rrule != null) { - if (!dateStart.hasTime() && (!rrule.getByHour().isEmpty() || !rrule.getByMinute().isEmpty() || !rrule.getBySecond().isEmpty())) { - warnings.add(new ValidationWarning(5)); - } - } - - //there *should* be only 1 instance of RRULE - //RFC 5545 p. 167 - if (getProperties(RecurrenceRule.class).size() > 1) { - warnings.add(new ValidationWarning(6)); - } - } - - @Override - public VJournal copy() { - return new VJournal(this); - } -} diff --git a/app/src/main/java/biweekly/component/VTimezone.java b/app/src/main/java/biweekly/component/VTimezone.java deleted file mode 100644 index 4d51c85721..0000000000 --- a/app/src/main/java/biweekly/component/VTimezone.java +++ /dev/null @@ -1,282 +0,0 @@ -package biweekly.component; - -import java.util.Date; -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.property.LastModified; -import biweekly.property.TimezoneId; -import biweekly.property.TimezoneUrl; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a timezone's UTC offsets throughout the year. - *

- * - *

- * Examples: - *

- * - *
- * VTimezone timezone = new VTimezone("Eastern Standard Time");
- * 
- * StandardTime standard = new StandardTime();
- * DateTimeComponents componentsStandard = new DateTimeComponents(1998, 10, 25, 2, 0, 0, false);
- * standard.setDateStart(componentsStandard);
- * standard.setTimezoneOffsetFrom(-4, 0);
- * standard.setTimezoneOffsetTo(-5, 0);
- * timezone.addStandardTime(standard);
- * 
- * DaylightSavingsTime daylight = new DaylightSavingsTime();
- * DateTimeComponents componentsDaylight = new DateTimeComponents(1999, 4, 4, 2, 0, 0, false);
- * daylight.setDateStart(componentsDaylight);
- * daylight.setTimezoneOffsetFrom(-5, 0);
- * daylight.setTimezoneOffsetTo(-4, 0);
- * timezone.addDaylightSavingsTime(daylight);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 p.60-7 - */ -/* - * Note: References to the vCal 1.0 spec are omitted from the property - * getter/setter method Javadocs because vCal does not use the VTIMEZONE - * component. - */ -public class VTimezone extends ICalComponent { - /** - * Creates a new timezone component. - * @param identifier a unique identifier for this timezone (allows it to be - * referenced by date-time properties that support timezones). - */ - public VTimezone(String identifier) { - setTimezoneId(identifier); - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public VTimezone(VTimezone original) { - super(original); - } - - /** - * Gets the ID for this timezone. This is a required property. - * @return the timezone ID or null if not set - * @see RFC 5545 - * p.102-3 - * @see RFC 2445 - * p.97-8 - */ - public TimezoneId getTimezoneId() { - return getProperty(TimezoneId.class); - } - - /** - * Sets an ID for this timezone. This is a required property. - * @param timezoneId the timezone ID or null to remove - * @see RFC 5545 - * p.102-3 - * @see RFC 2445 - * p.97-8 - */ - public void setTimezoneId(TimezoneId timezoneId) { - setProperty(TimezoneId.class, timezoneId); - } - - /** - * Sets an ID for this timezone. This is a required property. - * @param timezoneId the timezone ID or null to remove - * @return the property that was created - * @see RFC 5545 - * p.102-3 - * @see RFC 2445 - * p.97-8 - */ - public TimezoneId setTimezoneId(String timezoneId) { - TimezoneId prop = (timezoneId == null) ? null : new TimezoneId(timezoneId); - setTimezoneId(prop); - return prop; - } - - /** - * Gets the date-time that the timezone data was last changed. - * @return the last modified date or null if not set - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - */ - public LastModified getLastModified() { - return getProperty(LastModified.class); - } - - /** - * Sets the date-time that the timezone data was last changed. - * @param lastModified the last modified date or null to remove - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - */ - public void setLastModified(LastModified lastModified) { - setProperty(LastModified.class, lastModified); - } - - /** - * Sets the date-time that the timezone data was last changed. - * @param lastModified the last modified date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - */ - public LastModified setLastModified(Date lastModified) { - LastModified prop = (lastModified == null) ? null : new LastModified(lastModified); - setLastModified(prop); - return prop; - } - - /** - * Gets the timezone URL, which points to an iCalendar object that contains - * further information on the timezone. - * @return the URL or null if not set - * @see RFC 5545 - * p.106 - * @see RFC 2445 - * p.101 - */ - public TimezoneUrl getTimezoneUrl() { - return getProperty(TimezoneUrl.class); - } - - /** - * Sets the timezone URL, which points to an iCalendar object that contains - * further information on the timezone. - * @param url the URL or null to remove - * @see RFC 5545 - * p.106 - * @see RFC 2445 - * p.101 - */ - public void setTimezoneUrl(TimezoneUrl url) { - setProperty(TimezoneUrl.class, url); - } - - /** - * Sets the timezone URL, which points to an iCalendar object that contains - * further information on the timezone. - * @param url the timezone URL (e.g. - * "http://example.com/America-New_York.ics") or null to remove - * @return the property that was created - * @see RFC 5545 - * p.106 - * @see RFC 2445 - * p.101 - */ - public TimezoneUrl setTimezoneUrl(String url) { - TimezoneUrl prop = (url == null) ? null : new TimezoneUrl(url); - setTimezoneUrl(prop); - return prop; - } - - /** - * Gets the timezone's "standard" observance time ranges. - * @return the "standard" observance time ranges (any changes made this list - * will affect the parent component object and vice versa) - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 - * p.60-7 - */ - public List getStandardTimes() { - return getComponents(StandardTime.class); - } - - /** - * Adds a "standard" observance time range. - * @param standardTime the "standard" observance time - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 - * p.60-7 - */ - public void addStandardTime(StandardTime standardTime) { - addComponent(standardTime); - } - - /** - * Gets the timezone's "daylight savings" observance time ranges. - * @return the "daylight savings" observance time ranges (any changes made - * this list will affect the parent component object and vice versa) - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 - * p.60-7 - */ - public List getDaylightSavingsTime() { - return getComponents(DaylightSavingsTime.class); - } - - /** - * Adds a "daylight savings" observance time range. - * @param daylightSavingsTime the "daylight savings" observance time - * @see RFC 5545 - * p.62-71 - * @see RFC 2445 - * p.60-7 - */ - public void addDaylightSavingsTime(DaylightSavingsTime daylightSavingsTime) { - addComponent(daylightSavingsTime); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version == ICalVersion.V1_0) { - warnings.add(new ValidationWarning(48, version)); - } - - checkRequiredCardinality(warnings, TimezoneId.class); - checkOptionalCardinality(warnings, LastModified.class, TimezoneUrl.class); - - //STANDARD or DAYLIGHT must be defined - if (getStandardTimes().isEmpty() && getDaylightSavingsTime().isEmpty()) { - warnings.add(new ValidationWarning(21)); - } - } - - @Override - public VTimezone copy() { - return new VTimezone(this); - } -} diff --git a/app/src/main/java/biweekly/component/VTodo.java b/app/src/main/java/biweekly/component/VTodo.java deleted file mode 100644 index 87ee266259..0000000000 --- a/app/src/main/java/biweekly/component/VTodo.java +++ /dev/null @@ -1,1754 +0,0 @@ -package biweekly.component; - -import static biweekly.property.ValuedProperty.getValue; - -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.property.Attachment; -import biweekly.property.Attendee; -import biweekly.property.Categories; -import biweekly.property.Classification; -import biweekly.property.Color; -import biweekly.property.Comment; -import biweekly.property.Completed; -import biweekly.property.Conference; -import biweekly.property.Contact; -import biweekly.property.Created; -import biweekly.property.DateDue; -import biweekly.property.DateStart; -import biweekly.property.DateTimeStamp; -import biweekly.property.Description; -import biweekly.property.DurationProperty; -import biweekly.property.ExceptionDates; -import biweekly.property.ExceptionRule; -import biweekly.property.Geo; -import biweekly.property.Image; -import biweekly.property.LastModified; -import biweekly.property.Location; -import biweekly.property.Method; -import biweekly.property.Organizer; -import biweekly.property.PercentComplete; -import biweekly.property.Priority; -import biweekly.property.RecurrenceDates; -import biweekly.property.RecurrenceId; -import biweekly.property.RecurrenceRule; -import biweekly.property.RelatedTo; -import biweekly.property.RequestStatus; -import biweekly.property.Resources; -import biweekly.property.Sequence; -import biweekly.property.Status; -import biweekly.property.Summary; -import biweekly.property.Uid; -import biweekly.property.Url; -import biweekly.util.Duration; -import biweekly.util.Google2445Utils; -import biweekly.util.ICalDate; -import biweekly.util.Period; -import biweekly.util.Recurrence; -import biweekly.util.com.google.ical.compat.javautil.DateIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a task or assignment that needs to be completed at some point in the - * future. - *

- *

- * Examples: - *

- * - *
- * VTodo todo = new VTodo();
- * todo.setSummary("Complete report");
- * Date due = ...
- * todo.setDateDue(due);
- * todo.setStatus(Status.confirmed());
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.55-7 - * @see RFC 2445 p.55-6 - * @see vCal 1.0 p.14 - */ -public class VTodo extends ICalComponent { - /** - *

- * Creates a new to-do task. - *

- *

- * The following properties are added to the component when it is created: - *

- *
    - *
  • {@link Uid}: Set to a UUID.
  • - *
  • {@link DateTimeStamp}: Set to the current time.
  • - *
- */ - public VTodo() { - setUid(Uid.random()); - setDateTimeStamp(new Date()); - } - - /** - * Copy constructor. - * @param original the component to make a copy of - */ - public VTodo(VTodo original) { - super(original); - } - - /** - * Gets the unique identifier for this to-do task. This component object - * comes populated with a UID on creation. This is a required - * property. - * @return the UID or null if not set - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - */ - public Uid getUid() { - return getProperty(Uid.class); - } - - /** - * Sets the unique identifier for this to-do task. This component object - * comes populated with a UID on creation. This is a required - * property. - * @param uid the UID or null to remove - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - */ - public void setUid(Uid uid) { - setProperty(Uid.class, uid); - } - - /** - * Sets the unique identifier for this to-do task. This component object - * comes populated with a UID on creation. This is a required - * property. - * @param uid the UID or null to remove - * @return the property that was created - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - */ - public Uid setUid(String uid) { - Uid prop = (uid == null) ? null : new Uid(uid); - setUid(prop); - return prop; - } - - /** - * Gets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the to-do task - * was last modified (the {@link LastModified} property also holds this - * information). This to-do object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @return the date time stamp or null if not set - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp getDateTimeStamp() { - return getProperty(DateTimeStamp.class); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the to-do task - * was last modified (the {@link LastModified} property also holds this - * information). This to-do object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public void setDateTimeStamp(DateTimeStamp dateTimeStamp) { - setProperty(DateTimeStamp.class, dateTimeStamp); - } - - /** - * Sets either (a) the creation date of the iCalendar object (if the - * {@link Method} property is defined) or (b) the date that the to-do task - * was last modified (the {@link LastModified} property also holds this - * information). This to-do object comes populated with a - * {@link DateTimeStamp} property that is set to the current time. This is a - * required property. - * @param dateTimeStamp the date time stamp or null to remove - * @return the property that was created - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ - public DateTimeStamp setDateTimeStamp(Date dateTimeStamp) { - DateTimeStamp prop = (dateTimeStamp == null) ? null : new DateTimeStamp(dateTimeStamp); - setDateTimeStamp(prop); - return prop; - } - - /** - * Gets the level of sensitivity of the to-do data. If not specified, the - * data within the to-do task should be considered "public". - * @return the classification level or null if not set - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ - public Classification getClassification() { - return getProperty(Classification.class); - } - - /** - * Sets the level of sensitivity of the to-do data. If not specified, the - * data within the to-do task should be considered "public". - * @param classification the classification level or null to remove - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ - public void setClassification(Classification classification) { - setProperty(Classification.class, classification); - } - - /** - * Sets the level of sensitivity of the to-do data. If not specified, the - * data within the to-do task should be considered "public". - * @param classification the classification level (e.g. "CONFIDENTIAL") or - * null to remove - * @return the property that was created - * @see RFC 5545 - * p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ - public Classification setClassification(String classification) { - Classification prop = (classification == null) ? null : new Classification(classification); - setClassification(prop); - return prop; - } - - /** - * Gets the date and time that the to-do task was completed. - * @return the completion date or null if not set - * @see RFC 5545 - * p.94-5 - * @see RFC 2445 - * p.90-1 - * @see vCal 1.0 p.29 - */ - public Completed getCompleted() { - return getProperty(Completed.class); - } - - /** - * Sets the date and time that the to-do task was completed. - * @param completed the completion date or null to remove - * @see RFC 5545 - * p.94-5 - * @see RFC 2445 - * p.90-1 - * @see vCal 1.0 p.29 - */ - public void setCompleted(Completed completed) { - setProperty(Completed.class, completed); - } - - /** - * Sets the date and time that the to-do task was completed. - * @param completed the completion date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.94-5 - * @see RFC 2445 - * p.90-1 - * @see vCal 1.0 p.29 - */ - public Completed setCompleted(Date completed) { - Completed prop = (completed == null) ? null : new Completed(completed); - setCompleted(prop); - return prop; - } - - /** - * Gets the date-time that the to-do task was initially created. - * @return the creation date-time or null if not set - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ - public Created getCreated() { - return getProperty(Created.class); - } - - /** - * Sets the date-time that the to-do task was initially created. - * @param created the creation date-time or null to remove - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ - public void setCreated(Created created) { - setProperty(Created.class, created); - } - - /** - * Sets the date-time that the to-do task was initially created. - * @param created the creation date-time or null to remove - * @return the property that was created - * @see RFC 5545 - * p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ - public Created setCreated(Date created) { - Created prop = (created == null) ? null : new Created(created); - setCreated(prop); - return prop; - } - - /** - * Gets a detailed description of the to-do task. The description should be - * more detailed than the one provided by the {@link Summary} property. - * @return the description or null if not set - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - * @see vCal 1.0 p.30 - */ - public Description getDescription() { - return getProperty(Description.class); - } - - /** - * Sets a detailed description of the to-do task. The description should be - * more detailed than the one provided by the {@link Summary} property. - * @param description the description or null to remove - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - * @see vCal 1.0 p.30 - */ - public void setDescription(Description description) { - setProperty(Description.class, description); - } - - /** - * Sets a detailed description of the to-do task. The description should be - * more detailed than the one provided by the {@link Summary} property. - * @param description the description or null to remove - * @return the property that was created - * @see RFC 5545 - * p.84-5 - * @see RFC 2445 - * p.81-2 - * @see vCal 1.0 p.30 - */ - public Description setDescription(String description) { - Description prop = (description == null) ? null : new Description(description); - setDescription(prop); - return prop; - } - - /** - * Gets the date that the to-do task starts. - * @return the start date or null if not set - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public DateStart getDateStart() { - return getProperty(DateStart.class); - } - - /** - * Sets the date that the to-do task starts. - * @param dateStart the start date or null to remove - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public void setDateStart(DateStart dateStart) { - setProperty(DateStart.class, dateStart); - } - - /** - * Sets the date that the to-do task starts. - * @param dateStart the start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public DateStart setDateStart(Date dateStart) { - return setDateStart(dateStart, true); - } - - /** - * Sets the date that the to-do task starts. - * @param dateStart the start date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.97-8 - * @see RFC 2445 - * p.93-4 - * @see vCal 1.0 p.35 - */ - public DateStart setDateStart(Date dateStart, boolean hasTime) { - DateStart prop = (dateStart == null) ? null : new DateStart(dateStart, hasTime); - setDateStart(prop); - return prop; - } - - /** - * Gets a set of geographical coordinates. - * @return the geographical coordinates or null if not set - * @see RFC 5545 - * p.85-7 - * @see RFC 2445 - * p.82-3 - */ - //Note: vCal 1.0 spec is omitted because GEO is not used in vCal 1.0 to-dos - public Geo getGeo() { - return getProperty(Geo.class); - } - - /** - * Sets a set of geographical coordinates. - * @param geo the geographical coordinates or null to remove - * @see RFC 5545 - * p.85-7 - * @see RFC 2445 - * p.82-3 - */ - //Note: vCal 1.0 spec is omitted because GEO is not used in vCal 1.0 to-dos - public void setGeo(Geo geo) { - setProperty(Geo.class, geo); - } - - /** - * Gets the date-time that the to-do task was last changed. - * @return the last modified date or null if not set - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - * @see vCal 1.0 p.31 - */ - public LastModified getLastModified() { - return getProperty(LastModified.class); - } - - /** - * Sets the date-time that the to-do task was last changed. - * @param lastModified the last modified date or null to remove - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - * @see vCal 1.0 p.31 - */ - public void setLastModified(LastModified lastModified) { - setProperty(LastModified.class, lastModified); - } - - /** - * Sets the date-time that the to-do task was last changed. - * @param lastModified the last modified date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.138 - * @see RFC 2445 - * p.131 - * @see vCal 1.0 p.31 - */ - public LastModified setLastModified(Date lastModified) { - LastModified prop = (lastModified == null) ? null : new LastModified(lastModified); - setLastModified(prop); - return prop; - } - - /** - * Gets the physical location of the to-do task. - * @return the location or null if not set - * @see RFC 5545 - * p.87-8 - * @see RFC 2445 - * p.84 - * @see vCal 1.0 p.32 - */ - public Location getLocation() { - return getProperty(Location.class); - } - - /** - * Sets the physical location of the to-do task. - * @param location the location or null to remove - * @see RFC 5545 - * p.87-8 - * @see RFC 2445 - * p.84 - * @see vCal 1.0 p.32 - */ - public void setLocation(Location location) { - setProperty(Location.class, location); - } - - /** - * Sets the physical location of the to-do task. - * @param location the location (e.g. "Room 101") or null to remove - * @return the property that was created - * @see RFC 5545 - * p.87-8 - * @see RFC 2445 - * p.84 - * @see vCal 1.0 p.32 - */ - public Location setLocation(String location) { - Location prop = (location == null) ? null : new Location(location); - setLocation(prop); - return prop; - } - - /** - * Gets the organizer of the to-do task. - * @return the organizer or null if not set - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer getOrganizer() { - return getProperty(Organizer.class); - } - - /** - * Sets the organizer of the to-do task. - * @param organizer the organizer or null to remove - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public void setOrganizer(Organizer organizer) { - setProperty(Organizer.class, organizer); - } - - /** - * Sets the organizer of the to-do task. - * @param email the organizer's email address (e.g. "johndoe@example.com") - * or null to remove - * @return the property that was created - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ - public Organizer setOrganizer(String email) { - Organizer prop = (email == null) ? null : new Organizer(null, email); - setOrganizer(prop); - return prop; - } - - /** - * Gets the amount that the to-do task has been completed. - * @return the percent complete or null if not set - * @see RFC 5545 - * p.88-9 - * @see RFC 2445 - * p.85 - */ - public PercentComplete getPercentComplete() { - return getProperty(PercentComplete.class); - } - - /** - * Sets the amount that the to-do task has been completed. - * @param percentComplete the percent complete or null to remove - * @see RFC 5545 - * p.88-9 - * @see RFC 2445 - * p.85 - */ - public void setPercentComplete(PercentComplete percentComplete) { - setProperty(PercentComplete.class, percentComplete); - } - - /** - * Sets the amount that the to-do task has been completed. - * @param percent the percent complete (e.g. "50" for 50%) or null to remove - * @return the property that was created - * @see RFC 5545 - * p.88-9 - * @see RFC 2445 - * p.85 - */ - public PercentComplete setPercentComplete(Integer percent) { - PercentComplete prop = (percent == null) ? null : new PercentComplete(percent); - setPercentComplete(prop); - return prop; - } - - /** - * Gets the priority of the to-do task. - * @return the priority or null if not set - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 - * p.85-7 - * @see vCal 1.0 p.33 - */ - public Priority getPriority() { - return getProperty(Priority.class); - } - - /** - * Sets the priority of the to-do task. - * @param priority the priority or null to remove - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 - * p.85-7 - * @see vCal 1.0 p.33 - */ - public void setPriority(Priority priority) { - setProperty(Priority.class, priority); - } - - /** - * Sets the priority of the to-do task. - * @param priority the priority ("0" is undefined, "1" is the highest, "9" - * is the lowest) or null to remove - * @return the property that was created - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 - * p.85-7 - * @see vCal 1.0 p.33 - */ - public Priority setPriority(Integer priority) { - Priority prop = (priority == null) ? null : new Priority(priority); - setPriority(prop); - return prop; - } - - /** - * Gets the original value of the {@link DateStart} property if the to-do - * task is recurring and has been modified. Used in conjunction with the - * {@link Uid} and {@link Sequence} properties to uniquely identify a - * recurrence instance. - * @return the recurrence ID or null if not set - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public RecurrenceId getRecurrenceId() { - return getProperty(RecurrenceId.class); - } - - /** - * Sets the original value of the {@link DateStart} property if the to-do - * task is recurring and has been modified. Used in conjunction with the - * {@link Uid} and {@link Sequence} properties to uniquely identify a - * recurrence instance. - * @param recurrenceId the recurrence ID or null to remove - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public void setRecurrenceId(RecurrenceId recurrenceId) { - setProperty(RecurrenceId.class, recurrenceId); - } - - /** - * Sets the original value of the {@link DateStart} property if the to-do - * task is recurring and has been modified. Used in conjunction with the - * {@link Uid} and {@link Sequence} properties to uniquely identify a - * recurrence instance. - * @param originalStartDate the original start date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ - public RecurrenceId setRecurrenceId(Date originalStartDate) { - RecurrenceId prop = (originalStartDate == null) ? null : new RecurrenceId(originalStartDate); - setRecurrenceId(prop); - return prop; - } - - /** - * Gets the revision number of the to-do task. The organizer can increment - * this number every time he or she makes a significant change. - * @return the sequence number - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public Sequence getSequence() { - return getProperty(Sequence.class); - } - - /** - * Sets the revision number of the to-do task. The organizer can increment - * this number every time he or she makes a significant change. - * @param sequence the sequence number - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public void setSequence(Sequence sequence) { - setProperty(Sequence.class, sequence); - } - - /** - * Sets the revision number of the to-do task. The organizer can increment - * this number every time he or she makes a significant change. - * @param sequence the sequence number - * @return the property that was created - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public Sequence setSequence(Integer sequence) { - Sequence prop = (sequence == null) ? null : new Sequence(sequence); - setSequence(prop); - return prop; - } - - /** - * Increments the revision number of the to-do task. The organizer can - * increment this number every time he or she makes a significant change. - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ - public void incrementSequence() { - Sequence sequence = getSequence(); - if (sequence == null) { - setSequence(1); - } else { - sequence.increment(); - } - } - - /** - * Gets the status of the to-do task. - * @return the status or null if not set - * @see RFC 5545 - * p.92-3 - * @see RFC 2445 - * p.88-9 - * @see vCal 1.0 p.35-6 - */ - public Status getStatus() { - return getProperty(Status.class); - } - - /** - *

- * Sets the status of the to-do task. - *

- *

- * Valid status codes are: - *

- *
    - *
  • NEEDS-ACTION
  • - *
  • COMPLETED
  • - *
  • IN-PROGRESS
  • - *
  • CANCELLED
  • - *
- * @param status the status or null to remove - * @see RFC 5545 - * p.92-3 - * @see RFC 2445 - * p.88-9 - * @see vCal 1.0 p.35-6 - */ - public void setStatus(Status status) { - setProperty(Status.class, status); - } - - /** - * Gets the summary of the to-do task. - * @return the summary or null if not set - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ - public Summary getSummary() { - return getProperty(Summary.class); - } - - /** - * Sets the summary of the to-do task. - * @param summary the summary or null to remove - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ - public void setSummary(Summary summary) { - setProperty(Summary.class, summary); - } - - /** - * Sets the summary of the to-do task. - * @param summary the summary or null to remove - * @return the property that was created - * @see RFC 5545 - * p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ - public Summary setSummary(String summary) { - Summary prop = (summary == null) ? null : new Summary(summary); - setSummary(prop); - return prop; - } - - /** - * Gets a URL to a resource that contains additional information about the - * to-do task. - * @return the URL or null if not set - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - */ - public Url getUrl() { - return getProperty(Url.class); - } - - /** - * Sets a URL to a resource that contains additional information about the - * to-do task. - * @param url the URL or null to remove - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - */ - public void setUrl(Url url) { - setProperty(Url.class, url); - } - - /** - * Sets a URL to a resource that contains additional information about the - * to-do task. - * @param url the URL (e.g. "http://example.com/resource.ics") or null to - * remove - * @return the property that was created - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - */ - public Url setUrl(String url) { - Url prop = (url == null) ? null : new Url(url); - setUrl(prop); - return prop; - } - - /** - * Gets how often the to-do task repeats. - * @return the recurrence rule or null if not set - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ - public RecurrenceRule getRecurrenceRule() { - return getProperty(RecurrenceRule.class); - } - - /** - * Sets how often the to-do task repeats. - * @param recur the recurrence rule or null to remove - * @return the property that was created - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ - public RecurrenceRule setRecurrenceRule(Recurrence recur) { - RecurrenceRule prop = (recur == null) ? null : new RecurrenceRule(recur); - setRecurrenceRule(prop); - return prop; - } - - /** - * Sets how often the to-do task repeats. - * @param recurrenceRule the recurrence rule or null to remove - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ - public void setRecurrenceRule(RecurrenceRule recurrenceRule) { - setProperty(RecurrenceRule.class, recurrenceRule); - } - - /** - * Gets the date that a to-do task is due by. - * @return the due date or null if not set - * @see RFC 5545 - * p.96-7 - * @see RFC 2445 - * p.92-3 - * @see vCal 1.0 p.30 - */ - public DateDue getDateDue() { - return getProperty(DateDue.class); - } - - /** - * Sets the date that a to-do task is due by. This must NOT be set if a - * {@link DurationProperty} is defined. - * @param dateDue the due date or null to remove - * @see RFC 5545 - * p.96-7 - * @see RFC 2445 - * p.92-3 - * @see vCal 1.0 p.30 - */ - public void setDateDue(DateDue dateDue) { - setProperty(DateDue.class, dateDue); - } - - /** - * Sets the date that a to-do task is due by. This must NOT be set if a - * {@link DurationProperty} is defined. - * @param dateDue the due date or null to remove - * @return the property that was created - * @see RFC 5545 - * p.96-7 - * @see RFC 2445 - * p.92-3 - * @see vCal 1.0 p.30 - */ - public DateDue setDateDue(Date dateDue) { - return setDateDue(dateDue, true); - } - - /** - * Sets the date that a to-do task is due by. This must NOT be set if a - * {@link DurationProperty} is defined. - * @param dateDue the due date or null to remove - * @param hasTime true if the date has a time component, false if it is - * strictly a date (if false, the given Date object should be created by a - * {@link java.util.Calendar Calendar} object that uses the JVM's default - * timezone) - * @return the property that was created - * @see RFC 5545 - * p.96-7 - * @see RFC 2445 - * p.92-3 - * @see vCal 1.0 p.30 - */ - public DateDue setDateDue(Date dateDue, boolean hasTime) { - DateDue prop = (dateDue == null) ? null : new DateDue(dateDue, hasTime); - setDateDue(prop); - return prop; - } - - /** - * Gets the duration of the to-do task. - * @return the duration or null if not set - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public DurationProperty getDuration() { - return getProperty(DurationProperty.class); - } - - /** - * Sets the duration of the to-do task. This must NOT be set if a - * {@link DateDue} is defined. - * @param duration the duration or null to remove - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public void setDuration(DurationProperty duration) { - setProperty(DurationProperty.class, duration); - } - - /** - * Sets the duration of the to-do task. This must NOT be set if a - * {@link DateDue} is defined. - * @param duration the duration or null to remove - * @return the property that was created - * @see RFC 5545 - * p.99 - * @see RFC 2445 - * p.94-5 - */ - public DurationProperty setDuration(Duration duration) { - DurationProperty prop = (duration == null) ? null : new DurationProperty(duration); - setDuration(prop); - return prop; - } - - /** - * Gets any attachments that are associated with the to-do task. - * @return the attachments (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - * @see vCal 1.0 p.25 - */ - public List getAttachments() { - return getProperties(Attachment.class); - } - - /** - * Adds an attachment to the to-do task. - * @param attachment the attachment to add - * @see RFC 5545 - * p.80-1 - * @see RFC 2445 - * p.77-8 - * @see vCal 1.0 p.25 - */ - public void addAttachment(Attachment attachment) { - addProperty(attachment); - } - - /** - * Gets the people who are involved in the to-do task. - * @return the attendees (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ - public List getAttendees() { - return getProperties(Attendee.class); - } - - /** - * Adds a person who is involved in the to-do task. - * @param attendee the attendee - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ - public void addAttendee(Attendee attendee) { - addProperty(attendee); - } - - /** - * Adds a person who is involved in the to-do task. - * @param email the attendee's email address - * @return the property that was created - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ - public Attendee addAttendee(String email) { - Attendee prop = new Attendee(null, email, null); - addAttendee(prop); - return prop; - } - - /** - * Gets a list of "tags" or "keywords" that describe the to-do task. - * @return the categories (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public List getCategories() { - return getProperties(Categories.class); - } - - /** - * Adds a list of "tags" or "keywords" that describe the to-do task. Note - * that a single property can hold multiple keywords. - * @param categories the categories to add - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public void addCategories(Categories categories) { - addProperty(categories); - } - - /** - * Adds a list of "tags" or "keywords" that describe the to-do task. - * @param categories the categories to add - * @return the property that was created - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public Categories addCategories(String... categories) { - Categories prop = new Categories(categories); - addCategories(prop); - return prop; - } - - /** - * Adds a list of "tags" or "keywords" that describe the to-do task. - * @param categories the categories to add - * @return the property that was created - * @see RFC 5545 - * p.81-2 - * @see RFC 2445 - * p.78-9 - * @see vCal 1.0 p.28 - */ - public Categories addCategories(List categories) { - Categories prop = new Categories(categories); - addCategories(prop); - return prop; - } - - /** - * Gets the comments attached to the to-do task. - * @return the comments (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public List getComments() { - return getProperties(Comment.class); - } - - /** - * Adds a comment to the to-do task. - * @param comment the comment to add - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public void addComment(Comment comment) { - addProperty(comment); - } - - /** - * Adds a comment to the to-do task. - * @param comment the comment to add - * @return the property that was created - * @see RFC 5545 - * p.83-4 - * @see RFC 2445 - * p.80-1 - */ - public Comment addComment(String comment) { - Comment prop = new Comment(comment); - addComment(prop); - return prop; - } - - /** - * Gets the contacts associated with the to-do task. - * @return the contacts (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public List getContacts() { - return getProperties(Contact.class); - } - - /** - * Adds a contact to the to-do task. - * @param contact the contact - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public void addContact(Contact contact) { - addProperty(contact); - } - - /** - * Adds a contact to the to-do task. - * @param contact the contact (e.g. "ACME Co - (123) 555-1234") - * @return the property that was created - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ - public Contact addContact(String contact) { - Contact prop = new Contact(contact); - addContact(prop); - return prop; - } - - /** - * Gets the list of exceptions to the recurrence rule defined in the to-do - * task (if one is defined). - * @return the list of exceptions (any changes made this list will affect - * the parent component object and vice versa) - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - * @see vCal 1.0 p.31 - */ - public List getExceptionDates() { - return getProperties(ExceptionDates.class); - } - - /** - * Adds a list of exceptions to the recurrence rule defined in the to-do - * task (if one is defined). Note that this property can contain multiple - * dates. - * @param exceptionDates the list of exceptions - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - * @see vCal 1.0 p.31 - */ - public void addExceptionDates(ExceptionDates exceptionDates) { - addProperty(exceptionDates); - } - - /** - * Gets the response to a scheduling request. - * @return the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public RequestStatus getRequestStatus() { - return getProperty(RequestStatus.class); - } - - /** - * Sets the response to a scheduling request. - * @param requestStatus the response - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ - public void setRequestStatus(RequestStatus requestStatus) { - setProperty(RequestStatus.class, requestStatus); - } - - /** - * Gets the components that the to-do task is related to. - * @return the relationships (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ - public List getRelatedTo() { - return getProperties(RelatedTo.class); - } - - /** - * Adds a component that the to-do task is related to. - * @param relatedTo the relationship - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ - public void addRelatedTo(RelatedTo relatedTo) { - //TODO create a method that accepts a component and make the RelatedTo property invisible to the user - //@formatter:off - /* - * addRelation(RelationshipType relType, ICalComponent component) { - * RelatedTo prop = new RelatedTo(component.getUid().getValue()); - * prop.setRelationshipType(relType); - * addProperty(prop); - * } - */ - //@formatter:on - addProperty(relatedTo); - } - - /** - * Adds a component that the to-do task is related to. - * @param uid the UID of the other component - * @return the property that was created - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ - public RelatedTo addRelatedTo(String uid) { - RelatedTo prop = new RelatedTo(uid); - addRelatedTo(prop); - return prop; - } - - /** - * Gets the resources that are needed for the to-do task. - * @return the resources (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public List getResources() { - return getProperties(Resources.class); - } - - /** - * Adds a list of resources that are needed for the to-do task. Note that a - * single property can hold multiple resources. - * @param resources the resources to add - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public void addResources(Resources resources) { - addProperty(resources); - } - - /** - * Adds a list of resources that are needed for the to-do task. - * @param resources the resources to add (e.g. "easel", "projector") - * @return the property that was created - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public Resources addResources(String... resources) { - Resources prop = new Resources(resources); - addResources(prop); - return prop; - } - - /** - * Adds a list of resources that are needed for the to-do task. - * @param resources the resources to add (e.g. "easel", "projector") - * @return the property that was created - * @see RFC 5545 - * p.91 - * @see RFC 2445 - * p.87-8 - * @see vCal 1.0 p.34-5 - */ - public Resources addResources(List resources) { - Resources prop = new Resources(resources); - addResources(prop); - return prop; - } - - /** - * Gets the list of dates/periods that help define the recurrence rule of - * this to-do task (if one is defined). - * @return the recurrence dates (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - * @see vCal 1.0 p.34 - */ - public List getRecurrenceDates() { - return getProperties(RecurrenceDates.class); - } - - /** - * Adds a list of dates/periods that help define the recurrence rule of this - * to-do task (if one is defined). - * @param recurrenceDates the recurrence dates - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - * @see vCal 1.0 p.34 - */ - public void addRecurrenceDates(RecurrenceDates recurrenceDates) { - addProperty(recurrenceDates); - } - - /** - * Gets the alarms that are assigned to this to-do task. - * @return the alarms (any changes made this list will affect the parent - * component object and vice versa) - * @see RFC 5545 - * p.71-6 - * @see RFC 2445 - * p.67-73 - */ - public List getAlarms() { - return getComponents(VAlarm.class); - } - - /** - * Adds an alarm to this to-do task. - * @param alarm the alarm - * @see RFC 5545 - * p.71-6 - * @see RFC 2445 - * p.67-73 - */ - public void addAlarm(VAlarm alarm) { - addComponent(alarm); - } - - /** - *

- * Gets the exceptions for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @return the exception rules (any changes made this list will affect the - * parent component object and vice versa) - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ - public List getExceptionRules() { - return getProperties(ExceptionRule.class); - } - - /** - *

- * Adds an exception for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @param recur the exception rule to add - * @return the property that was created - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ - public ExceptionRule addExceptionRule(Recurrence recur) { - ExceptionRule prop = new ExceptionRule(recur); - addExceptionRule(prop); - return prop; - } - - /** - *

- * Adds an exception for the {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the - * iCal specification. Its use should be avoided. - *

- * @param exceptionRule the exception rule to add - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ - public void addExceptionRule(ExceptionRule exceptionRule) { - addProperty(exceptionRule); - } - - /** - * Gets the color that clients may use when displaying the to-do task (for - * example, a background color). - * @return the property or null if not set - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color getColor() { - return getProperty(Color.class); - } - - /** - * Sets the color that clients may use when displaying the to-do task (for - * example, a background color). - * @param color the property or null to remove - * @see draft-ietf-calext-extensions-01 - * p.79 - */ - public void setColor(Color color) { - setProperty(Color.class, color); - } - - /** - * Sets the color that clients may use when displaying the to-do task (for - * example, a background color). - * @param color the color name (case insensitive) or null to remove. - * Acceptable values are defined in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - * @return the property object that was created - * @see draft-ietf-calext-extensions-01 - * p.9 - */ - public Color setColor(String color) { - Color prop = (color == null) ? null : new Color(color); - setColor(prop); - return prop; - } - - /** - * Gets the images that are associated with the to-do task. - * @return the images (any changes made this list will affect the parent - * component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public List getImages() { - return getProperties(Image.class); - } - - /** - * Adds an image that is associated with the to-do task. - * @param image the image - * @see draft-ietf-calext-extensions-01 - * p.10 - */ - public void addImage(Image image) { - addProperty(image); - } - - /** - * Gets information related to the to-do task's conference system. - * @return the conferences (any changes made this list will affect the - * parent component object and vice versa) - * @see draft-ietf-calext-extensions-01 - * p.11 - */ - public List getConferences() { - return getProperties(Conference.class); - } - - /** - * Adds information related to the to-do task's conference system. - * @param conference the conference - * @see draft-ietf-calext-extensions-01 - * p.11 - */ - public void addConference(Conference conference) { - addProperty(conference); - } - - /** - *

- * Creates an iterator that computes the dates defined by the - * {@link RecurrenceRule} and {@link RecurrenceDates} properties (if - * present), and excludes those dates which are defined by the - * {@link ExceptionRule} and {@link ExceptionDates} properties (if present). - *

- *

- * In order for {@link RecurrenceRule} and {@link ExceptionRule} properties - * to be included in this iterator, a {@link DateStart} property must be - * defined. - *

- *

- * {@link Period} values in {@link RecurrenceDates} properties are not - * supported and are ignored. - *

- * @param timezone the timezone to iterate in. This is needed in order to - * adjust for when the iterator passes over a daylight savings boundary. - * This parameter is ignored if the start date does not have a time - * component. - * @return the iterator - */ - public DateIterator getDateIterator(TimeZone timezone) { - return Google2445Utils.getDateIterator(this, timezone); - } - - @SuppressWarnings("unchecked") - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (version != ICalVersion.V1_0) { - checkRequiredCardinality(warnings, Uid.class, DateTimeStamp.class); - checkOptionalCardinality(warnings, Classification.class, Completed.class, Created.class, Description.class, DateStart.class, Geo.class, LastModified.class, Location.class, Organizer.class, PercentComplete.class, Priority.class, RecurrenceId.class, Sequence.class, Status.class, Summary.class, Url.class); - } - - checkOptionalCardinality(warnings, Color.class); - - Status[] validStatuses; - switch (version) { - case V1_0: - validStatuses = new Status[] { Status.needsAction(), Status.completed(), Status.accepted(), Status.declined(), Status.delegated(), Status.sent() }; - break; - default: - validStatuses = new Status[] { Status.needsAction(), Status.completed(), Status.inProgress(), Status.cancelled() }; - break; - } - checkStatus(warnings, validStatuses); - - ICalDate dateStart = getValue(getDateStart()); - ICalDate dateDue = getValue(getDateDue()); - if (dateStart != null && dateDue != null) { - //DTSTART must come before DUE - if (dateStart.compareTo(dateDue) > 0) { - warnings.add(new ValidationWarning(22)); - } - - //DTSTART and DUE must have the same data type - if (dateStart.hasTime() != dateDue.hasTime()) { - warnings.add(new ValidationWarning(23)); - } - } - - //DUE and DURATION cannot both exist - DurationProperty duration = getDuration(); - if (dateDue != null && duration != null) { - warnings.add(new ValidationWarning(24)); - } - - //DTSTART is required if DURATION exists - if (dateStart == null && duration != null) { - warnings.add(new ValidationWarning(25)); - } - - //DTSTART and RECURRENCE-ID must have the same data type - ICalDate recurrenceId = getValue(getRecurrenceId()); - if (recurrenceId != null && dateStart != null && dateStart.hasTime() != recurrenceId.hasTime()) { - warnings.add(new ValidationWarning(19)); - } - - //BYHOUR, BYMINUTE, and BYSECOND cannot be specified in RRULE if DTSTART's data type is "date" - //RFC 5545 p. 167 - Recurrence rrule = getValue(getRecurrenceRule()); - if (dateStart != null && rrule != null) { - if (!dateStart.hasTime() && (!rrule.getByHour().isEmpty() || !rrule.getByMinute().isEmpty() || !rrule.getBySecond().isEmpty())) { - warnings.add(new ValidationWarning(5)); - } - } - - //there *should* be only 1 instance of RRULE - //RFC 5545 p. 167 - if (getProperties(RecurrenceRule.class).size() > 1) { - warnings.add(new ValidationWarning(6)); - } - } - - @Override - public VTodo copy() { - return new VTodo(this); - } -} diff --git a/app/src/main/java/biweekly/component/package-info.java b/app/src/main/java/biweekly/component/package-info.java deleted file mode 100644 index c672418963..0000000000 --- a/app/src/main/java/biweekly/component/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains DTO classes for each component. - */ -package biweekly.component; \ No newline at end of file diff --git a/app/src/main/java/biweekly/google-rfc-2445.license b/app/src/main/java/biweekly/google-rfc-2445.license deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/app/src/main/java/biweekly/google-rfc-2445.license +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/app/src/main/java/biweekly/io/CannotParseException.java b/app/src/main/java/biweekly/io/CannotParseException.java deleted file mode 100644 index b3c18ca652..0000000000 --- a/app/src/main/java/biweekly/io/CannotParseException.java +++ /dev/null @@ -1,79 +0,0 @@ -package biweekly.io; - -import biweekly.Messages; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Thrown during the unmarshalling of an iCalendar property to signal that the - * property's value could not be parsed (for example, being unable to parse a - * date string). - * @author Michael Angstadt - */ -public class CannotParseException extends RuntimeException { - private static final long serialVersionUID = 8299420302297241326L; - private final Integer code; - private final Object args[]; - - /** - * Creates a new "cannot parse" exception. - * @param code the warning message code - * @param args the warning message arguments - */ - public CannotParseException(int code, Object... args) { - this.code = code; - this.args = args; - } - - /** - * Creates a new "cannot parse" exception. - * @param reason the reason why the property value cannot be parsed - */ - public CannotParseException(String reason) { - this(1, reason); - } - - /** - * Gets the warning message code. - * @return the message code - */ - public Integer getCode() { - return code; - } - - /** - * Gets the warning message arguments. - * @return the message arguments - */ - public Object[] getArgs() { - return args; - } - - @Override - public String getMessage() { - return Messages.INSTANCE.getParseMessage(code, args); - } -} diff --git a/app/src/main/java/biweekly/io/DataModelConversionException.java b/app/src/main/java/biweekly/io/DataModelConversionException.java deleted file mode 100644 index 8111fe9be2..0000000000 --- a/app/src/main/java/biweekly/io/DataModelConversionException.java +++ /dev/null @@ -1,81 +0,0 @@ -package biweekly.io; - -import java.util.ArrayList; -import java.util.List; - -import biweekly.component.ICalComponent; -import biweekly.component.VAlarm; -import biweekly.property.AudioAlarm; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Thrown when a component or property needs to be converted to a different - * component or property when being read or written. For example, converting a - * vCal {@link AudioAlarm} property to a {@link VAlarm} component when parsing a - * vCal file. - * @author Michael Angstadt - */ -public class DataModelConversionException extends RuntimeException { - private static final long serialVersionUID = -4789186852509057375L; - private final ICalProperty originalProperty; - private final List components = new ArrayList(); - private final List properties = new ArrayList(); - - /** - * Creates a conversion exception. - * @param originalProperty the original property object that was parsed or - * null if not applicable - */ - public DataModelConversionException(ICalProperty originalProperty) { - this.originalProperty = originalProperty; - } - - /** - * Gets the original property object that was parsed. - * @return the original property object or null if not applicable - */ - public ICalProperty getOriginalProperty() { - return originalProperty; - } - - /** - * Gets the components that were converted from the original property. - * @return the components - */ - public List getComponents() { - return components; - } - - /** - * Gets the properties that were converted from the original property. - * @return the properties - */ - public List getProperties() { - return properties; - } -} diff --git a/app/src/main/java/biweekly/io/DataModelConverter.java b/app/src/main/java/biweekly/io/DataModelConverter.java deleted file mode 100644 index 317d8282e5..0000000000 --- a/app/src/main/java/biweekly/io/DataModelConverter.java +++ /dev/null @@ -1,241 +0,0 @@ -package biweekly.io; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.TimeZone; - -import biweekly.component.DaylightSavingsTime; -import biweekly.component.Observance; -import biweekly.component.StandardTime; -import biweekly.component.VTimezone; -import biweekly.io.ICalTimeZone.Boundary; -import biweekly.property.Daylight; -import biweekly.property.Timezone; -import biweekly.property.UtcOffsetProperty; -import biweekly.property.ValuedProperty; -import biweekly.util.DateTimeComponents; -import biweekly.util.ICalDate; -import biweekly.util.UtcOffset; -import biweekly.util.com.google.ical.values.DateTimeValue; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Converts various properties/components into other properties/components for - * vCalendar-iCalendar compatibility. - * @author Michael Angstadt - */ -public final class DataModelConverter { - /** - * Converts vCalendar timezone information to an iCalendar {@link VTimezone} - * component. - * @param daylights the DAYLIGHT properties - * @param tz the TZ property - * @return the VTIMEZONE component - */ - public static VTimezone convert(List daylights, Timezone tz) { - UtcOffset tzOffset = ValuedProperty.getValue(tz); - if (daylights.isEmpty() && tzOffset == null) { - return null; - } - - VTimezone timezone = new VTimezone("TZ"); - if (daylights.isEmpty() && tzOffset != null) { - StandardTime st = new StandardTime(); - st.setTimezoneOffsetFrom(tzOffset); - st.setTimezoneOffsetTo(tzOffset); - timezone.addStandardTime(st); - return timezone; - } - - for (Daylight daylight : daylights) { - if (!daylight.isDaylight()) { - continue; - } - - UtcOffset daylightOffset = daylight.getOffset(); - UtcOffset standardOffset = new UtcOffset(daylightOffset.getMillis() - (1000 * 60 * 60)); - - DaylightSavingsTime dst = new DaylightSavingsTime(); - dst.setDateStart(daylight.getStart()); - dst.setTimezoneOffsetFrom(standardOffset); - dst.setTimezoneOffsetTo(daylightOffset); - dst.addTimezoneName(daylight.getDaylightName()); - timezone.addDaylightSavingsTime(dst); - - StandardTime st = new StandardTime(); - st.setDateStart(daylight.getEnd()); - st.setTimezoneOffsetFrom(daylightOffset); - st.setTimezoneOffsetTo(standardOffset); - st.addTimezoneName(daylight.getStandardName()); - timezone.addStandardTime(st); - } - - return timezone.getComponents().isEmpty() ? null : timezone; - } - - /** - * Converts an iCalendar {@link VTimezone} component into the appropriate - * vCalendar properties. - * @param timezone the TIMEZONE component - * @param dates the date values in the vCalendar object that are effected by - * the timezone. - * @return the vCalendar properties - */ - public static VCalTimezoneProperties convert(VTimezone timezone, List dates) { - List daylights = new ArrayList(); - Timezone tz = null; - if (dates.isEmpty()) { - return new VCalTimezoneProperties(daylights, tz); - } - - ICalTimeZone icalTz = new ICalTimeZone(timezone); - Collections.sort(dates); - Set daylightStartDates = new HashSet(); - boolean zeroObservanceUsed = false; - for (Date date : dates) { - Boundary boundary = icalTz.getObservanceBoundary(date); - Observance observance = boundary.getObservanceIn(); - Observance observanceAfter = boundary.getObservanceAfter(); - if (observance == null && observanceAfter == null) { - continue; - } - - if (observance == null) { - //the date comes before the earliest observance - if (observanceAfter instanceof StandardTime && !zeroObservanceUsed) { - UtcOffset offset = getOffset(observanceAfter.getTimezoneOffsetFrom()); - DateTimeValue start = null; - DateTimeValue end = boundary.getObservanceAfterStart(); - String standardName = icalTz.getDisplayName(false, TimeZone.SHORT); - String daylightName = icalTz.getDisplayName(true, TimeZone.SHORT); - - Daylight daylight = new Daylight(true, offset, convert(start), convert(end), standardName, daylightName); - daylights.add(daylight); - zeroObservanceUsed = true; - } - - if (observanceAfter instanceof DaylightSavingsTime) { - UtcOffset offset = getOffset(observanceAfter.getTimezoneOffsetFrom()); - if (offset != null) { - tz = new Timezone(offset); - } - } - - continue; - } - - if (observance instanceof StandardTime) { - UtcOffset offset = getOffset(observance.getTimezoneOffsetTo()); - if (offset != null) { - tz = new Timezone(offset); - } - continue; - } - - if (observance instanceof DaylightSavingsTime && !daylightStartDates.contains(boundary.getObservanceInStart())) { - UtcOffset offset = getOffset(observance.getTimezoneOffsetTo()); - DateTimeValue start = boundary.getObservanceInStart(); - DateTimeValue end = null; - if (observanceAfter != null) { - end = boundary.getObservanceAfterStart(); - } - - String standardName = icalTz.getDisplayName(false, TimeZone.SHORT); - String daylightName = icalTz.getDisplayName(true, TimeZone.SHORT); - - Daylight daylight = new Daylight(true, offset, convert(start), convert(end), standardName, daylightName); - daylights.add(daylight); - daylightStartDates.add(start); - continue; - } - } - - if (tz == null) { - int rawOffset = icalTz.getRawOffset(); - UtcOffset offset = new UtcOffset(rawOffset); - tz = new Timezone(offset); - } - - if (daylights.isEmpty()) { - Daylight daylight = new Daylight(); - daylight.setDaylight(false); - daylights.add(daylight); - } - - return new VCalTimezoneProperties(daylights, tz); - } - - private static UtcOffset getOffset(UtcOffsetProperty property) { - return (property == null) ? null : property.getValue(); - } - - private static ICalDate convert(DateTimeValue value) { - if (value == null) { - return null; - } - - //@formatter:off - DateTimeComponents components = new DateTimeComponents( - value.year(), - value.month(), - value.day(), - value.hour(), - value.minute(), - value.second(), - false - ); - //@formatter:on - - return new ICalDate(components, true); - } - - public static class VCalTimezoneProperties { - private final List daylights; - private final Timezone tz; - - public VCalTimezoneProperties(List daylights, Timezone tz) { - this.daylights = daylights; - this.tz = tz; - } - - public List getDaylights() { - return daylights; - } - - public Timezone getTz() { - return tz; - } - } - - private DataModelConverter() { - //hide - } -} diff --git a/app/src/main/java/biweekly/io/DefaultGlobalTimezoneIdResolver.java b/app/src/main/java/biweekly/io/DefaultGlobalTimezoneIdResolver.java deleted file mode 100644 index 9648fce9c0..0000000000 --- a/app/src/main/java/biweekly/io/DefaultGlobalTimezoneIdResolver.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.io; - -import biweekly.util.ICalDateFormat; - -import java.util.TimeZone; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Default implementation of {@link GlobalTimezoneIdResolver}. - *

- *

- * The following are examples of the kinds of TZID formats this class is able to - * handle. - *

- *
    - *
  • "TZID=/America/New_York" resolves to - * {@code TimeZone.getTimeZone("America/New_York")}
  • - *
  • "TZID=/mozilla.org/20050126_1/America/New_York" resolves to - * {@code TimeZone.getTimeZone("America/New_York")}
  • - *
- * @author Michael Angstadt - */ -public class DefaultGlobalTimezoneIdResolver implements GlobalTimezoneIdResolver { - @Override - public TimeZone resolve(String globalId) { - globalId = removeMozillaPrefixIfPresent(globalId); - return ICalDateFormat.parseTimeZoneId(globalId); - } - - /** - * Checks for, and removes, a global ID prefix that Mozilla software adds to - * its iCal files. Googling this prefix returns several search results, - * suggesting it is frequently encountered in the wild. - * @param globalId the global ID (may or may not contain the Mozilla prefix) - * @return the sanitized global ID, or the unchanged ID if it does not - * contain the prefix - */ - private String removeMozillaPrefixIfPresent(String globalId) { - String prefix = "mozilla.org/20050126_1/"; - return globalId.startsWith(prefix) ? globalId.substring(prefix.length()) : globalId; - } -} diff --git a/app/src/main/java/biweekly/io/GlobalTimezoneIdResolver.java b/app/src/main/java/biweekly/io/GlobalTimezoneIdResolver.java deleted file mode 100644 index 337112b25a..0000000000 --- a/app/src/main/java/biweekly/io/GlobalTimezoneIdResolver.java +++ /dev/null @@ -1,50 +0,0 @@ -package biweekly.io; - -import java.util.TimeZone; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Gets Java {@link TimeZone} objects that correspond with TZID parameters that - * contain global timezone IDs (as opposed to IDs that correspond with a - * VTIMEZONE component). - * @author Michael Angstadt - * @see RFC 5545 - * section 3.8.3.1 - * @see RFC 2445 - * section 4.2.19 - */ -public interface GlobalTimezoneIdResolver { - /** - * Returns an appropriate Java {@link TimeZone} object that corresponds to - * the given global ID. - * @param globalId the global ID (the value of the TZID parameter, without - * the forward slash prefix) - * @return the corresponding {@link TimeZone} object or null if the global - * ID is not recognized - */ - TimeZone resolve(String globalId); -} diff --git a/app/src/main/java/biweekly/io/ICalTimeZone.java b/app/src/main/java/biweekly/io/ICalTimeZone.java deleted file mode 100644 index 46c3046b46..0000000000 --- a/app/src/main/java/biweekly/io/ICalTimeZone.java +++ /dev/null @@ -1,720 +0,0 @@ -package biweekly.io; - -import static biweekly.property.ValuedProperty.getValue; -import static biweekly.util.Google2445Utils.convertFromRawComponents; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.TimeZone; - -import biweekly.Messages; -import biweekly.component.DaylightSavingsTime; -import biweekly.component.Observance; -import biweekly.component.StandardTime; -import biweekly.component.VTimezone; -import biweekly.property.ExceptionDates; -import biweekly.property.ExceptionRule; -import biweekly.property.RecurrenceDates; -import biweekly.property.RecurrenceRule; -import biweekly.property.TimezoneName; -import biweekly.util.ICalDate; -import biweekly.util.Recurrence; -import biweekly.util.UtcOffset; -import biweekly.util.com.google.ical.iter.RecurrenceIterator; -import biweekly.util.com.google.ical.iter.RecurrenceIteratorFactory; -import biweekly.util.com.google.ical.util.DTBuilder; -import biweekly.util.com.google.ical.values.DateTimeValue; -import biweekly.util.com.google.ical.values.DateTimeValueImpl; -import biweekly.util.com.google.ical.values.DateValue; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * A timezone that is based on an iCalendar {@link VTimezone} component. This - * class is not thread safe. - * @author Michael Angstadt - */ -@SuppressWarnings("serial") -public class ICalTimeZone extends TimeZone { - private final VTimezone component; - private final Map> observanceDateCache; - final List sortedObservances; - private final int rawOffset; - private final TimeZone utc = TimeZone.getTimeZone("UTC"); - private final Calendar utcCalendar = Calendar.getInstance(utc); - - /** - * Creates a new timezone based on an iCalendar VTIMEZONE component. - * @param component the VTIMEZONE component to wrap - */ - public ICalTimeZone(VTimezone component) { - this.component = component; - - int numObservances = component.getStandardTimes().size() + component.getDaylightSavingsTime().size(); - observanceDateCache = new IdentityHashMap>(numObservances); - - sortedObservances = calculateSortedObservances(); - - rawOffset = calculateRawOffset(); - - String id = getValue(component.getTimezoneId()); - if (id != null) { - setID(id); - } - } - - /** - * Builds a list of all the observances in the VTIMEZONE component, sorted - * by DTSTART. - * @return the sorted observances - */ - private List calculateSortedObservances() { - List daylights = component.getDaylightSavingsTime(); - List standards = component.getStandardTimes(); - - int numObservances = standards.size() + daylights.size(); - List sortedObservances = new ArrayList(numObservances); - - sortedObservances.addAll(standards); - sortedObservances.addAll(daylights); - - Collections.sort(sortedObservances, new Comparator() { - public int compare(Observance left, Observance right) { - ICalDate startLeft = getValue(left.getDateStart()); - ICalDate startRight = getValue(right.getDateStart()); - if (startLeft == null && startRight == null) { - return 0; - } - if (startLeft == null) { - return -1; - } - if (startRight == null) { - return 1; - } - - return startLeft.getRawComponents().compareTo(startRight.getRawComponents()); - } - }); - - return Collections.unmodifiableList(sortedObservances); - } - - @Override - public String getDisplayName(boolean daylight, int style, Locale locale) { - ListIterator it = sortedObservances.listIterator(sortedObservances.size()); - while (it.hasPrevious()) { - Observance observance = it.previous(); - - if (daylight && observance instanceof DaylightSavingsTime) { - List names = observance.getTimezoneNames(); - if (!names.isEmpty()) { - String name = names.get(0).getValue(); - if (name != null) { - return name; - } - } - } - - if (!daylight && observance instanceof StandardTime) { - List names = observance.getTimezoneNames(); - if (!names.isEmpty()) { - String name = names.get(0).getValue(); - if (name != null) { - return name; - } - } - } - } - - return super.getDisplayName(daylight, style, locale); - } - - @Override - public int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis) { - int hour = millis / 1000 / 60 / 60; - millis -= hour * 1000 * 60 * 60; - int minute = millis / 1000 / 60; - millis -= minute * 1000 * 60; - int second = millis / 1000; - - Observance observance = getObservance(year, month + 1, day, hour, minute, second); - if (observance == null) { - /* - * Find the first observance that has a DTSTART property and a - * TZOFFSETFROM property. - */ - for (Observance obs : sortedObservances) { - ICalDate dateStart = getValue(obs.getDateStart()); - if (dateStart == null) { - continue; - } - - UtcOffset offsetFrom = getValue(obs.getTimezoneOffsetFrom()); - if (offsetFrom == null) { - continue; - } - - return (int) offsetFrom.getMillis(); - } - return 0; - } - - UtcOffset offsetTo = getValue(observance.getTimezoneOffsetTo()); - return (offsetTo == null) ? 0 : (int) offsetTo.getMillis(); - } - - @Override - public int getRawOffset() { - return rawOffset; - } - - private int calculateRawOffset() { - Observance observance = getObservance(new Date()); - if (observance == null) { - //return the offset of the first STANDARD component - for (Observance obs : sortedObservances) { - if (!(obs instanceof StandardTime)) { - continue; - } - - UtcOffset offsetTo = getValue(obs.getTimezoneOffsetTo()); - if (offsetTo == null) { - continue; - } - - return (int) offsetTo.getMillis(); - } - return 0; - } - - UtcOffset offset = getValue((observance instanceof StandardTime) ? observance.getTimezoneOffsetTo() : observance.getTimezoneOffsetFrom()); - return (offset == null) ? 0 : (int) offset.getMillis(); - } - - @Override - public boolean inDaylightTime(Date date) { - if (!useDaylightTime()) { - return false; - } - - Observance observance = getObservance(date); - return (observance == null) ? false : (observance instanceof DaylightSavingsTime); - } - - /** - * This method is not supported by this class. - * @throws UnsupportedOperationException thrown when this method is called - */ - @Override - public void setRawOffset(int offset) { - throw new UnsupportedOperationException(Messages.INSTANCE.getExceptionMessage(12)); - } - - @Override - public boolean useDaylightTime() { - for (Observance observance : sortedObservances) { - if (observance instanceof DaylightSavingsTime) { - return true; - } - } - return false; - } - - /** - * Gets the timezone information of a date. - * @param date the date - * @return the timezone information - */ - public Boundary getObservanceBoundary(Date date) { - utcCalendar.setTime(date); - int year = utcCalendar.get(Calendar.YEAR); - int month = utcCalendar.get(Calendar.MONTH) + 1; - int day = utcCalendar.get(Calendar.DATE); - int hour = utcCalendar.get(Calendar.HOUR); - int minute = utcCalendar.get(Calendar.MINUTE); - int second = utcCalendar.get(Calendar.SECOND); - - return getObservanceBoundary(year, month, day, hour, minute, second); - } - - /** - * Gets the observance that a date is effected by. - * @param date the date - * @return the observance or null if an observance cannot be found - */ - public Observance getObservance(Date date) { - Boundary boundary = getObservanceBoundary(date); - return (boundary == null) ? null : boundary.getObservanceIn(); - } - - /** - *

- * Gets the VTIMEZONE component that is being wrapped. - *

- *

- * Note that the ICalTimeZone class makes heavy use of caching. Any - * modifications made to the VTIMEZONE component that is returned by this - * method may effect the accuracy of this ICalTimeZone instance. - *

- * @return the VTIMEZONE component - */ - public VTimezone getComponent() { - return component; - } - - /** - * Gets the observance that a date is effected by. - * @param year the year - * @param month the month (1-12) - * @param day the day of the month - * @param hour the hour - * @param minute the minute - * @param second the second - * @return the observance or null if an observance cannot be found - */ - private Observance getObservance(int year, int month, int day, int hour, int minute, int second) { - Boundary boundary = getObservanceBoundary(year, month, day, hour, minute, second); - return (boundary == null) ? null : boundary.getObservanceIn(); - } - - /** - * Gets the observance information of a date. - * @param year the year - * @param month the month (1-12) - * @param day the day of the month - * @param hour the hour - * @param minute the minute - * @param second the second - * @return the observance information or null if none was found - */ - private Boundary getObservanceBoundary(int year, int month, int day, int hour, int minute, int second) { - if (sortedObservances.isEmpty()) { - return null; - } - - DateValue givenTime = new DateTimeValueImpl(year, month, day, hour, minute, second); - int closestIndex = -1; - Observance closest = null; - DateValue closestValue = null; - for (int i = 0; i < sortedObservances.size(); i++) { - Observance observance = sortedObservances.get(i); - - //skip observances that start after the given time - ICalDate dtstart = getValue(observance.getDateStart()); - if (dtstart != null) { - DateValue dtstartValue = convertFromRawComponents(dtstart); - if (dtstartValue.compareTo(givenTime) > 0) { - continue; - } - } - - DateValue dateValue = getObservanceDateClosestToTheGivenDate(observance, givenTime, false); - if (dateValue != null && (closestValue == null || closestValue.compareTo(dateValue) < 0)) { - closestValue = dateValue; - closest = observance; - closestIndex = i; - } - } - - Observance observanceIn = closest; - DateValue observanceInStart = closestValue; - Observance observanceAfter = null; - DateValue observanceAfterStart = null; - if (closestIndex < sortedObservances.size() - 1) { - observanceAfter = sortedObservances.get(closestIndex + 1); - observanceAfterStart = getObservanceDateClosestToTheGivenDate(observanceAfter, givenTime, true); - } - - /* - * If any of the DTSTART properties are missing their time components, - * then observanceInStart/observanceAfterStart could be a DateValue - * object. If so, convert it to a DateTimeValue object (see Issue 77). - */ - if (observanceInStart != null && !(observanceInStart instanceof DateTimeValue)) { - observanceInStart = new DTBuilder(observanceInStart).toDateTime(); - } - if (observanceAfterStart != null && !(observanceAfterStart instanceof DateTimeValue)) { - observanceAfterStart = new DTBuilder(observanceAfterStart).toDateTime(); - } - - return new Boundary((DateTimeValue) observanceInStart, observanceIn, (DateTimeValue) observanceAfterStart, observanceAfter); - } - - /** - * Iterates through each of the timezone boundary dates defined by the given - * observance and finds the date that comes closest to the given date. - * @param observance the observance - * @param givenDate the given date - * @param after true to return the closest date greater than the - * given date, false to return the closest date less than or equal to - * the given date. - * @return the closest date - */ - private DateValue getObservanceDateClosestToTheGivenDate(Observance observance, DateValue givenDate, boolean after) { - List dateCache = observanceDateCache.get(observance); - if (dateCache == null) { - dateCache = new ArrayList(); - observanceDateCache.put(observance, dateCache); - } - - if (dateCache.isEmpty()) { - DateValue prev = null, cur = null; - boolean stopped = false; - RecurrenceIterator it = createIterator(observance); - while (it.hasNext()) { - cur = it.next(); - dateCache.add(cur); - - if (givenDate.compareTo(cur) < 0) { - //stop if we have passed the givenTime - stopped = true; - break; - } - - prev = cur; - } - return after ? (stopped ? cur : null) : prev; - } - - DateValue last = dateCache.get(dateCache.size() - 1); - int comparison = last.compareTo(givenDate); - if ((after && comparison <= 0) || comparison < 0) { - RecurrenceIterator it = createIterator(observance); - - /* - * Calling "it.advanceTo()" here causes problems. - * - * See: https://github.com/mangstadt/biweekly/issues/126 - */ - //it.advanceTo(last); - - DateValue prev = null, cur = null; - boolean stopped = false; - while (it.hasNext()) { - cur = it.next(); - int curCompareToLast = cur.compareTo(last); - if (curCompareToLast < 0) { - continue; - } - if (curCompareToLast > 0) { - dateCache.add(cur); - } - if (curCompareToLast == 0) { - //do nothing; don't add to dateCache - } - - if (givenDate.compareTo(cur) < 0) { - //stop if we have passed the givenTime - stopped = true; - break; - } - - prev = cur; - } - return after ? (stopped ? cur : null) : prev; - } - - /* - * The date is somewhere in the cached list, so find it. - * - * Note: Read the "binarySearch" method Javadoc carefully for an - * explanation of its return value. - */ - int index = Collections.binarySearch(dateCache, givenDate); - - if (index < 0) { - /* - * The index where the date would be if it was inside the list. - */ - index = (index * -1) - 1; - - if (after) { - /* - * This is where the date would be if it was inside the list, so - * we want to return the date value that's currently at that - * position. - */ - int afterIndex = index; - - return (afterIndex < dateCache.size()) ? dateCache.get(afterIndex) : null; - } - - int beforeIndex = index - 1; - if (beforeIndex < 0) { - return null; - } - if (beforeIndex >= dateCache.size()) { - return dateCache.get(dateCache.size() - 1); - } - return dateCache.get(beforeIndex); - } - - /* - * An exact match was found. - */ - if (after) { - int afterIndex = index + 1; //remember: the date must be > - return (afterIndex < dateCache.size()) ? dateCache.get(afterIndex) : null; - } - return dateCache.get(index); //remember: the date must be <= - } - - /** - * Creates an iterator which iterates over each of the dates in an - * observance. - * @param observance the observance - * @return the iterator - */ - RecurrenceIterator createIterator(Observance observance) { - List inclusions = new ArrayList(); - List exclusions = new ArrayList(); - - ICalDate dtstart = getValue(observance.getDateStart()); - if (dtstart != null) { - DateValue dtstartValue = convertFromRawComponents(dtstart); - - //add DTSTART property - inclusions.add(new DateValueRecurrenceIterator(Collections.singletonList(dtstartValue))); - - //add RRULE properties - for (RecurrenceRule rrule : observance.getProperties(RecurrenceRule.class)) { - Recurrence recur = rrule.getValue(); - if (recur != null) { - inclusions.add(RecurrenceIteratorFactory.createRecurrenceIterator(recur, dtstartValue, utc)); - } - } - - //add EXRULE properties - for (ExceptionRule exrule : observance.getProperties(ExceptionRule.class)) { - Recurrence recur = exrule.getValue(); - if (recur != null) { - exclusions.add(RecurrenceIteratorFactory.createRecurrenceIterator(recur, dtstartValue, utc)); - } - } - } - - //add RDATE properties - List rdates = new ArrayList(); - for (RecurrenceDates rdate : observance.getRecurrenceDates()) { - rdates.addAll(rdate.getDates()); - } - Collections.sort(rdates); - inclusions.add(new DateRecurrenceIterator(rdates)); - - //add EXDATE properties - List exdates = new ArrayList(); - for (ExceptionDates exdate : observance.getProperties(ExceptionDates.class)) { - exdates.addAll(exdate.getValues()); - } - Collections.sort(exdates); - exclusions.add(new DateRecurrenceIterator(exdates)); - - RecurrenceIterator included = join(inclusions); - if (exclusions.isEmpty()) { - return included; - } - - RecurrenceIterator excluded = join(exclusions); - return RecurrenceIteratorFactory.except(included, excluded); - } - - private static RecurrenceIterator join(List iterators) { - if (iterators.isEmpty()) { - return new EmptyRecurrenceIterator(); - } - - RecurrenceIterator first = iterators.get(0); - if (iterators.size() == 1) { - return first; - } - - List theRest = iterators.subList(1, iterators.size()); - return RecurrenceIteratorFactory.join(first, theRest.toArray(new RecurrenceIterator[0])); - } - - /** - * A recurrence iterator that doesn't have any elements. - */ - private static class EmptyRecurrenceIterator implements RecurrenceIterator { - public boolean hasNext() { - return false; - } - - public DateValue next() { - throw new NoSuchElementException(); - } - - public void advanceTo(DateValue newStartUtc) { - //empty - } - - public void remove() { - //RecurrenceIterator does not support this method - throw new UnsupportedOperationException(); - } - } - - /** - * A recurrence iterator that takes a collection of {@link DateValue} - * objects. - */ - private static class DateValueRecurrenceIterator extends IteratorWrapper { - public DateValueRecurrenceIterator(Collection dates) { - super(dates.iterator()); - } - - @Override - protected DateValue toDateValue(DateValue value) { - return value; - } - } - - /** - * A recurrence iterator that takes a collection of {@link ICalDate} - * objects. - */ - private static class DateRecurrenceIterator extends IteratorWrapper { - public DateRecurrenceIterator(Collection dates) { - super(dates.iterator()); - } - - @Override - protected DateValue toDateValue(ICalDate value) { - return convertFromRawComponents(value); - } - } - - /** - * A recurrence iterator that wraps an {@link Iterator}. - */ - private static abstract class IteratorWrapper implements RecurrenceIterator { - protected final Iterator it; - private DateValue next; - - public IteratorWrapper(Iterator it) { - this.it = it; - } - - public DateValue next() { - if (next != null) { - DateValue value = next; - next = null; - return value; - } - return toDateValue(it.next()); - } - - public boolean hasNext() { - return next != null || it.hasNext(); - } - - public void advanceTo(DateValue newStartUtc) { - if (this.next != null && this.next.compareTo(newStartUtc) >= 0) { - return; - } - - while (it.hasNext()) { - DateValue next = toDateValue(it.next()); - if (next.compareTo(newStartUtc) >= 0) { - this.next = next; - break; - } - } - } - - public void remove() { - //RecurrenceIterator does not support this method - throw new UnsupportedOperationException(); - } - - protected abstract DateValue toDateValue(T next); - } - - /** - * Holds the timezone observance information of a particular date. - */ - public static class Boundary { - private final DateTimeValue observanceInStart, observanceAfterStart; - private final Observance observanceIn, observanceAfter; - - public Boundary(DateTimeValue observanceInStart, Observance observanceIn, DateTimeValue observanceAfterStart, Observance observanceAfter) { - this.observanceInStart = observanceInStart; - this.observanceAfterStart = observanceAfterStart; - this.observanceIn = observanceIn; - this.observanceAfter = observanceAfter; - } - - /** - * Gets start time of the observance that the date resides in. - * @return the time - */ - public DateTimeValue getObservanceInStart() { - return observanceInStart; - } - - /** - * Gets the start time the observance that comes after the observance - * that the date resides in. - * @return the time - */ - public DateTimeValue getObservanceAfterStart() { - return observanceAfterStart; - } - - /** - * Gets the observance that the date resides in. - * @return the observance - */ - public Observance getObservanceIn() { - return observanceIn; - } - - /** - * Gets the observance that comes after the observance that the date - * resides in. - * @return the observance - */ - public Observance getObservanceAfter() { - return observanceAfter; - } - - @Override - public String toString() { - return "Boundary [observanceInStart=" + observanceInStart + ", observanceAfterStart=" + observanceAfterStart + ", observanceIn=" + observanceIn + ", observanceAfter=" + observanceAfter + "]"; - } - } -} diff --git a/app/src/main/java/biweekly/io/ParseContext.java b/app/src/main/java/biweekly/io/ParseContext.java deleted file mode 100644 index 8bbf578b3c..0000000000 --- a/app/src/main/java/biweekly/io/ParseContext.java +++ /dev/null @@ -1,257 +0,0 @@ -package biweekly.io; - -import java.util.ArrayList; -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.util.ICalDate; -import biweekly.util.ListMultimap; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Stores information used during the parsing of an iCalendar object. - * @author Michael Angstadt - */ -public class ParseContext { - private ICalVersion version; - private List warnings = new ArrayList(); - private ListMultimap timezonedDates = new ListMultimap(); - private List floatingDates = new ArrayList(); - private Integer lineNumber; - private String propertyName; - - /** - * Gets the version of the iCalendar object being parsed. - * @return the iCalendar version - */ - public ICalVersion getVersion() { - return version; - } - - /** - * Sets the version of the iCalendar object being parsed. - * @param version the iCalendar version - */ - public void setVersion(ICalVersion version) { - this.version = version; - } - - /** - * Gets the line number the parser is currently on. - * @return the line number or null if not applicable - */ - public Integer getLineNumber() { - return lineNumber; - } - - /** - * Sets the line number the parser is currently on. - * @param lineNumber the line number or null if not applicable - */ - public void setLineNumber(Integer lineNumber) { - this.lineNumber = lineNumber; - } - - /** - * Gets the name of the property that the parser is currently parsing. - * @return the property name (e.g. "DTSTART") or null if not applicable - */ - public String getPropertyName() { - return propertyName; - } - - /** - * Sets the name of the property that the parser is currently parsing. - * @param propertyName the property name (e.g. "DTSTART") or null if not - * applicable - */ - public void setPropertyName(String propertyName) { - this.propertyName = propertyName; - } - - /** - * Adds a parsed date to this parse context so its timezone can be applied - * to it after the iCalendar object has been parsed (if it has one). - * @param icalDate the parsed date - * @param property the property that the date value belongs to - * @param parameters the property's parameters - */ - public void addDate(ICalDate icalDate, ICalProperty property, ICalParameters parameters) { - if (!icalDate.hasTime()) { - //dates don't have timezones - return; - } - - if (icalDate.getRawComponents().isUtc()) { - //it's a UTC date, so it was already parsed under the correct timezone - return; - } - - //TODO handle UTC offsets within the date strings (not part of iCal standard) - String tzid = parameters.getTimezoneId(); - if (tzid == null) { - addFloatingDate(property, icalDate); - } else { - addTimezonedDate(tzid, property, icalDate); - } - } - - /** - * Keeps track of a date-time property value that uses a timezone so it can - * be parsed later. Timezones cannot be handled until the entire iCalendar - * object has been parsed. - * @param tzid the timezone ID (TZID parameter) - * @param property the property - * @param date the date object that was assigned to the property object - */ - public void addTimezonedDate(String tzid, ICalProperty property, ICalDate date) { - timezonedDates.put(tzid, new TimezonedDate(date, property)); - } - - /** - * Gets the list of date-time property values that use a timezone. - * @return the date-time property values that use a timezone (key = TZID; - * value = the property) - */ - public ListMultimap getTimezonedDates() { - return timezonedDates; - } - - /** - * Keeps track of a date-time property that does not have a timezone - * (floating time), so it can be added to the {@link TimezoneInfo} object - * after the iCalendar object is parsed. - * @param property the property - * @param date the property's date value - */ - public void addFloatingDate(ICalProperty property, ICalDate date) { - floatingDates.add(new TimezonedDate(date, property)); - } - - /** - * Gets the date-time properties that are in floating time (lacking a - * timezone). - * @return the floating date-time properties - */ - public List getFloatingDates() { - return floatingDates; - } - - /** - * Adds a parse warning. - * @param code the warning code - * @param args the warning message arguments - */ - public void addWarning(int code, Object... args) { - //@formatter:off - warnings.add(new ParseWarning.Builder(this) - .message(code, args) - .build()); - //@formatter:on - } - - /** - * Adds a parse warning. - * @param message the warning message - */ - public void addWarning(String message) { - //@formatter:off - warnings.add(new ParseWarning.Builder(this) - .message(message) - .build()); - //@formatter:on - } - - /** - * Gets the parse warnings. - * @return the parse warnings - */ - public List getWarnings() { - return warnings; - } - - /** - * Represents a property whose date-time value has a timezone. - * @author Michael Angstadt - */ - public static class TimezonedDate { - private final ICalDate date; - private final ICalProperty property; - - /** - * @param date the date object that was assigned to the property object - * @param property the property object - */ - public TimezonedDate(ICalDate date, ICalProperty property) { - this.date = date; - this.property = property; - } - - /** - * Gets the date object that was assigned to the property object (should - * be parsed under the JVM's default timezone) - * @return the date object - */ - public ICalDate getDate() { - return date; - } - - /** - * Gets the property object. - * @return the property - */ - public ICalProperty getProperty() { - return property; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((date == null) ? 0 : date.hashCode()); - result = prime * result + ((property == null) ? 0 : property.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - TimezonedDate other = (TimezonedDate) obj; - if (date == null) { - if (other.date != null) return false; - } else if (!date.equals(other.date)) return false; - if (property == null) { - if (other.property != null) return false; - } else if (!property.equals(other.property)) return false; - return true; - } - } -} diff --git a/app/src/main/java/biweekly/io/ParseWarning.java b/app/src/main/java/biweekly/io/ParseWarning.java deleted file mode 100644 index 9d42627180..0000000000 --- a/app/src/main/java/biweekly/io/ParseWarning.java +++ /dev/null @@ -1,186 +0,0 @@ -package biweekly.io; - -import biweekly.Messages; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a warning that occurred during the parsing of an iCalendar object. - * @author Michael Angstadt - */ -public class ParseWarning { - private final Integer code, lineNumber; - private final String propertyName, message; - - private ParseWarning(Integer lineNumber, String propertyName, Integer code, String message) { - this.lineNumber = lineNumber; - this.propertyName = propertyName; - this.code = code; - this.message = message; - } - - /** - * Gets the warning code. - * @return the warning code or null if no code was specified - */ - public Integer getCode() { - return code; - } - - /** - * Gets the line number the warning occurred on. - * @return the line number or null if not applicable - */ - public Integer getLineNumber() { - return lineNumber; - } - - /** - * Gets the warning message - * @return the warning message - */ - public String getMessage() { - return message; - } - - /** - * Gets the name of the property that the warning occurred on. - * @return the property name (e.g. "DTSTART") or null if not applicable - */ - public String getPropertyName() { - return propertyName; - } - - @Override - public String toString() { - String message = this.message; - if (code != null) { - message = "(" + code + ") " + message; - } - - if (lineNumber == null && propertyName == null) { - return message; - } - - String key = null; - if (lineNumber != null && propertyName == null) { - key = "parse.line"; - } else if (lineNumber == null && propertyName != null) { - key = "parse.prop"; - } else if (lineNumber != null && propertyName != null) { - key = "parse.lineWithProp"; - } - - return Messages.INSTANCE.getMessage(key, lineNumber, propertyName, message); - } - - /** - * Constructs instances of the {@link ParseWarning} class. - * @author Michael Angstadt - */ - public static class Builder { - private Integer lineNumber, code; - private String propertyName, message; - - /** - * Creates an empty builder. - */ - public Builder() { - //empty - } - - /** - * Initializes the builder with data from the parse context. - * @param context the parse context - */ - public Builder(ParseContext context) { - lineNumber(context.getLineNumber()); - propertyName(context.getPropertyName()); - } - - /** - * Sets the name of the property that the warning occurred on. - * @param propertyName the property name (e.g. "DTSTART") or null if not - * applicable - * @return this - */ - public Builder propertyName(String propertyName) { - this.propertyName = propertyName; - return this; - } - - /** - * Sets the line number that the warning occurred on. - * @param lineNumber the line number or null if not applicable - * @return this - */ - public Builder lineNumber(Integer lineNumber) { - this.lineNumber = lineNumber; - return this; - } - - /** - * Sets the warning message. - * @param code the message code - * @param args the message arguments - * @return this - */ - public Builder message(int code, Object... args) { - this.code = code; - message = Messages.INSTANCE.getParseMessage(code, args); - return this; - } - - /** - * Sets the warning message. - * @param message the warning message - * @return this - */ - public Builder message(String message) { - code = null; - this.message = message; - return this; - } - - /** - * Sets the warning message, based on the contents of a - * {@link CannotParseException}. - * @param exception the exception - * @return this - */ - public Builder message(CannotParseException exception) { - return message(exception.getCode(), exception.getArgs()); - } - - /** - * Builds the {@link ParseWarning} object. - * @return the {@link ParseWarning} object - */ - public ParseWarning build() { - return new ParseWarning(lineNumber, propertyName, code, message); - } - } -} diff --git a/app/src/main/java/biweekly/io/SkipMeException.java b/app/src/main/java/biweekly/io/SkipMeException.java deleted file mode 100644 index 622e9a1cec..0000000000 --- a/app/src/main/java/biweekly/io/SkipMeException.java +++ /dev/null @@ -1,56 +0,0 @@ -package biweekly.io; - -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Thrown during the reading or writing of an iCalendar property to show that - * the property should not be written to the iCalendar data stream or not be - * included in the parsed {@link ICalendar} object. - * @author Michael Angstadt - */ -public class SkipMeException extends RuntimeException { - private static final long serialVersionUID = 3384029056232963767L; - private final String reason; - - /** - * Creates a new "skip me" exception. - * @param reason the reason why the property was skipped - */ - public SkipMeException(String reason) { - super(reason); - this.reason = reason; - } - - /** - * Gets the reason why the property was skipped. - * @return the reason - */ - public String getReason() { - return reason; - } -} diff --git a/app/src/main/java/biweekly/io/StreamReader.java b/app/src/main/java/biweekly/io/StreamReader.java deleted file mode 100644 index 505b5ab6b5..0000000000 --- a/app/src/main/java/biweekly/io/StreamReader.java +++ /dev/null @@ -1,398 +0,0 @@ -package biweekly.io; - -import static biweekly.io.DataModelConverter.convert; - -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; - -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.component.VTimezone; -import biweekly.io.ParseContext.TimezonedDate; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.Daylight; -import biweekly.property.ICalProperty; -import biweekly.property.Timezone; -import biweekly.property.ValuedProperty; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Parses iCalendar objects from a data stream. - * @author Michael Angstadt - */ -public abstract class StreamReader implements Closeable { - protected final List warnings = new ArrayList(); - protected ScribeIndex index = new ScribeIndex(); - protected ParseContext context; - private TimeZone defaultTimezone = TimeZone.getDefault(); - private GlobalTimezoneIdResolver globalTimezoneIdResolver = new DefaultGlobalTimezoneIdResolver(); - - /** - *

- * Registers an experimental property scribe. Can also be used to override - * the scribe of a standard property (such as DTSTART). Calling this method - * is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)}. - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalPropertyScribe scribe) { - index.register(scribe); - } - - /** - *

- * Registers an experimental component scribe. Can also be used to override - * the scribe of a standard component (such as VEVENT). Calling this method - * is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)}. - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalComponentScribe scribe) { - index.register(scribe); - } - - /** - * Gets the object that manages the component/property scribes. - * @return the scribe index - */ - public ScribeIndex getScribeIndex() { - return index; - } - - /** - * Sets the object that manages the component/property scribes. - * @param index the scribe index - */ - public void setScribeIndex(ScribeIndex index) { - this.index = index; - } - - /** - * Gets the warnings from the last iCalendar object that was read. - * @return the warnings or empty list if there were no warnings - */ - public List getWarnings() { - return new ArrayList(warnings); - } - - /** - * Gets the timezone that will be used for parsing date property values that - * are floating or that have invalid timezone definitions assigned to them. - * Defaults to {@link TimeZone#getDefault}. - * @return the default timezone - */ - public TimeZone getDefaultTimezone() { - return defaultTimezone; - } - - /** - * Sets the timezone that will be used for parsing date property values that - * are floating or that have invalid timezone definitions assigned to them. - * Defaults to {@link TimeZone#getDefault}. - * @param defaultTimezone the default timezone - */ - public void setDefaultTimezone(TimeZone defaultTimezone) { - this.defaultTimezone = defaultTimezone; - } - - /** - * Gets the resolver that maps global timezone IDs to Java {@link TimeZone} - * objects. Defaults to {@link DefaultGlobalTimezoneIdResolver}. - * @return the resolver - */ - public GlobalTimezoneIdResolver getGlobalTimezoneIdResolver() { - return globalTimezoneIdResolver; - } - - /** - * Sets the resolver that maps global timezone IDs to Java {@link TimeZone} - * objects. Defaults to {@link DefaultGlobalTimezoneIdResolver}. - * @param globalTimezoneIdResolver the resolver - */ - public void setGlobalTimezoneIdResolver(GlobalTimezoneIdResolver globalTimezoneIdResolver) { - this.globalTimezoneIdResolver = globalTimezoneIdResolver; - } - - /** - * Reads all iCalendar objects from the data stream. - * @return the iCalendar objects - * @throws IOException if there's a problem reading from the stream - */ - public List readAll() throws IOException { - List icals = new ArrayList(); - ICalendar ical; - while ((ical = readNext()) != null) { - icals.add(ical); - } - return icals; - } - - /** - * Reads the next iCalendar object from the data stream. - * @return the next iCalendar object or null if there are no more - * @throws IOException if there's a problem reading from the stream - */ - public ICalendar readNext() throws IOException { - warnings.clear(); - context = new ParseContext(); - ICalendar ical = _readNext(); - if (ical == null) { - return null; - } - - ical.setVersion(context.getVersion()); - handleTimezones(ical); - return ical; - } - - /** - * Reads the next iCalendar object from the data stream. - * @return the next iCalendar object or null if there are no more - * @throws IOException if there's a problem reading from the stream - */ - protected abstract ICalendar _readNext() throws IOException; - - private void handleTimezones(ICalendar ical) { - TimezoneInfo tzinfo = ical.getTimezoneInfo(); - - //convert vCalendar DAYLIGHT and TZ properties to a VTIMEZONE component - TimezoneAssignment vcalTimezone = extractVCalTimezone(ical); - - //assign a TimeZone object to each VTIMEZONE component. - Iterator it = ical.getComponents(VTimezone.class).iterator(); - while (it.hasNext()) { - VTimezone component = it.next(); - - //make sure the component has an ID - String id = ValuedProperty.getValue(component.getTimezoneId()); - if (id == null || id.trim().isEmpty()) { - //note: do not remove invalid VTIMEZONE components from the ICalendar object - warnings.add(new ParseWarning.Builder().message(39).build()); - continue; - } - - TimeZone timezone = new ICalTimeZone(component); - tzinfo.getTimezones().add(new TimezoneAssignment(timezone, component)); - - //remove the component from the ICalendar object - it.remove(); - } - - boolean userChangedTheDefaultTimezone = !defaultTimezone.equals(TimeZone.getDefault()); - - if (vcalTimezone != null) { - //vCal: parse floating dates according to the DAYLIGHT and TZ properties (which were converted to a VTIMEZONE component) - Calendar cal = Calendar.getInstance(vcalTimezone.getTimeZone()); - for (TimezonedDate timezonedDate : context.getFloatingDates()) { - reparseDateUnderDifferentTimezone(timezonedDate, cal); - } - } else { - //iCal: treat floating dates as floating dates - for (TimezonedDate timezonedDate : context.getFloatingDates()) { - tzinfo.setFloating(timezonedDate.getProperty(), true); - } - - //convert all floating dates to the default timezone - if (userChangedTheDefaultTimezone) { - Calendar cal = Calendar.getInstance(defaultTimezone); - for (TimezonedDate timezonedDate : context.getFloatingDates()) { - reparseDateUnderDifferentTimezone(timezonedDate, cal); - } - } - } - - //convert all date values to their appropriate timezone - for (Map.Entry> entry : context.getTimezonedDates()) { - String tzid = entry.getKey(); - - //determine which timezone is associated with the given TZID - TimezoneAssignment assignment = determineTimezoneAssignment(tzid, tzinfo); - - /* - * If a timezone assignment could not be found for the given TZID - * and the user did not change the default timezone, then there is - * no need to further process the properties that are assigned to - * this TZID--the date value should remain unchanged (parsed under - * the local machine's default timezone), and its TZID parameter - * should also remain. - */ - if (assignment == null && !userChangedTheDefaultTimezone) { - continue; - } - - //convert each property to the timezone - TimeZone tz = (assignment == null) ? defaultTimezone : assignment.getTimeZone(); - Calendar cal = Calendar.getInstance(tz); - for (TimezonedDate timezonedDate : entry.getValue()) { - ICalProperty property = timezonedDate.getProperty(); - - if (assignment != null) { - tzinfo.setTimezone(property, assignment); - - /* - * Only remove the TZID parameter if the TZID is *valid*. - * Invalid TZID parameters should remain so that user can - * inspect the invalid information. - */ - property.getParameters().setTimezoneId(null); - } - - reparseDateUnderDifferentTimezone(timezonedDate, cal); - } - } - } - - private void reparseDateUnderDifferentTimezone(TimezonedDate timezonedDate, Calendar cal) { - ICalDate date = timezonedDate.getDate(); - - //parse its raw date components under its real timezone - Date realDate = date.getRawComponents().toDate(cal); - - //update the Date object with the new timestamp - date.setTime(realDate.getTime()); - } - - /** - * Determines the timezone definition that is associated with the given ID. - * @param tzid the timezone ID - * @param tzinfo the timezone settings of the iCalendar object - * @return the timezone definition or null to use the default timezone - */ - private TimezoneAssignment determineTimezoneAssignment(String tzid, TimezoneInfo tzinfo) { - boolean isOlsenId = tzid.startsWith("/"); - - //HANDLE OLSEN IDS====================================================== - - if (isOlsenId) { - String globalId = tzid.substring(1); - TimeZone timezone = globalTimezoneIdResolver.resolve(globalId); - if (timezone != null) { - /* - * Olsen ID is valid. Everything is Ok. - */ - TimezoneAssignment assignment = new TimezoneAssignment(timezone, globalId); - tzinfo.getTimezones().add(assignment); - return assignment; - } - - /* - * Even though the TZID is marked as an Olsen ID, and the timezone - * isn't recognized by Java, try looking for a VTIMEZONE component - * that matches it. - * - * This is done as a courtesy and is not required by the specs. - */ - TimezoneAssignment assignment = tzinfo.getTimezoneById(tzid); - int warning; - if (assignment == null) { - /* - * TZID does not match any VTIMEZONE components, use the default - * timezone. - */ - warning = 38; - } else { - warning = 43; - } - - warnings.add(new ParseWarning.Builder().message(warning, tzid).build()); - return assignment; - } - - //HANDLE VTIMEZONE COMPONENT IDS======================================== - - TimezoneAssignment assignment = tzinfo.getTimezoneById(tzid); - if (assignment != null) { - /* - * VTIMEZONE component with the given TZID was found. - * Everything is Ok. - */ - return assignment; - } - - /* - * Try treating the TZID as an Olsen timezone ID, even though it does - * not start with a forward slash. - * - * This is done as a courtesy for users who do not know they must prefix - * Olsen IDs with a forward slash. It is not required by the specs. - */ - String globalId = tzid; - TimeZone timezone = globalTimezoneIdResolver.resolve(globalId); - int warning; - if (timezone == null) { - /* - * TZID is not a valid Olsen ID, use the default timezone. - */ - warning = 38; - assignment = null; - } else { - /* - * TZID was successfully parsed as an Olsen ID. - */ - warning = 37; - assignment = new TimezoneAssignment(timezone, globalId); - tzinfo.getTimezones().add(assignment); - } - - warnings.add(new ParseWarning.Builder().message(warning, globalId).build()); - return assignment; - } - - private TimezoneAssignment extractVCalTimezone(ICalendar ical) { - List daylights = ical.removeProperties(Daylight.class); - List timezones = ical.removeProperties(Timezone.class); - - Timezone timezone = timezones.isEmpty() ? null : timezones.get(0); - VTimezone vcalComponent = convert(daylights, timezone); - if (vcalComponent == null) { - return null; - } - - TimeZone icalTimezone = new ICalTimeZone(vcalComponent); - TimezoneInfo tzinfo = ical.getTimezoneInfo(); - TimezoneAssignment assignment = new TimezoneAssignment(icalTimezone, vcalComponent); - tzinfo.setDefaultTimezone(assignment); - - return assignment; - } -} diff --git a/app/src/main/java/biweekly/io/StreamWriter.java b/app/src/main/java/biweekly/io/StreamWriter.java deleted file mode 100644 index b8c394f009..0000000000 --- a/app/src/main/java/biweekly/io/StreamWriter.java +++ /dev/null @@ -1,216 +0,0 @@ -package biweekly.io; - -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.Messages; -import biweekly.component.ICalComponent; -import biweekly.component.RawComponent; -import biweekly.component.VTimezone; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; -import biweekly.property.RawProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Writes iCalendar objects to a data stream. - * @author Michael Angstadt - */ -public abstract class StreamWriter implements Closeable { - protected ScribeIndex index = new ScribeIndex(); - protected WriteContext context; - protected TimezoneAssignment globalTimezone; - private TimezoneInfo tzinfo; - - /** - * Writes an iCalendar object to the data stream. - * @param ical the iCalendar object to write - * @throws IllegalArgumentException if the scribe class for a component or - * property object cannot be found (only happens when an experimental - * property/component scribe is not registered with the - * {@code registerScribe} method.) - * @throws IOException if there's a problem writing to the data stream - */ - public void write(ICalendar ical) throws IOException { - Collection> unregistered = findScribeless(ical); - if (!unregistered.isEmpty()) { - List classNames = new ArrayList(unregistered.size()); - for (Class clazz : unregistered) { - classNames.add(clazz.getName()); - } - throw Messages.INSTANCE.getIllegalArgumentException(13, classNames); - } - - tzinfo = ical.getTimezoneInfo(); - context = new WriteContext(getTargetVersion(), tzinfo, globalTimezone); - _write(ical); - } - - /** - * Gets the {@link VTimezone} components that need to be written to the - * output stream. - * @return the components - */ - protected Collection getTimezoneComponents() { - if (globalTimezone != null) { - VTimezone component = globalTimezone.getComponent(); - return (component == null) ? Collections. emptyList() : Collections.singletonList(component); - } - - return tzinfo.getComponents(); - } - - /** - * Gets the version that the next iCalendar object will be written as. - * @return the version - */ - protected abstract ICalVersion getTargetVersion(); - - /** - * Writes an iCalendar object to the data stream. - * @param ical the iCalendar object to write - * @throws IOException if there's a problem writing to the data stream - */ - protected abstract void _write(ICalendar ical) throws IOException; - - /** - * Gets the timezone that all date/time property values will be formatted - * in. If set, this setting will override the timezone information - * associated with each {@link ICalendar} object. - * @return the global timezone or null if not set (defaults to null) - */ - public TimezoneAssignment getGlobalTimezone() { - return globalTimezone; - } - - /** - * Sets the timezone that all date/time property values will be formatted - * in. This is a convenience method that overrides the timezone information - * associated with each {@link ICalendar} object that is passed into this - * writer. - * @param globalTimezone the global timezone or null not to set a global - * timezone (defaults to null) - */ - public void setGlobalTimezone(TimezoneAssignment globalTimezone) { - this.globalTimezone = globalTimezone; - } - - /** - *

- * Registers an experimental property scribe. Can also be used to override - * the scribe of a standard property (such as DTSTART). Calling this method - * is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)}. - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalPropertyScribe scribe) { - index.register(scribe); - } - - /** - *

- * Registers an experimental component scribe. Can also be used to override - * the scribe of a standard component (such as VEVENT). Calling this method - * is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)}. - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalComponentScribe scribe) { - index.register(scribe); - } - - /** - * Gets the object that manages the component/property scribes. - * @return the scribe index - */ - public ScribeIndex getScribeIndex() { - return index; - } - - /** - * Sets the object that manages the component/property scribes. - * @param scribe the scribe index - */ - public void setScribeIndex(ScribeIndex scribe) { - this.index = scribe; - } - - /** - * Gets the component/property classes that don't have scribes associated - * with them. - * @param ical the iCalendar object - * @return the component/property classes - */ - private Collection> findScribeless(ICalendar ical) { - Set> unregistered = new HashSet>(); - LinkedList components = new LinkedList(); - components.add(ical); - - while (!components.isEmpty()) { - ICalComponent component = components.removeLast(); - - Class componentClass = component.getClass(); - if (componentClass != RawComponent.class && index.getComponentScribe(componentClass) == null) { - unregistered.add(componentClass); - } - - for (Map.Entry, List> entry : component.getProperties()) { - List properties = entry.getValue(); - if (properties.isEmpty()) { - continue; - } - - Class clazz = entry.getKey(); - if (clazz != RawProperty.class && index.getPropertyScribe(clazz) == null) { - unregistered.add(clazz); - } - } - - components.addAll(component.getComponents().values()); - } - - return unregistered; - } -} diff --git a/app/src/main/java/biweekly/io/TimezoneAssignment.java b/app/src/main/java/biweekly/io/TimezoneAssignment.java deleted file mode 100644 index f5335bc6e3..0000000000 --- a/app/src/main/java/biweekly/io/TimezoneAssignment.java +++ /dev/null @@ -1,127 +0,0 @@ -package biweekly.io; - -import java.util.TimeZone; - -import biweekly.Messages; -import biweekly.component.VTimezone; -import biweekly.property.TimezoneId; -import biweekly.property.ValuedProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a timezone definition that is used within an iCalendar object. - * @author Michael Angstadt - */ -public class TimezoneAssignment { - private final TimeZone timezone; - private final VTimezone component; - private final String globalId; - - /** - * Creates a timezone that will be inserted into the iCalendar object as a - * VTIMEZONE component. This what most iCalendar files use. - * @param timezone the Java timezone object - * @param component the iCalendar component - * @throws IllegalArgumentException if the given {@link VTimezone} component - * doesn't have a {@link TimezoneId} property - */ - public TimezoneAssignment(TimeZone timezone, VTimezone component) { - String id = ValuedProperty.getValue(component.getTimezoneId()); - if (id == null || id.trim().isEmpty()) { - throw Messages.INSTANCE.getIllegalArgumentException(14); - } - - this.timezone = timezone; - this.component = component; - this.globalId = null; - } - - /** - *

- * Creates a timezone that will be inserted into the iCalendar object as a - * "global ID". This means that a {@link VTimezone} component containing the - * timezone definition will NOT be inserted into the iCalendar object. - *

- *

- * Because the timezone definition is not included inside of the iCalendar - * object, the client consuming the iCalendar object must know how to - * interpret such an ID. The iCalendar specification does not specify a list - * of such IDs, but suggests using the naming convention of an existing - * timezone specification, such as the - * public-domain TZ - * database. - *

- * @param timezone the Java timezone object - * @param globalId the global ID (e.g. "America/New_York") - */ - public TimezoneAssignment(TimeZone timezone, String globalId) { - this.timezone = timezone; - this.component = null; - this.globalId = globalId; - } - - /** - * Creates a timezone whose VTIMEZONE component is downloaded from - * tzurl.org. - * @param timezone the Java timezone object - * @param outlookCompatible true to download a {@link VTimezone} component - * that is tailored for Microsoft Outlook email clients, false to download a - * standards-based one. - * @return the timezone assignment - * @throws IllegalArgumentException if an appropriate VTIMEZONE component - * cannot be found on the website - */ - public static TimezoneAssignment download(TimeZone timezone, boolean outlookCompatible) { - TzUrlDotOrgGenerator generator = new TzUrlDotOrgGenerator(outlookCompatible); - VTimezone component = generator.generate(timezone); - return new TimezoneAssignment(timezone, component); - } - - /** - * Gets the Java object associated with the timezone. - * @return the Java object - */ - public TimeZone getTimeZone() { - return timezone; - } - - /** - * Gets the iCalendar component associated with the timezone. - * @return the component or null if the timezone uses a global ID - */ - public VTimezone getComponent() { - return component; - } - - /** - * Gets the global ID associated with the timezone. - * @return the global ID or null if the timezone uses an iCalendar component - */ - public String getGlobalId() { - return globalId; - } -} diff --git a/app/src/main/java/biweekly/io/TimezoneInfo.java b/app/src/main/java/biweekly/io/TimezoneInfo.java deleted file mode 100644 index 4ae152648d..0000000000 --- a/app/src/main/java/biweekly/io/TimezoneInfo.java +++ /dev/null @@ -1,305 +0,0 @@ -package biweekly.io; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import biweekly.component.VTimezone; -import biweekly.property.ICalProperty; -import biweekly.property.TimezoneId; -import biweekly.property.ValuedProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Holds the timezone-related settings of an iCalendar object. - * @author Michael Angstadt - */ -public class TimezoneInfo { - @SuppressWarnings("serial") - private final Collection assignments = new HashSet() { - @Override - public boolean remove(Object assignment) { - //remove all property assignments - Collection values = propertyTimezones.values(); - while (values.remove(assignment)) { - //empty - } - - return super.remove(assignment); - } - }; - private final Map propertyTimezones = new IdentityHashMap(); - private final List floatingProperties = new ArrayList(); - - private TimezoneAssignment defaultTimezone; - private boolean globalFloatingTime = false; - - /** - * Gets all the timezones assigned to this object. - * @return the timezones (collection is mutable) - */ - public Collection getTimezones() { - return assignments; - } - - /** - *

- * Gets the timezone to format all date/time values in (by default, all - * dates are formatted in UTC). - *

- *

- * The default timezone is not used for properties that are configured to - * use their own timezone (see {@link #setTimezone}). - *

- * @return the timezone or null if using UTC - */ - public TimezoneAssignment getDefaultTimezone() { - return defaultTimezone; - } - - /** - *

- * Sets the timezone to format all date/time values in (by default, all - * dates are formatted in UTC). - *

- *

- * The default timezone is not used for properties that are configured to - * use their own timezone (see {@link #setTimezone}). - *

- * @param timezone the timezone or null to use UTC - */ - public void setDefaultTimezone(TimezoneAssignment timezone) { - if (timezone == null) { - if (defaultTimezone != null && !propertyTimezones.containsValue(defaultTimezone)) { - assignments.remove(defaultTimezone); - } - } else { - assignments.add(timezone); - } - - defaultTimezone = timezone; - } - - /** - * Assigns a timezone to a specific property. - * @param property the property - * @param timezone the timezone or null to format the property according to - * the default timezone (see {@link #setDefaultTimezone}). - */ - public void setTimezone(ICalProperty property, TimezoneAssignment timezone) { - if (timezone == null) { - TimezoneAssignment existing = propertyTimezones.remove(property); - if (existing != null && existing != defaultTimezone && !propertyTimezones.containsValue(existing)) { - assignments.remove(existing); - } - return; - } - - assignments.add(timezone); - propertyTimezones.put(property, timezone); - } - - /** - * Gets the timezone that is assigned to a property. - * @param property the property - * @return the timezone or null if no timezone is assigned to the property - */ - public TimezoneAssignment getTimezone(ICalProperty property) { - return propertyTimezones.get(property); - } - - /** - *

- * Determines the timezone that a particular property should be formatted in - * when written to an output stream. - *

- *

- * Note: You should call {@link #isFloating} first, to determine if the - * property's value is floating (without a timezone). - *

- * @param property the property - * @return the timezone or null for UTC - */ - public TimezoneAssignment getTimezoneToWriteIn(ICalProperty property) { - TimezoneAssignment assignment = getTimezone(property); - return (assignment == null) ? defaultTimezone : assignment; - } - - /** - * Gets the timezone whose {@link VTimezone} component contains a - * {@link TimezoneId} property with the given value. - * @param tzid the value of the {@link TimezoneId} property - * @return the timezone or null if not found - */ - public TimezoneAssignment getTimezoneById(String tzid) { - for (TimezoneAssignment assignment : assignments) { - VTimezone component = assignment.getComponent(); - if (component == null) { - continue; - } - - String componentId = ValuedProperty.getValue(component.getTimezoneId()); - if (tzid.equals(componentId)) { - return assignment; - } - } - return null; - } - - /** - *

- * Gets whether to format all date/time values as floating times (defaults - * to false). - *

- *

- * This setting does not apply to properties whose floating time settings - * are configured individually (see: {@link #setFloating}) or that are - * configured to use their own timezone (see {@link #setTimezone}). - *

- *

- * A floating time value does not have a timezone associated with it, and is - * to be interpreted as being in the local timezone of the computer that is - * consuming the iCalendar object. - *

- * @return true if enabled, false if disabled - */ - public boolean isGlobalFloatingTime() { - return globalFloatingTime; - } - - /** - *

- * Sets whether to format all date/time values as floating times (defaults - * to false). - *

- *

- * This setting does not apply to properties whose floating time settings - * are configured individually (see: {@link #setFloating}) or that are - * configured to use their own timezone (see {@link #setTimezone}). - *

- *

- * A floating time value does not have a timezone associated with it, and is - * to be interpreted as being in the local timezone of the computer that is - * consuming the iCalendar object. - *

- * @param enable true to enable, false to disable - */ - public void setGlobalFloatingTime(boolean enable) { - globalFloatingTime = enable; - } - - /** - * Determines if a property value should be formatted in floating time when - * written to an output stream. - * @param property the property - * @return true to format in floating time, false not to - */ - public boolean isFloating(ICalProperty property) { - if (containsIdentity(floatingProperties, property)) { - return true; - } - - if (propertyTimezones.containsKey(property)) { - return false; - } - - return globalFloatingTime; - } - - /** - *

- * Sets whether a property value should be formatted in floating time when - * written to an output stream (by default, floating time is disabled for - * all properties). - *

- *

- * A floating time value does not have a timezone associated with it, and is - * to be interpreted as being in the local timezone of the computer that is - * consuming the iCalendar object. - *

- * @param property the property - * @param enable true to enable floating time for this property, false to - * disable - */ - public void setFloating(ICalProperty property, boolean enable) { - if (enable) { - floatingProperties.add(property); - } else { - removeIdentity(floatingProperties, property); - } - } - - /** - * Gets all of the iCalendar {@link VTimezone} components that have been - * registered with this object. - * @return the components (this collection is immutable) - */ - public Collection getComponents() { - List components = new ArrayList(assignments.size()); - for (TimezoneAssignment assignment : assignments) { - VTimezone component = assignment.getComponent(); - if (component != null) { - components.add(component); - } - } - return Collections.unmodifiableList(components); - } - - /** - * Removes an object from a list using reference equality. - * @param list the list - * @param object the object to remove - */ - private static void removeIdentity(List list, T object) { - Iterator it = list.iterator(); - while (it.hasNext()) { - if (object == it.next()) { - it.remove(); - } - } - } - - /** - * Searches for an item in a list using reference equality. - * @param list the list - * @param object the object to search for - * @return true if the object was found, false if not - */ - private static boolean containsIdentity(List list, T object) { - for (T item : list) { - if (item == object) { - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/TzUrlDotOrgGenerator.java b/app/src/main/java/biweekly/io/TzUrlDotOrgGenerator.java deleted file mode 100644 index ab56667ecd..0000000000 --- a/app/src/main/java/biweekly/io/TzUrlDotOrgGenerator.java +++ /dev/null @@ -1,158 +0,0 @@ -package biweekly.io; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.TimeZone; - -import biweekly.ICalendar; -import biweekly.component.VTimezone; -import biweekly.io.text.ICalReader; -import biweekly.property.TimezoneId; -import biweekly.property.ValuedProperty; -import biweekly.util.IOUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Downloads {@link VTimezone} components from tzurl.org. This class is thread-safe. - * @author Michael Angstadt - */ -public class TzUrlDotOrgGenerator { - private static final Map cache = Collections.synchronizedMap(new HashMap()); - private final String baseUrl; - - /** - * Creates a new tzurl.org generator. - * @param outlookCompatible true to download {@link VTimezone} components - * that are tailored for Microsoft Outlook email clients, false to download - * standards-based ones - */ - public TzUrlDotOrgGenerator(boolean outlookCompatible) { - baseUrl = "http://www.tzurl.org/zoneinfo" + (outlookCompatible ? "-outlook" : "") + "/"; - } - - /** - * Generates an iCalendar {@link VTimezone} components from a Java - * {@link TimeZone} object. - * @param timezone the timezone object - * @return the timezone component - * @throws IllegalArgumentException if a timezone definition cannot be found - */ - public VTimezone generate(TimeZone timezone) throws IllegalArgumentException { - URI uri; - try { - uri = new URI(buildUrl(timezone)); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - - VTimezone component = cache.get(uri); - if (component != null) { - return component.copy(); - } - - ICalendar ical; - ICalReader reader = null; - try { - reader = new ICalReader(getInputStream(uri)); - ical = reader.readNext(); - } catch (FileNotFoundException e) { - throw notFound(e); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - IOUtils.closeQuietly(reader); - } - - /* - * There should always be exactly one iCalendar object in the file, but - * check to be sure. - */ - if (ical == null) { - throw notFound(null); - } - - /* - * There should always be exactly one VTIMEZONE component, but check to - * be sure. - */ - TimezoneInfo tzinfo = ical.getTimezoneInfo(); - Collection components = tzinfo.getComponents(); - if (components.isEmpty()) { - components = ical.getComponents(VTimezone.class); //VTIMEZONE components without TZID properties are treated as ordinary components - if (components.isEmpty()) { - throw notFound(null); - } - } - - component = components.iterator().next(); - - /* - * There should always be a TZID property, but just in case there there - * isn't one, create one. - */ - TimezoneId id = component.getTimezoneId(); - if (id == null) { - component.setTimezoneId(timezone.getID()); - } else { - String value = ValuedProperty.getValue(id); - if (value == null || value.trim().isEmpty()) { - id.setValue(timezone.getID()); - } - } - - cache.put(uri, component); - return component.copy(); - } - - private String buildUrl(TimeZone timezone) { - return baseUrl + timezone.getID(); - } - - //for unit testing - InputStream getInputStream(URI uri) throws IOException { - return uri.toURL().openStream(); - } - - /** - * Clears the internal cache of downloaded timezone definitions. - */ - public static void clearCache() { - cache.clear(); - } - - private static IllegalArgumentException notFound(Exception e) { - return new IllegalArgumentException("Timezone ID not recognized.", e); - } -} diff --git a/app/src/main/java/biweekly/io/WriteContext.java b/app/src/main/java/biweekly/io/WriteContext.java deleted file mode 100644 index a0e9f2bfed..0000000000 --- a/app/src/main/java/biweekly/io/WriteContext.java +++ /dev/null @@ -1,117 +0,0 @@ -package biweekly.io; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Stores information used to write the properties in an iCalendar object. - * @author Michael Angstadt - */ -public class WriteContext { - private final ICalVersion version; - private final TimezoneInfo timezoneOptions; - private final TimezoneAssignment globalTimezone; - private final List dates = new ArrayList(); - private ICalComponent parent; - - public WriteContext(ICalVersion version, TimezoneInfo timezoneOptions, TimezoneAssignment globalTimezone) { - this.version = version; - this.timezoneOptions = timezoneOptions; - this.globalTimezone = globalTimezone; - } - - /** - * Gets the version of the iCalendar object that is being written. - * @return the iCalendar version - */ - public ICalVersion getVersion() { - return version; - } - - /** - * Gets the timezone options for this iCalendar object. - * @return the timezone options - */ - public TimezoneInfo getTimezoneInfo() { - return timezoneOptions; - } - - /** - * Gets the global timezone to format all date/time values in, regardless of - * each individual {@link ICalendar}'s timezone settings. - * @return the global timezone or null if not set - */ - public TimezoneAssignment getGlobalTimezone() { - return globalTimezone; - } - - /** - * Gets the parent component of the property that is being written. - * @return the parent component - */ - public ICalComponent getParent() { - return parent; - } - - /** - * Sets the parent component of the property that is being written. - * @param parent the parent component - */ - public void setParent(ICalComponent parent) { - this.parent = parent; - } - - /** - * Gets the timezoned date-time property values that are in the iCalendar - * object. - * @return the timezoned date-time property values - */ - public List getDates() { - return dates; - } - - /** - * Records the timezoned date-time values that are being written. This is - * used to generate a DAYLIGHT property for vCalendar objects. - * @param floating true if the date is floating, false if not - * @param tz the timezone to format the date in or null for UTC - * @param date the date value - */ - public void addDate(ICalDate date, boolean floating, TimeZone tz) { - if (date != null && date.hasTime() && !floating && tz != null) { - dates.add(date); - } - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingJsonParser.java b/app/src/main/java/biweekly/io/chain/ChainingJsonParser.java deleted file mode 100644 index 8f6ca53648..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingJsonParser.java +++ /dev/null @@ -1,74 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -import biweekly.Biweekly; -import biweekly.io.StreamReader; -import biweekly.io.json.JCalReader; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for parsing jCals (JSON-encoded iCalendar objects). - * @see Biweekly#parseJson(InputStream) - * @see Biweekly#parseJson(File) - * @see Biweekly#parseJson(Reader) - * @author Michael Angstadt - */ -public class ChainingJsonParser> extends ChainingParser { - public ChainingJsonParser(String string) { - super(string); - } - - public ChainingJsonParser(InputStream in) { - super(in); - } - - public ChainingJsonParser(Reader reader) { - super(reader); - } - - public ChainingJsonParser(File file) { - super(file); - } - - @Override - StreamReader constructReader() throws IOException { - if (string != null) { - return new JCalReader(string); - } - if (in != null) { - return new JCalReader(in); - } - if (reader != null) { - return new JCalReader(reader); - } - return new JCalReader(file); - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingJsonStringParser.java b/app/src/main/java/biweekly/io/chain/ChainingJsonStringParser.java deleted file mode 100644 index 2354d19f22..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingJsonStringParser.java +++ /dev/null @@ -1,64 +0,0 @@ -package biweekly.io.chain; - -import java.io.IOException; -import java.util.List; - -import biweekly.Biweekly; -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for parsing jCals (JSON-encoded iCalendar objects) from - * strings. - * @see Biweekly#parseJson(String) - * @author Michael Angstadt - */ -public class ChainingJsonStringParser extends ChainingJsonParser { - public ChainingJsonStringParser(String json) { - super(json); - } - - @Override - public ICalendar first() { - try { - return super.first(); - } catch (IOException e) { - //should never be thrown because we're reading from a string - throw new RuntimeException(e); - } - } - - @Override - public List all() { - try { - return super.all(); - } catch (IOException e) { - //should never be thrown because we're reading from a string - throw new RuntimeException(e); - } - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingJsonWriter.java b/app/src/main/java/biweekly/io/chain/ChainingJsonWriter.java deleted file mode 100644 index 8c4a173f17..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingJsonWriter.java +++ /dev/null @@ -1,154 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Collection; -import java.util.TimeZone; - -import biweekly.Biweekly; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.json.JCalWriter; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for writing jCals (JSON-encoded iCalendar objects). - * @see Biweekly#writeJson(Collection) - * @see Biweekly#writeJson(ICalendar...) - * @author Michael Angstadt - */ -public class ChainingJsonWriter extends ChainingWriter { - private boolean prettyPrint = false; - - /** - * @param icals the iCalendar objects to write - */ - public ChainingJsonWriter(Collection icals) { - super(icals); - } - - /** - * Sets whether or not to pretty-print the JSON. - * @param prettyPrint true to pretty-print it, false not to (defaults to - * false) - * @return this - */ - public ChainingJsonWriter prettyPrint(boolean prettyPrint) { - this.prettyPrint = prettyPrint; - return this; - } - - @Override - public ChainingJsonWriter tz(TimeZone defaultTimeZone, boolean outlookCompatible) { - return super.tz(defaultTimeZone, outlookCompatible); - } - - @Override - public ChainingJsonWriter register(ICalPropertyScribe scribe) { - return super.register(scribe); - } - - @Override - public ChainingJsonWriter register(ICalComponentScribe scribe) { - return super.register(scribe); - } - - /** - * Writes the iCalendar objects to a string. - * @return the JSON string - */ - public String go() { - StringWriter sw = new StringWriter(); - try { - go(sw); - } catch (IOException e) { - //should never be thrown because we're writing to a string - throw new RuntimeException(e); - } - return sw.toString(); - } - - /** - * Writes the iCalendar objects to an output stream. - * @param out the output stream to write to - * @throws IOException if there's a problem writing to the output stream - */ - public void go(OutputStream out) throws IOException { - go(new JCalWriter(out, wrapInArray())); - } - - /** - * Writes the iCalendar objects to a file. - * @param file the file to write to - * @throws IOException if there's a problem writing to the file - */ - public void go(File file) throws IOException { - JCalWriter writer = new JCalWriter(file, wrapInArray()); - try { - go(writer); - } finally { - writer.close(); - } - } - - /** - * Writes the iCalendar objects to a writer. - * @param writer the writer to write to - * @throws IOException if there's a problem writing to the writer - */ - public void go(Writer writer) throws IOException { - go(new JCalWriter(writer, wrapInArray())); - } - - private void go(JCalWriter writer) throws IOException { - if (defaultTimeZone != null) { - writer.setGlobalTimezone(defaultTimeZone); - } - writer.setPrettyPrint(prettyPrint); - if (index != null) { - writer.setScribeIndex(index); - } - try { - for (ICalendar ical : icals) { - writer.write(ical); - writer.flush(); - } - } finally { - writer.closeJsonStream(); - } - } - - private boolean wrapInArray() { - return icals.size() > 1; - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingParser.java b/app/src/main/java/biweekly/io/chain/ChainingParser.java deleted file mode 100644 index 8ba17653ce..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingParser.java +++ /dev/null @@ -1,206 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.util.ArrayList; -import java.util.List; -import java.util.TimeZone; - -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.ParseWarning; -import biweekly.io.StreamReader; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Parent class for all chaining parsers. This class is package-private in order - * to hide it from the generated Javadocs. - * @author Michael Angstadt - * @param the object instance's type (for method chaining) - */ -abstract class ChainingParser> { - final String string; - final InputStream in; - final Reader reader; - final File file; - - ScribeIndex index; - List> warnings; - TimeZone defaultTimezone; - - @SuppressWarnings("unchecked") - final T this_ = (T) this; - - ChainingParser(String string) { - this(string, null, null, null); - } - - ChainingParser(InputStream in) { - this(null, in, null, null); - } - - ChainingParser(Reader reader) { - this(null, null, reader, null); - } - - ChainingParser(File file) { - this(null, null, null, file); - } - - ChainingParser() { - this(null, null, null, null); - } - - private ChainingParser(String string, InputStream in, Reader reader, File file) { - this.string = string; - this.in = in; - this.reader = reader; - this.file = file; - } - - /** - * Registers a property scribe. - * @param scribe the scribe - * @return this - */ - public T register(ICalPropertyScribe scribe) { - if (index == null) { - index = new ScribeIndex(); - } - index.register(scribe); - return this_; - } - - /** - * Registers a component scribe. - * @param scribe the scribe - * @return this - */ - public T register(ICalComponentScribe scribe) { - if (index == null) { - index = new ScribeIndex(); - } - index.register(scribe); - return this_; - } - - /** - * Provides a list object that any parser warnings will be put into. - * @param warnings the list object that will be populated with the warnings - * of each parsed iCalendar object. Each element in the list is a list of - * warnings for one parsed object. Therefore, the size of this list will be - * equal to the number of parsed iCalendar objects. If an iCalendar object - * does not have any warnings, then its warning list will be empty. - * @return this - */ - public T warnings(List> warnings) { - this.warnings = warnings; - return this_; - } - - /** - * Sets the timezone that will be used for parsing date property values that - * are floating or that have invalid timezone definitions assigned to them. - * Defaults to {@link TimeZone#getDefault}. - * @param defaultTimezone the default timezone - * @return this - */ - public T defaultTimezone(TimeZone defaultTimezone) { - this.defaultTimezone = defaultTimezone; - return this_; - } - - /** - * Reads the first iCalendar object from the stream. - * @return the iCalendar object or null if there are none - * @throws IOException if there's an I/O problem - */ - public ICalendar first() throws IOException { - StreamReader reader = constructReader(); - if (index != null) { - reader.setScribeIndex(index); - } - if (defaultTimezone != null) { - reader.setDefaultTimezone(defaultTimezone); - } - - try { - ICalendar ical = reader.readNext(); - if (warnings != null) { - warnings.add(reader.getWarnings()); - } - return ical; - } finally { - if (closeWhenDone()) { - reader.close(); - } - } - } - - /** - * Reads all iCalendar objects from the stream. - * @return the parsed iCalendar objects - * @throws IOException if there's an I/O problem - */ - public List all() throws IOException { - StreamReader reader = constructReader(); - if (index != null) { - reader.setScribeIndex(index); - } - if (defaultTimezone != null) { - reader.setDefaultTimezone(defaultTimezone); - } - - try { - List icals = new ArrayList(); - ICalendar ical; - while ((ical = reader.readNext()) != null) { - if (warnings != null) { - warnings.add(reader.getWarnings()); - } - icals.add(ical); - } - return icals; - } finally { - if (closeWhenDone()) { - reader.close(); - } - } - } - - abstract StreamReader constructReader() throws IOException; - - private boolean closeWhenDone() { - return in == null && reader == null; - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingTextParser.java b/app/src/main/java/biweekly/io/chain/ChainingTextParser.java deleted file mode 100644 index d0745f5d6e..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingTextParser.java +++ /dev/null @@ -1,97 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -import biweekly.Biweekly; -import biweekly.io.StreamReader; -import biweekly.io.text.ICalReader; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for parsing traditional, plain-text iCalendar objects. - * @see Biweekly#parse(InputStream) - * @see Biweekly#parse(File) - * @see Biweekly#parse(Reader) - * @author Michael Angstadt - */ -public class ChainingTextParser> extends ChainingParser { - private boolean caretDecoding = true; - - public ChainingTextParser(String string) { - super(string); - } - - public ChainingTextParser(InputStream in) { - super(in); - } - - public ChainingTextParser(Reader reader) { - super(reader); - } - - public ChainingTextParser(File file) { - super(file); - } - - /** - * Sets whether the reader will decode characters in parameter values that - * use circumflex accent encoding (enabled by default). This only applies to - * version 2.0 iCalendar objects. - * - * @param enable true to use circumflex accent decoding, false not to - * @return this - * @see ICalReader#setCaretDecodingEnabled(boolean) - * @see RFC 6868 - */ - public T caretDecoding(boolean enable) { - caretDecoding = enable; - return this_; - } - - @Override - StreamReader constructReader() throws IOException { - ICalReader reader = newReader(); - reader.setCaretDecodingEnabled(caretDecoding); - return reader; - } - - private ICalReader newReader() throws IOException { - if (string != null) { - return new ICalReader(string); - } - if (in != null) { - return new ICalReader(in); - } - if (reader != null) { - return new ICalReader(reader); - } - return new ICalReader(file); - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingTextStringParser.java b/app/src/main/java/biweekly/io/chain/ChainingTextStringParser.java deleted file mode 100644 index da8bb368f7..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingTextStringParser.java +++ /dev/null @@ -1,64 +0,0 @@ -package biweekly.io.chain; - -import java.io.IOException; -import java.util.List; - -import biweekly.Biweekly; -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for parsing traditional, plain-text iCalendar objects from - * strings. - * @see Biweekly#parse(String) - * @author Michael Angstadt - */ -public class ChainingTextStringParser extends ChainingTextParser { - public ChainingTextStringParser(String string) { - super(string); - } - - @Override - public ICalendar first() { - try { - return super.first(); - } catch (IOException e) { - //should never be thrown because we're reading from a string - throw new RuntimeException(e); - } - } - - @Override - public List all() { - try { - return super.all(); - } catch (IOException e) { - //should never be thrown because we're reading from a string - throw new RuntimeException(e); - } - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingTextWriter.java b/app/src/main/java/biweekly/io/chain/ChainingTextWriter.java deleted file mode 100644 index a3c61ef092..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingTextWriter.java +++ /dev/null @@ -1,233 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Collection; -import java.util.TimeZone; - -import biweekly.Biweekly; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.io.text.ICalWriter; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for writing traditional, plain-text iCalendar objects. - * @see Biweekly#write(Collection) - * @see Biweekly#write(ICalendar...) - * @author Michael Angstadt - */ -public class ChainingTextWriter extends ChainingWriter { - private ICalVersion version; - private boolean caretEncoding = false; - private boolean foldLines = true; - - /** - * @param icals the iCalendar objects to write - */ - public ChainingTextWriter(Collection icals) { - super(icals); - } - - /** - *

- * Sets the version that all the iCalendar objects will be marshalled to. - * The version that is attached to each individual {@link ICalendar} object - * will be ignored. - *

- *

- * If no version is passed into this method, the writer will look at the - * version attached to each individual {@link ICalendar} object and marshal - * it to that version. And if a {@link ICalendar} object has no version - * attached to it, then it will be marshalled to version 2.0. - *

- * @param version the version to marshal the iCalendar objects to - * @return this - */ - public ChainingTextWriter version(ICalVersion version) { - this.version = version; - return this; - } - - /** - * Sets whether the writer will use circumflex accent encoding for parameter - * values (disabled by default). This only applies to version 2.0 iCalendar - * objects. - * @param enable true to use circumflex accent encoding, false not to - * @return this - * @see ICalWriter#setCaretEncodingEnabled(boolean) - * @see RFC 6868 - */ - public ChainingTextWriter caretEncoding(boolean enable) { - this.caretEncoding = enable; - return this; - } - - /** - *

- * Sets whether to fold long lines. Line folding is when long lines are - * split up into multiple lines. No data is lost or changed when a line is - * folded. - *

- *

- * Line folding is enabled by default. If the iCalendar consumer is not - * parsing your iCalendar objects properly, disabling line folding may help. - *

- * @param foldLines true to enable line folding, false to disable it - * (defaults to true) - * @return this - */ - public ChainingTextWriter foldLines(boolean foldLines) { - this.foldLines = foldLines; - return this; - } - - @Override - public ChainingTextWriter tz(TimeZone defaultTimeZone, boolean outlookCompatible) { - return super.tz(defaultTimeZone, outlookCompatible); - } - - @Override - public ChainingTextWriter register(ICalPropertyScribe scribe) { - return super.register(scribe); - } - - @Override - public ChainingTextWriter register(ICalComponentScribe scribe) { - return super.register(scribe); - } - - /** - * Writes the iCalendar objects to a string. - * @return the iCalendar string - */ - public String go() { - StringWriter sw = new StringWriter(); - try { - go(sw); - } catch (IOException e) { - //should never be thrown because we're writing to a string - throw new RuntimeException(e); - } - return sw.toString(); - } - - /** - * Writes the iCalendar objects to an output stream. - * @param out the output stream to write to - * @throws IOException if there's a problem writing to the output stream - */ - public void go(OutputStream out) throws IOException { - go(new ICalWriter(out, getICalWriterConstructorVersion())); - } - - /** - * Writes the iCalendar objects to a file. If the file exists, it will be - * overwritten. - * @param file the file to write to - * @throws IOException if there's a problem writing to the file - */ - public void go(File file) throws IOException { - go(file, false); - } - - /** - * Writes the iCalendar objects to a file. - * @param file the file to write to - * @param append true to append onto the end of the file, false to overwrite - * it - * @throws IOException if there's a problem writing to the file - */ - public void go(File file, boolean append) throws IOException { - ICalWriter writer = new ICalWriter(file, append, getICalWriterConstructorVersion()); - try { - go(writer); - } finally { - writer.close(); - } - } - - /** - * Writes the iCalendar objects to a writer. - * @param writer the writer to write to - * @throws IOException if there's a problem writing to the writer - */ - public void go(Writer writer) throws IOException { - go(new ICalWriter(writer, getICalWriterConstructorVersion())); - } - - private void go(ICalWriter writer) throws IOException { - writer.setCaretEncodingEnabled(caretEncoding); - if (!foldLines) { - writer.getVObjectWriter().getFoldedLineWriter().setLineLength(null); - } - if (defaultTimeZone != null) { - writer.setGlobalTimezone(defaultTimeZone); - } - if (index != null) { - writer.setScribeIndex(index); - } - - for (ICalendar ical : icals) { - if (version == null) { - //use the version that's assigned to each individual iCalendar object - ICalVersion icalVersion = ical.getVersion(); - if (icalVersion == null) { - icalVersion = ICalVersion.V2_0; - } - writer.setTargetVersion(icalVersion); - } - writer.write(ical); - writer.flush(); - } - } - - /** - *

- * Gets the {@link ICalVersion} object to pass into the {@link ICalWriter} - * constructor. The constructor does not allow a null version, so this - * method ensures that a non-null version is passed in. - *

- *

- * If the user hasn't chosen a version, the version that is passed into the - * constructor doesn't matter. This is because the writer's target version - * is reset every time an iCalendar object is written (see the - * {@link #go(ICalWriter)} method). - *

- * @return the version to pass into the constructor - */ - private ICalVersion getICalWriterConstructorVersion() { - return (version == null) ? ICalVersion.V2_0 : version; - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingWriter.java b/app/src/main/java/biweekly/io/chain/ChainingWriter.java deleted file mode 100644 index 2a05b5a14d..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingWriter.java +++ /dev/null @@ -1,108 +0,0 @@ -package biweekly.io.chain; - -import java.util.Collection; -import java.util.TimeZone; - -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.TimezoneAssignment; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Parent class for all chaining writers. This class is package-private in order - * to hide it from the generated Javadocs. - * @author Michael Angstadt - * @param the object instance's type (for method chaining) - */ -class ChainingWriter> { - final Collection icals; - ScribeIndex index; - // boolean prodId = true; - // boolean versionStrict = true; - TimezoneAssignment defaultTimeZone = null; - - @SuppressWarnings("unchecked") - private final T this_ = (T) this; - - /** - * @param icals the iCalendar objects to write - */ - ChainingWriter(Collection icals) { - this.icals = icals; - } - - /** - *

- * Sets the timezone to use when outputting date values (defaults to UTC). - *

- *

- * This method downloads an appropriate VTIMEZONE component from the tzurl.org website. - *

- * @param defaultTimeZone the default timezone or null for UTC - * @param outlookCompatible true to download a VTIMEZONE component that is - * tailored for Microsoft Outlook email clients, false to download a - * standards-based one - * @return this - * @throws IllegalArgumentException if an appropriate VTIMEZONE component - * cannot be found on the website - */ - T tz(TimeZone defaultTimeZone, boolean outlookCompatible) { - this.defaultTimeZone = (defaultTimeZone == null) ? null : TimezoneAssignment.download(defaultTimeZone, outlookCompatible); - return this_; - } - - /** - * Registers a property scribe. - * @param scribe the scribe to register - * @return this - */ - T register(ICalPropertyScribe scribe) { - if (index == null) { - index = new ScribeIndex(); - } - index.register(scribe); - return this_; - } - - /** - * Registers a component scribe. - * @param scribe the scribe to register - * @return this - */ - T register(ICalComponentScribe scribe) { - if (index == null) { - index = new ScribeIndex(); - } - index.register(scribe); - return this_; - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingXmlMemoryParser.java b/app/src/main/java/biweekly/io/chain/ChainingXmlMemoryParser.java deleted file mode 100644 index 3f524ab328..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingXmlMemoryParser.java +++ /dev/null @@ -1,71 +0,0 @@ -package biweekly.io.chain; - -import java.io.IOException; -import java.util.List; - -import org.w3c.dom.Document; - -import biweekly.Biweekly; -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for parsing xCals (XML-encoded iCalendar objects) from strings - * or DOMs. - * @see Biweekly#parseXml(String) - * @see Biweekly#parseXml(Document) - * @author Michael Angstadt - */ -public class ChainingXmlMemoryParser extends ChainingXmlParser { - public ChainingXmlMemoryParser(String xml) { - super(xml); - } - - public ChainingXmlMemoryParser(Document dom) { - super(dom); - } - - @Override - public ICalendar first() { - try { - return super.first(); - } catch (IOException e) { - //should never be thrown because we're reading from a string - throw new RuntimeException(e); - } - } - - @Override - public List all() { - try { - return super.all(); - } catch (IOException e) { - //should never be thrown because we're reading from a string - throw new RuntimeException(e); - } - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingXmlParser.java b/app/src/main/java/biweekly/io/chain/ChainingXmlParser.java deleted file mode 100644 index 96f8451ad5..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingXmlParser.java +++ /dev/null @@ -1,85 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -import org.w3c.dom.Document; - -import biweekly.Biweekly; -import biweekly.io.StreamReader; -import biweekly.io.xml.XCalReader; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for parsing xCals (XML-encoded iCalendar objects). - * @see Biweekly#parseXml(InputStream) - * @see Biweekly#parseXml(File) - * @see Biweekly#parseXml(Reader) - * @author Michael Angstadt - */ -public class ChainingXmlParser> extends ChainingParser { - private Document dom; - - public ChainingXmlParser(String string) { - super(string); - } - - public ChainingXmlParser(InputStream in) { - super(in); - } - - public ChainingXmlParser(File file) { - super(file); - } - - public ChainingXmlParser(Reader reader) { - super(reader); - } - - public ChainingXmlParser(Document dom) { - this.dom = dom; - } - - @Override - StreamReader constructReader() throws IOException { - if (string != null) { - return new XCalReader(string); - } - if (in != null) { - return new XCalReader(in); - } - if (reader != null) { - return new XCalReader(reader); - } - if (file != null) { - return new XCalReader(file); - } - return new XCalReader(dom); - } -} diff --git a/app/src/main/java/biweekly/io/chain/ChainingXmlWriter.java b/app/src/main/java/biweekly/io/chain/ChainingXmlWriter.java deleted file mode 100644 index ede127b9d0..0000000000 --- a/app/src/main/java/biweekly/io/chain/ChainingXmlWriter.java +++ /dev/null @@ -1,213 +0,0 @@ -package biweekly.io.chain; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.TimeZone; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; - -import org.w3c.dom.Document; - -import biweekly.Biweekly; -import biweekly.ICalDataType; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.io.xml.XCalDocument; -import biweekly.io.xml.XCalDocument.XCalDocumentStreamWriter; -import biweekly.io.xml.XCalOutputProperties; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Chainer class for writing xCal (XML-encoded iCalendar objects). - * @see Biweekly#writeXml(Collection) - * @see Biweekly#writeXml(ICalendar...) - * @author Michael Angstadt - */ -public class ChainingXmlWriter extends ChainingWriter { - private final XCalOutputProperties outputProperties = new XCalOutputProperties(); - private final Map parameterDataTypes = new HashMap(0); - - /** - * @param icals the iCValendar objects to write - */ - public ChainingXmlWriter(Collection icals) { - super(icals); - } - - /** - * Sets the number of indent spaces to use for pretty-printing. If not set, - * then the XML will not be pretty-printed. - * @param indent the number of spaces in the indent string or "null" not to - * pretty-print (disabled by default) - * @return this - */ - public ChainingXmlWriter indent(Integer indent) { - outputProperties.setIndent(indent); - return this; - } - - /** - * Sets the XML version to use. Note that many JDKs only support 1.0 - * natively. For XML 1.1 support, add a JAXP library like xalan to your project. - * @param xmlVersion the XML version (defaults to "1.0") - * @return this - */ - public ChainingXmlWriter xmlVersion(String xmlVersion) { - outputProperties.setXmlVersion(xmlVersion); - return this; - } - - /** - * Assigns an output property to the JAXP transformer (see - * {@link Transformer#setOutputProperty}). - * @param name the property name - * @param value the property value - * @return this - */ - public ChainingXmlWriter outputProperty(String name, String value) { - outputProperties.put(name, value); - return this; - } - - /** - * Assigns all of the given output properties to the JAXP transformer (see - * {@link Transformer#setOutputProperty}). - * @param outputProperties the properties - * @return this - */ - public ChainingXmlWriter outputProperties(Map outputProperties) { - this.outputProperties.putAll(outputProperties); - return this; - } - - @Override - public ChainingXmlWriter tz(TimeZone defaultTimeZone, boolean outlookCompatible) { - return super.tz(defaultTimeZone, outlookCompatible); - } - - @Override - public ChainingXmlWriter register(ICalPropertyScribe scribe) { - return super.register(scribe); - } - - @Override - public ChainingXmlWriter register(ICalComponentScribe scribe) { - return super.register(scribe); - } - - /** - * Registers the data type of a non-standard parameter. Non-standard - * parameters use the "unknown" data type by default. - * @param parameterName the parameter name (e.g. "x-foo") - * @param dataType the data type - * @return this - */ - public ChainingXmlWriter register(String parameterName, ICalDataType dataType) { - parameterDataTypes.put(parameterName, dataType); - return this; - } - - /** - * Writes the iCalendar objects to a string. - * @return the XML document - */ - public String go() { - return createXCalDocument().write(outputProperties); - } - - /** - * Writes the iCalendar objects to an output stream. - * @param out the output stream to write to - * @throws TransformerException if there's a problem writing to the output - * stream - */ - public void go(OutputStream out) throws TransformerException { - createXCalDocument().write(out, outputProperties); - } - - /** - * Writes the iCalendar objects to a file. - * @param file the file to write to - * @throws IOException if the file can't be opened - * @throws TransformerException if there's a problem writing to the file - */ - public void go(File file) throws IOException, TransformerException { - createXCalDocument().write(file, outputProperties); - } - - /** - * Writes the iCalendar objects to a writer. - * @param writer the writer to write to - * @throws TransformerException if there's a problem writing to the writer - */ - public void go(Writer writer) throws TransformerException { - createXCalDocument().write(writer, outputProperties); - } - - /** - * Generates an XML document object model (DOM) containing the iCalendar - * objects. - * @return the DOM - */ - public Document dom() { - return createXCalDocument().getDocument(); - } - - private XCalDocument createXCalDocument() { - XCalDocument document = new XCalDocument(); - - XCalDocumentStreamWriter writer = document.writer(); - if (defaultTimeZone != null) { - writer.setGlobalTimezone(defaultTimeZone); - } - for (Map.Entry entry : parameterDataTypes.entrySet()) { - String parameterName = entry.getKey(); - ICalDataType dataType = entry.getValue(); - writer.registerParameterDataType(parameterName, dataType); - } - if (index != null) { - writer.setScribeIndex(index); - } - - for (ICalendar ical : icals) { - writer.write(ical); - } - - return document; - } -} diff --git a/app/src/main/java/biweekly/io/chain/package-info.java b/app/src/main/java/biweekly/io/chain/package-info.java deleted file mode 100644 index 7e5d5b2784..0000000000 --- a/app/src/main/java/biweekly/io/chain/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Contains classes used in the chaining API. - * @see biweekly.Biweekly - */ -package biweekly.io.chain; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/json/JCalDeserializer.java b/app/src/main/java/biweekly/io/json/JCalDeserializer.java deleted file mode 100644 index 34d125577b..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalDeserializer.java +++ /dev/null @@ -1,84 +0,0 @@ -package biweekly.io.json; - -import java.io.IOException; - -import biweekly.ICalendar; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Deserializes jCals within the jackson-databind framework. - * @author Buddy Gorven - * @author Michael Angstadt - */ -public class JCalDeserializer extends JsonDeserializer { - private ScribeIndex index = new ScribeIndex(); - - @Override - public ICalendar deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { - @SuppressWarnings("resource") - JCalReader reader = new JCalReader(parser); - reader.setScribeIndex(index); - return reader.readNext(); - } - - /** - *

- * Registers a property scribe. This is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)} - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalPropertyScribe scribe) { - index.register(scribe); - } - - /** - * Gets the scribe index. - * @return the scribe index - */ - public ScribeIndex getScribeIndex() { - return index; - } - - /** - * Sets the scribe index. - * @param index the scribe index - */ - public void setScribeIndex(ScribeIndex index) { - this.index = index; - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalModule.java b/app/src/main/java/biweekly/io/json/JCalModule.java deleted file mode 100644 index 50a8409ca3..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalModule.java +++ /dev/null @@ -1,145 +0,0 @@ -package biweekly.io.json; - -import biweekly.Biweekly; -import biweekly.ICalendar; -import biweekly.io.TimezoneAssignment; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; - -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.databind.module.SimpleModule; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Module for jackson-databind that serializes and deserializes jCals. - *

- *

- * Example: - *

- * - *
- * ObjectMapper mapper = new ObjectMapper();
- * mapper.registerModule(new JCalModule());
- * ICalendar result = mapper.readValue(..., ICalendar.class);
- * 
- * @author Buddy Gorven - * @author Michael Angstadt - */ -public class JCalModule extends SimpleModule { - private static final long serialVersionUID = 8022429868572303471L; - private static final String MODULE_NAME = "biweekly-jcal"; - private static final Version MODULE_VERSION = moduleVersion(); - - private final JCalDeserializer deserializer = new JCalDeserializer(); - private final JCalSerializer serializer = new JCalSerializer(); - - private ScribeIndex index; - - /** - * Creates the module. - */ - public JCalModule() { - super(MODULE_NAME, MODULE_VERSION); - - setScribeIndex(new ScribeIndex()); - addSerializer(serializer); - addDeserializer(ICalendar.class, deserializer); - } - - private static Version moduleVersion() { - String[] split = Biweekly.VERSION.split("[.-]"); - if (split.length < 3) { - /* - * This can happen during development if the "biweekly.properties" - * file has not been filtered by Maven. - */ - return new Version(0, 0, 0, "", Biweekly.GROUP_ID, Biweekly.ARTIFACT_ID); - } - - int major = Integer.parseInt(split[0]); - int minor = Integer.parseInt(split[1]); - int patch = Integer.parseInt(split[2]); - String snapshot = (split.length > 3) ? split[3] : "RELEASE"; - - return new Version(major, minor, patch, snapshot, Biweekly.GROUP_ID, Biweekly.ARTIFACT_ID); - } - - /** - *

- * Registers a property scribe. This is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)} - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalPropertyScribe scribe) { - index.register(scribe); - } - - /** - * Gets the scribe index used by the serializer and deserializer. - * @return the scribe index - */ - public ScribeIndex getScribeIndex() { - return index; - } - - /** - * Sets the scribe index for the serializer and deserializer to use. - * @param index the scribe index - */ - public void setScribeIndex(ScribeIndex index) { - this.index = index; - serializer.setScribeIndex(index); - deserializer.setScribeIndex(index); - } - - /** - * Gets the timezone that all date/time property values will be formatted - * in. If set, this setting will override the timezone information - * associated with each {@link ICalendar} object. - * @return the global timezone or null if not set (defaults to null) - */ - public TimezoneAssignment getGlobalTimezone() { - return serializer.getGlobalTimezone(); - } - - /** - * Sets the timezone that all date/time property values will be formatted - * in. This is a convenience method that overrides the timezone information - * associated with each {@link ICalendar} object that is passed into this - * writer. - * @param globalTimezone the global timezone or null not to set a global - * timezone (defaults to null) - */ - public void setGlobalTimezone(TimezoneAssignment globalTimezone) { - serializer.setGlobalTimezone(globalTimezone); - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalParseException.java b/app/src/main/java/biweekly/io/json/JCalParseException.java deleted file mode 100644 index 4eacc58079..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalParseException.java +++ /dev/null @@ -1,80 +0,0 @@ -package biweekly.io.json; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonToken; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Thrown during the parsing of a JSON-encoded iCalendar object (jCal) when the - * jCal object is not formatted in the correct way (the JSON syntax is valid, - * but it's not in the correct jCal format). - * @author Michael Angstadt - */ -public class JCalParseException extends IOException { - private static final long serialVersionUID = -2447563507966434472L; - private final JsonToken expected, actual; - - /** - * Creates a jCal parse exception. - * @param expected the JSON token that the parser was expecting - * @param actual the actual JSON token - */ - public JCalParseException(JsonToken expected, JsonToken actual) { - super("Expected " + expected + " but was " + actual + "."); - this.expected = expected; - this.actual = actual; - } - - /** - * Creates a jCal parse exception. - * @param message the detail message - * @param expected the JSON token that the parser was expecting - * @param actual the actual JSON token - */ - public JCalParseException(String message, JsonToken expected, JsonToken actual) { - super(message); - this.expected = expected; - this.actual = actual; - } - - /** - * Gets the JSON token that the parser was expected. - * @return the expected token - */ - public JsonToken getExpectedToken() { - return expected; - } - - /** - * Gets the JSON token that was read. - * @return the actual token - */ - public JsonToken getActualToken() { - return actual; - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalPrettyPrinter.java b/app/src/main/java/biweekly/io/json/JCalPrettyPrinter.java deleted file mode 100644 index 17de29b374..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalPrettyPrinter.java +++ /dev/null @@ -1,133 +0,0 @@ -package biweekly.io.json; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonStreamContext; -import com.fasterxml.jackson.core.util.DefaultIndenter; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * A JSON pretty-printer for jCals. - * @author Buddy Gorven - * @author Michael Angstadt - */ -public class JCalPrettyPrinter extends DefaultPrettyPrinter { - private static final long serialVersionUID = 1L; - - /** - * The value that is assigned to {@link JsonGenerator#setCurrentValue} to - * let the pretty-printer know that a iCalendar property is currently being - * written. - */ - public static final Object PROPERTY_VALUE = "ical-property"; - - /** - * Alias for {@link DefaultIndenter#SYSTEM_LINEFEED_INSTANCE} - */ - private static final Indenter NEWLINE_INDENTER = DefaultIndenter.SYSTEM_LINEFEED_INSTANCE; - - /** - * Instance of {@link DefaultPrettyPrinter.FixedSpaceIndenter} - */ - private static final Indenter INLINE_INDENTER = new DefaultPrettyPrinter.FixedSpaceIndenter(); - - private Indenter propertyIndenter, arrayIndenter, objectIndenter; - - public JCalPrettyPrinter() { - propertyIndenter = INLINE_INDENTER; - indentArraysWith(NEWLINE_INDENTER); - indentObjectsWith(NEWLINE_INDENTER); - } - - public JCalPrettyPrinter(JCalPrettyPrinter base) { - super(base); - propertyIndenter = base.propertyIndenter; - indentArraysWith(base.arrayIndenter); - indentObjectsWith(base.objectIndenter); - } - - @Override - public JCalPrettyPrinter createInstance() { - return new JCalPrettyPrinter(this); - } - - @Override - public void indentArraysWith(Indenter indenter) { - arrayIndenter = indenter; - super.indentArraysWith(indenter); - } - - @Override - public void indentObjectsWith(Indenter indenter) { - objectIndenter = indenter; - super.indentObjectsWith(indenter); - } - - public void indentICalPropertiesWith(Indenter indenter) { - propertyIndenter = indenter; - } - - protected static boolean isInICalProperty(JsonStreamContext context) { - if (context == null) { - return false; - } - - Object currentValue = context.getCurrentValue(); - if (currentValue == PROPERTY_VALUE) { - return true; - } - - return isInICalProperty(context.getParent()); - } - - private void updateIndenter(JsonStreamContext context) { - boolean inICalProperty = isInICalProperty(context); - super.indentArraysWith(inICalProperty ? propertyIndenter : arrayIndenter); - super.indentObjectsWith(inICalProperty ? propertyIndenter : objectIndenter); - } - - @Override - public void writeStartArray(JsonGenerator gen) throws IOException, JsonGenerationException { - updateIndenter(gen.getOutputContext().getParent()); - super.writeStartArray(gen); - } - - @Override - public void writeEndArray(JsonGenerator gen, int numValues) throws IOException, JsonGenerationException { - updateIndenter(gen.getOutputContext().getParent()); - super.writeEndArray(gen, numValues); - } - - @Override - public void writeArrayValueSeparator(JsonGenerator gen) throws IOException { - updateIndenter(gen.getOutputContext().getParent()); - super.writeArrayValueSeparator(gen); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/json/JCalRawReader.java b/app/src/main/java/biweekly/io/json/JCalRawReader.java deleted file mode 100644 index 390c5d7529..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalRawReader.java +++ /dev/null @@ -1,335 +0,0 @@ -package biweekly.io.json; - -import java.io.Closeable; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalDataType; -import biweekly.io.scribe.ScribeIndex; -import biweekly.parameter.ICalParameters; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Parses an iCalendar JSON data stream (jCal). - * @author Michael Angstadt - * @see RFC 7265 - */ -public class JCalRawReader implements Closeable { - private static final String VCALENDAR_COMPONENT_NAME = ScribeIndex.getICalendarScribe().getComponentName().toLowerCase(); //"vcalendar" - - private final Reader reader; - private JsonParser parser; - private boolean eof = false; - private JCalDataStreamListener listener; - private boolean strict = false; - - /** - * @param reader the reader to wrap - */ - public JCalRawReader(Reader reader) { - this.reader = reader; - } - - /** - * @param parser the parser to read from - * @param strict true if the parser's current token is expected to be - * positioned at the start of a jCard, false if not. If this is true, and - * the parser is not positioned at the beginning of a jCard, a - * {@link JCalParseException} will be thrown. If this if false, the parser - * will consume input until it reaches the beginning of a jCard. - */ - public JCalRawReader(JsonParser parser, boolean strict) { - reader = null; - this.parser = parser; - this.strict = strict; - } - - /** - * Gets the current line number. - * @return the line number - */ - public int getLineNum() { - return (parser == null) ? 0 : parser.getCurrentLocation().getLineNr(); - } - - /** - * Reads the next iCalendar object from the jCal data stream. - * @param listener handles the iCalendar data as it is read off the wire - * @throws JCalParseException if the jCal syntax is incorrect (the JSON - * syntax may be valid, but it is not in the correct jCal format). - * @throws JsonParseException if the JSON syntax is incorrect - * @throws IOException if there is a problem reading from the data stream - */ - public void readNext(JCalDataStreamListener listener) throws IOException { - if (parser == null) { - JsonFactory factory = new JsonFactory(); - parser = factory.createParser(reader); - } - - if (parser.isClosed()) { - return; - } - - this.listener = listener; - - //find the next iCalendar object - JsonToken prev = parser.getCurrentToken(); - JsonToken cur; - while ((cur = parser.nextToken()) != null) { - if (prev == JsonToken.START_ARRAY && cur == JsonToken.VALUE_STRING && VCALENDAR_COMPONENT_NAME.equals(parser.getValueAsString())) { - //found - break; - } - - if (strict) { - //the parser was expecting the jCal to be there - if (prev != JsonToken.START_ARRAY) { - throw new JCalParseException(JsonToken.START_ARRAY, prev); - } - - if (cur != JsonToken.VALUE_STRING) { - throw new JCalParseException(JsonToken.VALUE_STRING, cur); - } - - throw new JCalParseException("Invalid value for first token: expected \"vcalendar\" , was \"" + parser.getValueAsString() + "\"", JsonToken.VALUE_STRING, cur); - } - - prev = cur; - } - - if (cur == null) { - //EOF - eof = true; - return; - } - - parseComponent(new ArrayList()); - } - - private void parseComponent(List components) throws IOException { - checkCurrent(JsonToken.VALUE_STRING); - String componentName = parser.getValueAsString(); - listener.readComponent(components, componentName); - components.add(componentName); - - //start properties array - checkNext(JsonToken.START_ARRAY); - - //read properties - while (parser.nextToken() != JsonToken.END_ARRAY) { //until we reach the end properties array - checkCurrent(JsonToken.START_ARRAY); - parser.nextToken(); - parseProperty(components); - } - - //start sub-components array - checkNext(JsonToken.START_ARRAY); - - //read sub-components - while (parser.nextToken() != JsonToken.END_ARRAY) { //until we reach the end sub-components array - checkCurrent(JsonToken.START_ARRAY); - parser.nextToken(); - parseComponent(new ArrayList(components)); - } - - //read the end of the component array (e.g. the last bracket in this example: ["comp", [ /* props */ ], [ /* comps */] ]) - checkNext(JsonToken.END_ARRAY); - } - - private void parseProperty(List components) throws IOException { - //get property name - checkCurrent(JsonToken.VALUE_STRING); - String propertyName = parser.getValueAsString().toLowerCase(); - - ICalParameters parameters = parseParameters(); - - //get data type - checkNext(JsonToken.VALUE_STRING); - String dataTypeStr = parser.getText(); - ICalDataType dataType = "unknown".equals(dataTypeStr) ? null : ICalDataType.get(dataTypeStr); - - //get property value(s) - List values = parseValues(); - - JCalValue value = new JCalValue(values); - listener.readProperty(components, propertyName, parameters, dataType, value); - } - - private ICalParameters parseParameters() throws IOException { - checkNext(JsonToken.START_OBJECT); - - ICalParameters parameters = new ICalParameters(); - while (parser.nextToken() != JsonToken.END_OBJECT) { - String parameterName = parser.getText(); - - if (parser.nextToken() == JsonToken.START_ARRAY) { - //multi-valued parameter - while (parser.nextToken() != JsonToken.END_ARRAY) { - parameters.put(parameterName, parser.getText()); - } - } else { - parameters.put(parameterName, parser.getValueAsString()); - } - } - - return parameters; - } - - private List parseValues() throws IOException { - List values = new ArrayList(); - while (parser.nextToken() != JsonToken.END_ARRAY) { //until we reach the end of the property array - JsonValue value = parseValue(); - values.add(value); - } - return values; - } - - private Object parseValueElement() throws IOException { - switch (parser.getCurrentToken()) { - case VALUE_FALSE: - case VALUE_TRUE: - return parser.getBooleanValue(); - case VALUE_NUMBER_FLOAT: - return parser.getDoubleValue(); - case VALUE_NUMBER_INT: - return parser.getLongValue(); - case VALUE_NULL: - return null; - default: - return parser.getText(); - } - } - - private List parseValueArray() throws IOException { - List array = new ArrayList(); - - while (parser.nextToken() != JsonToken.END_ARRAY) { - JsonValue value = parseValue(); - array.add(value); - } - - return array; - } - - private Map parseValueObject() throws IOException { - Map object = new HashMap(); - - parser.nextToken(); - while (parser.getCurrentToken() != JsonToken.END_OBJECT) { - checkCurrent(JsonToken.FIELD_NAME); - - String key = parser.getText(); - parser.nextToken(); - JsonValue value = parseValue(); - object.put(key, value); - - parser.nextToken(); - } - - return object; - } - - private JsonValue parseValue() throws IOException { - switch (parser.getCurrentToken()) { - case START_ARRAY: - return new JsonValue(parseValueArray()); - case START_OBJECT: - return new JsonValue(parseValueObject()); - default: - return new JsonValue(parseValueElement()); - } - } - - private void checkNext(JsonToken expected) throws IOException { - JsonToken actual = parser.nextToken(); - check(expected, actual); - } - - private void checkCurrent(JsonToken expected) throws JCalParseException { - JsonToken actual = parser.getCurrentToken(); - check(expected, actual); - } - - private void check(JsonToken expected, JsonToken actual) throws JCalParseException { - if (actual != expected) { - throw new JCalParseException(expected, actual); - } - } - - /** - * Determines whether the end of the data stream has been reached. - * @return true if the end has been reached, false if not - */ - public boolean eof() { - return eof; - } - - /** - * Handles the iCalendar data as it is read off the data stream. - * @author Michael Angstadt - */ - public interface JCalDataStreamListener { - /** - * Called when the parser begins to read a component. - * @param parentHierarchy the component's parent components - * @param componentName the component name (e.g. "vevent") - */ - void readComponent(List parentHierarchy, String componentName); - - /** - * Called when a property is read. - * @param componentHierarchy the hierarchy of components that the - * property belongs to - * @param propertyName the property name (e.g. "summary") - * @param parameters the parameters - * @param dataType the data type (e.g. "text") - * @param value the property value - */ - void readProperty(List componentHierarchy, String propertyName, ICalParameters parameters, ICalDataType dataType, JCalValue value); - } - - /** - * Closes the underlying {@link Reader} object. - */ - public void close() throws IOException { - if (parser != null) { - parser.close(); - } - if (reader != null) { - reader.close(); - } - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalRawWriter.java b/app/src/main/java/biweekly/io/json/JCalRawWriter.java deleted file mode 100644 index 34c3c2a887..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalRawWriter.java +++ /dev/null @@ -1,364 +0,0 @@ -package biweekly.io.json; - -import java.io.Closeable; -import java.io.Flushable; -import java.io.IOException; -import java.io.Writer; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import biweekly.ICalDataType; -import biweekly.Messages; -import biweekly.parameter.ICalParameters; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonGenerator.Feature; -import com.fasterxml.jackson.core.PrettyPrinter; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Writes data to an iCalendar JSON data stream (jCal). - * @author Michael Angstadt - * @see RFC 7265 - */ -public class JCalRawWriter implements Closeable, Flushable { - private final Writer writer; - private final boolean wrapInArray; - private final LinkedList stack = new LinkedList(); - private JsonGenerator generator; - private boolean prettyPrint = false; - private boolean componentEnded = false; - private boolean closeGenerator = true; - private PrettyPrinter prettyPrinter; - - /** - * @param writer the writer to wrap - * @param wrapInArray true to wrap everything in an array, false not to - * (useful when writing more than one iCalendar object) - */ - public JCalRawWriter(Writer writer, boolean wrapInArray) { - this.writer = writer; - this.wrapInArray = wrapInArray; - } - - /** - * @param generator the generator to write to - */ - public JCalRawWriter(JsonGenerator generator) { - this.writer = null; - this.generator = generator; - this.closeGenerator = false; - this.wrapInArray = false; - } - - /** - * Gets whether or not the JSON will be pretty-printed. - * @return true if it will be pretty-printed, false if not (defaults to - * false) - */ - public boolean isPrettyPrint() { - return prettyPrint; - } - - /** - * Sets whether or not to pretty-print the JSON. - * @param prettyPrint true to pretty-print it, false not to (defaults to - * false) - */ - public void setPrettyPrint(boolean prettyPrint) { - this.prettyPrint = prettyPrint; - } - - /** - * Sets the pretty printer to pretty-print the JSON with. Note that this - * method implicitly enables indenting, so {@code setPrettyPrint(true)} does - * not also need to be called. - * @param prettyPrinter the custom pretty printer (defaults to an instance - * of {@link JCalPrettyPrinter}, if {@code setPrettyPrint(true)} has been - * called) - */ - public void setPrettyPrinter(PrettyPrinter prettyPrinter) { - prettyPrint = true; - this.prettyPrinter = prettyPrinter; - } - - /** - * Writes the beginning of a new component array. - * @param componentName the component name (e.g. "vevent") - * @throws IOException if there's an I/O problem - */ - public void writeStartComponent(String componentName) throws IOException { - if (generator == null) { - init(); - } - - componentEnded = false; - - if (!stack.isEmpty()) { - Info parent = stack.getLast(); - if (!parent.wroteEndPropertiesArray) { - generator.writeEndArray(); - parent.wroteEndPropertiesArray = true; - } - if (!parent.wroteStartSubComponentsArray) { - generator.writeStartArray(); - parent.wroteStartSubComponentsArray = true; - } - } - - generator.writeStartArray(); - generator.writeString(componentName); - generator.writeStartArray(); //start properties array - - stack.add(new Info()); - } - - /** - * Closes the current component array. - * @throws IllegalStateException if there are no open components ( - * {@link #writeStartComponent(String)} must be called first) - * @throws IOException if there's an I/O problem - */ - public void writeEndComponent() throws IOException { - if (stack.isEmpty()) { - throw new IllegalStateException(Messages.INSTANCE.getExceptionMessage(2)); - } - Info cur = stack.removeLast(); - - if (!cur.wroteEndPropertiesArray) { - generator.writeEndArray(); - } - if (!cur.wroteStartSubComponentsArray) { - generator.writeStartArray(); - } - - generator.writeEndArray(); //end sub-components array - generator.writeEndArray(); //end the array of this component - - componentEnded = true; - } - - /** - * Writes a property to the current component. - * @param propertyName the property name (e.g. "version") - * @param dataType the property's data type (e.g. "text") - * @param value the property value - * @throws IllegalStateException if there are no open components ( - * {@link #writeStartComponent(String)} must be called first) or if the last - * method called was {@link #writeEndComponent()}. - * @throws IOException if there's an I/O problem - */ - public void writeProperty(String propertyName, ICalDataType dataType, JCalValue value) throws IOException { - writeProperty(propertyName, new ICalParameters(), dataType, value); - } - - /** - * Writes a property to the current component. - * @param propertyName the property name (e.g. "version") - * @param parameters the parameters - * @param dataType the property's data type (e.g. "text") - * @param value the property value - * @throws IllegalStateException if there are no open components ( - * {@link #writeStartComponent(String)} must be called first) or if the last - * method called was {@link #writeEndComponent()}. - * @throws IOException if there's an I/O problem - */ - public void writeProperty(String propertyName, ICalParameters parameters, ICalDataType dataType, JCalValue value) throws IOException { - if (stack.isEmpty()) { - throw new IllegalStateException(Messages.INSTANCE.getExceptionMessage(2)); - } - if (componentEnded) { - throw new IllegalStateException(Messages.INSTANCE.getExceptionMessage(3)); - } - - generator.setCurrentValue(JCalPrettyPrinter.PROPERTY_VALUE); - - generator.writeStartArray(); - - //write the property name - generator.writeString(propertyName); - - //write parameters - generator.writeStartObject(); - for (Map.Entry> entry : parameters) { - String name = entry.getKey().toLowerCase(); - List values = entry.getValue(); - if (values.isEmpty()) { - continue; - } - - if (values.size() == 1) { - generator.writeStringField(name, values.get(0)); - } else { - generator.writeArrayFieldStart(name); - for (String paramValue : values) { - generator.writeString(paramValue); - } - generator.writeEndArray(); - } - } - generator.writeEndObject(); - - //write data type - generator.writeString((dataType == null) ? "unknown" : dataType.getName().toLowerCase()); - - //write value - for (JsonValue jsonValue : value.getValues()) { - writeValue(jsonValue); - } - - generator.writeEndArray(); - - generator.setCurrentValue(null); - } - - private void writeValue(JsonValue jsonValue) throws IOException { - if (jsonValue.isNull()) { - generator.writeNull(); - return; - } - - Object val = jsonValue.getValue(); - if (val != null) { - if (val instanceof Byte) { - generator.writeNumber((Byte) val); - } else if (val instanceof Short) { - generator.writeNumber((Short) val); - } else if (val instanceof Integer) { - generator.writeNumber((Integer) val); - } else if (val instanceof Long) { - generator.writeNumber((Long) val); - } else if (val instanceof Float) { - generator.writeNumber((Float) val); - } else if (val instanceof Double) { - generator.writeNumber((Double) val); - } else if (val instanceof Boolean) { - generator.writeBoolean((Boolean) val); - } else { - generator.writeString(val.toString()); - } - return; - } - - List array = jsonValue.getArray(); - if (array != null) { - generator.writeStartArray(); - for (JsonValue element : array) { - writeValue(element); - } - generator.writeEndArray(); - return; - } - - Map object = jsonValue.getObject(); - if (object != null) { - generator.writeStartObject(); - for (Map.Entry entry : object.entrySet()) { - generator.writeFieldName(entry.getKey()); - writeValue(entry.getValue()); - } - generator.writeEndObject(); - return; - } - } - - /** - * Flushes the JSON stream. - * @throws IOException if there's a problem flushing the stream - */ - public void flush() throws IOException { - if (generator == null) { - return; - } - - generator.flush(); - } - - /** - * Finishes writing the JSON document so that it is syntactically correct. - * No more data can be written once this method is called. - * @throws IOException if there's a problem closing the stream - */ - public void closeJsonStream() throws IOException { - if (generator == null) { - return; - } - - while (!stack.isEmpty()) { - writeEndComponent(); - } - - if (wrapInArray) { - generator.writeEndArray(); - } - - if (closeGenerator) { - generator.close(); - } - } - - /** - * Finishes writing the JSON document and closes the underlying - * {@link Writer}. - * @throws IOException if there's a problem closing the stream - */ - public void close() throws IOException { - if (generator == null) { - return; - } - - closeJsonStream(); - - if (writer != null) { - writer.close(); - } - } - - private void init() throws IOException { - JsonFactory factory = new JsonFactory(); - factory.configure(Feature.AUTO_CLOSE_TARGET, false); - generator = factory.createGenerator(writer); - - if (prettyPrint) { - if (prettyPrinter == null) { - prettyPrinter = new JCalPrettyPrinter(); - } - generator.setPrettyPrinter(prettyPrinter); - } - - if (wrapInArray) { - generator.writeStartArray(); - } - } - - private static class Info { - public boolean wroteEndPropertiesArray = false; - public boolean wroteStartSubComponentsArray = false; - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalReader.java b/app/src/main/java/biweekly/io/json/JCalReader.java deleted file mode 100644 index 5371e772a4..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalReader.java +++ /dev/null @@ -1,241 +0,0 @@ -package biweekly.io.json; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.CannotParseException; -import biweekly.io.ParseWarning; -import biweekly.io.SkipMeException; -import biweekly.io.StreamReader; -import biweekly.io.json.JCalRawReader.JCalDataStreamListener; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.component.ICalendarScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.io.scribe.property.RawPropertyScribe; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.property.RawProperty; -import biweekly.property.Version; -import biweekly.util.Utf8Reader; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Parses {@link ICalendar} objects from a jCal data stream (JSON). - *

- *

- * Example: - *

- * - *
- * File file = new File("icals.json");
- * JCalReader reader = null;
- * try {
- *   reader = new JCalReader(file);
- *   ICalendar ical;
- *   while ((ical = reader.readNext()) != null) {
- *     //...
- *   }
- * } finally {
- *   if (reader != null) reader.close();
- * }
- * 
- * @author Michael Angstadt - * @see RFC 7265 - */ -public class JCalReader extends StreamReader { - private static final ICalendarScribe icalScribe = ScribeIndex.getICalendarScribe(); - private final JCalRawReader reader; - - /** - * @param json the JSON string to read from - */ - public JCalReader(String json) { - this(new StringReader(json)); - } - - /** - * @param in the input stream to read from - */ - public JCalReader(InputStream in) { - this(new Utf8Reader(in)); - } - - /** - * @param file the file to read from - * @throws FileNotFoundException if the file doesn't exist - */ - public JCalReader(File file) throws FileNotFoundException { - this(new BufferedReader(new Utf8Reader(file))); - } - - /** - * @param reader the reader to read from - */ - public JCalReader(Reader reader) { - this.reader = new JCalRawReader(reader); - } - - /** - * @param parser the parser to read from - */ - public JCalReader(JsonParser parser) { - this.reader = new JCalRawReader(parser, true); - } - - /** - * Reads the next iCalendar object from the JSON data stream. - * @return the iCalendar object or null if there are no more - * @throws JCalParseException if the jCal syntax is incorrect (the JSON - * syntax may be valid, but it is not in the correct jCal format). - * @throws JsonParseException if the JSON syntax is incorrect - * @throws IOException if there is a problem reading from the data stream - */ - @Override - public ICalendar _readNext() throws IOException { - if (reader.eof()) { - return null; - } - - context.setVersion(ICalVersion.V2_0); - - JCalDataStreamListenerImpl listener = new JCalDataStreamListenerImpl(); - reader.readNext(listener); - - return listener.getICalendar(); - } - - //@Override - public void close() throws IOException { - reader.close(); - } - - private class JCalDataStreamListenerImpl implements JCalDataStreamListener { - private final Map, ICalComponent> components = new HashMap, ICalComponent>(); - - public void readProperty(List componentHierarchy, String propertyName, ICalParameters parameters, ICalDataType dataType, JCalValue value) { - context.getWarnings().clear(); - context.setLineNumber(reader.getLineNum()); - context.setPropertyName(propertyName); - - //get the component that the property belongs to - ICalComponent parent = components.get(componentHierarchy); - - //unmarshal the property - ICalPropertyScribe scribe = index.getPropertyScribe(propertyName, ICalVersion.V2_0); - try { - ICalProperty property = scribe.parseJson(value, dataType, parameters, context); - warnings.addAll(context.getWarnings()); - - //set "ICalendar.version" if the value of the VERSION property is recognized - //otherwise, unmarshal VERSION like a normal property - if (parent instanceof ICalendar && property instanceof Version) { - Version version = (Version) property; - ICalVersion icalVersion = version.toICalVersion(); - if (icalVersion != null) { - context.setVersion(icalVersion); - return; - } - } - - parent.addProperty(property); - } catch (SkipMeException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(0, e.getMessage()) - .build() - ); - //@formatter:on - } catch (CannotParseException e) { - RawProperty property = new RawPropertyScribe(propertyName).parseJson(value, dataType, parameters, context); - parent.addProperty(property); - - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(e) - .build() - ); - //@formatter:on - } - } - - public void readComponent(List parentHierarchy, String componentName) { - ICalComponentScribe scribe = index.getComponentScribe(componentName, ICalVersion.V2_0); - ICalComponent component = scribe.emptyInstance(); - - ICalComponent parent = components.get(parentHierarchy); - if (parent != null) { - parent.addComponent(component); - } - - List hierarchy = new ArrayList(parentHierarchy); - hierarchy.add(componentName); - components.put(hierarchy, component); - } - - public ICalendar getICalendar() { - if (components.isEmpty()) { - //EOF - return null; - } - - ICalComponent component = components.get(Collections.singletonList(icalScribe.getComponentName().toLowerCase())); - if (component == null) { - //should never happen because the parser always looks for a "vcalendar" component - return null; - } - - if (component instanceof ICalendar) { - //should happen every time - return (ICalendar) component; - } - - //this will only happen if the user decides to override the ICalendarScribe for some reason - ICalendar ical = icalScribe.emptyInstance(); - ical.addComponent(component); - return ical; - } - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalSerializer.java b/app/src/main/java/biweekly/io/json/JCalSerializer.java deleted file mode 100644 index f006b9d12c..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalSerializer.java +++ /dev/null @@ -1,116 +0,0 @@ -package biweekly.io.json; - -import java.io.IOException; - -import biweekly.ICalendar; -import biweekly.io.TimezoneAssignment; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.property.ICalProperty; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Serializes jCals within the jackson-databind framework. - * @author Buddy Gorven - * @author Michael Angstadt - */ -@JsonFormat -public class JCalSerializer extends StdSerializer { - private static final long serialVersionUID = 8964681078186049817L; - private ScribeIndex index = new ScribeIndex(); - private TimezoneAssignment globalTimezone; - - public JCalSerializer() { - super(ICalendar.class); - } - - @Override - public void serialize(ICalendar value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { - @SuppressWarnings("resource") - JCalWriter writer = new JCalWriter(gen); - writer.setScribeIndex(getScribeIndex()); - writer.setGlobalTimezone(globalTimezone); - writer.write(value); - } - - /** - *

- * Registers a property scribe. This is the same as calling: - *

- *

- * {@code getScribeIndex().register(scribe)} - *

- * @param scribe the scribe to register - */ - public void registerScribe(ICalPropertyScribe scribe) { - index.register(scribe); - } - - /** - * Gets the scribe index. - * @return the scribe index - */ - public ScribeIndex getScribeIndex() { - return index; - } - - /** - * Sets the scribe index. - * @param index the scribe index - */ - public void setScribeIndex(ScribeIndex index) { - this.index = index; - } - - /** - * Gets the timezone that all date/time property values will be formatted - * in. If set, this setting will override the timezone information - * associated with each {@link ICalendar} object. - * @return the global timezone or null if not set (defaults to null) - */ - public TimezoneAssignment getGlobalTimezone() { - return globalTimezone; - } - - /** - * Sets the timezone that all date/time property values will be formatted - * in. This is a convenience method that overrides the timezone information - * associated with each {@link ICalendar} object that is passed into this - * writer. - * @param globalTimezone the global timezone or null not to set a global - * timezone (defaults to null) - */ - public void setGlobalTimezone(TimezoneAssignment globalTimezone) { - this.globalTimezone = globalTimezone; - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalValue.java b/app/src/main/java/biweekly/io/json/JCalValue.java deleted file mode 100644 index 087912a3f4..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalValue.java +++ /dev/null @@ -1,360 +0,0 @@ -package biweekly.io.json; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.util.ListMultimap; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Holds the value of a jCal property. - * @author Michael Angstadt - */ -public class JCalValue { - private final List values; - - /** - * Creates a new jCal value. - * @param values the values - */ - public JCalValue(List values) { - this.values = Collections.unmodifiableList(values); - } - - /** - * Creates a new jCal value. - * @param values the values - */ - public JCalValue(JsonValue... values) { - this.values = Arrays.asList(values); //unmodifiable - } - - /** - * Creates a single-valued value. - * @param value the value - * @return the jCal value - */ - public static JCalValue single(Object value) { - return new JCalValue(new JsonValue(value)); - } - - /** - * Creates a multi-valued value. - * @param values the values - * @return the jCal value - */ - public static JCalValue multi(Object... values) { - return multi(Arrays.asList(values)); - } - - /** - * Creates a multi-valued value. - * @param values the values - * @return the jCal value - */ - public static JCalValue multi(List values) { - List multiValues = new ArrayList(values.size()); - for (Object value : values) { - multiValues.add(new JsonValue(value)); - } - return new JCalValue(multiValues); - } - - /** - *

- * Creates a structured value. - *

- *

- * This method accepts a vararg of {@link Object} instances. {@link List} - * objects will be treated as multi-valued components. All other objects. - * Null values will be treated as empty components. - *

- * @param values the values - * @return the jCal value - */ - public static JCalValue structured(Object... values) { - List> valuesList = new ArrayList>(values.length); - for (Object value : values) { - List list = (value instanceof List) ? (List) value : Collections.singletonList(value); - valuesList.add(list); - } - return structured(valuesList); - } - - /** - * Creates a structured value. - * @param values the values - * @return the jCal value - */ - public static JCalValue structured(List> values) { - List array = new ArrayList(values.size()); - - for (List list : values) { - if (list.isEmpty()) { - array.add(new JsonValue("")); - continue; - } - - if (list.size() == 1) { - Object value = list.get(0); - if (value == null) { - value = ""; - } - array.add(new JsonValue(value)); - continue; - } - - List subArray = new ArrayList(list.size()); - for (Object value : list) { - if (value == null) { - value = ""; - } - subArray.add(new JsonValue(value)); - } - array.add(new JsonValue(subArray)); - } - - return new JCalValue(new JsonValue(array)); - } - - /** - * Creates an object value. - * @param value the object - * @return the jCal value - */ - public static JCalValue object(ListMultimap value) { - Map object = new LinkedHashMap(); - for (Map.Entry> entry : value) { - String key = entry.getKey(); - List list = entry.getValue(); - - JsonValue v; - if (list.size() == 1) { - v = new JsonValue(list.get(0)); - } else { - List array = new ArrayList(list.size()); - for (Object element : list) { - array.add(new JsonValue(element)); - } - v = new JsonValue(array); - } - object.put(key, v); - } - return new JCalValue(new JsonValue(object)); - } - - /** - * Gets the raw JSON values. Use one of the "{@code as*}" methods to parse - * the values as one of the standard jCal values. - * @return the JSON values - */ - public List getValues() { - return values; - } - - /** - * Parses this jCal value as a single-valued property value. - * @return the value or empty string if not found - */ - public String asSingle() { - if (values.isEmpty()) { - return ""; - } - - JsonValue first = values.get(0); - if (first.isNull()) { - return ""; - } - - Object obj = first.getValue(); - if (obj != null) { - return obj.toString(); - } - - //get the first element of the array - List array = first.getArray(); - if (array != null && !array.isEmpty()) { - obj = array.get(0).getValue(); - if (obj != null) { - return obj.toString(); - } - } - - return ""; - } - - /** - * Parses this jCal value as a structured property value. - * @return the structured values or empty list if not found - */ - public List> asStructured() { - if (values.isEmpty()) { - return Collections.emptyList(); - } - - JsonValue first = values.get(0); - - //["request-status", {}, "text", ["2.0", "Success"] ] - List array = first.getArray(); - if (array != null) { - List> components = new ArrayList>(array.size()); - for (JsonValue value : array) { - if (value.isNull()) { - components.add(Collections.emptyList()); - continue; - } - - Object obj = value.getValue(); - if (obj != null) { - String s = obj.toString(); - List component = s.isEmpty() ? Collections.emptyList() : Collections.singletonList(s); - components.add(component); - continue; - } - - List subArray = value.getArray(); - if (subArray != null) { - List component = new ArrayList(subArray.size()); - for (JsonValue subArrayValue : subArray) { - if (subArrayValue.isNull()) { - component.add(""); - continue; - } - - obj = subArrayValue.getValue(); - if (obj != null) { - component.add(obj.toString()); - continue; - } - } - if (component.size() == 1 && component.get(0).isEmpty()) { - component.clear(); - } - components.add(component); - } - } - return components; - } - - //get the first value if it's not enclosed in an array - //["request-status", {}, "text", "2.0"] - Object obj = first.getValue(); - if (obj != null) { - List> components = new ArrayList>(1); - String s = obj.toString(); - List component = s.isEmpty() ? Collections.emptyList() : Collections.singletonList(s); - components.add(component); - return components; - } - - //["request-status", {}, "text", null] - if (first.isNull()) { - List> components = new ArrayList>(1); - components.add(Collections.emptyList()); - return components; - } - - return Collections.emptyList(); - } - - /** - * Parses this jCal value as a multi-valued property value. - * @return the values or empty list if not found - */ - public List asMulti() { - if (values.isEmpty()) { - return Collections.emptyList(); - } - - List multi = new ArrayList(values.size()); - for (JsonValue value : values) { - if (value.isNull()) { - multi.add(""); - continue; - } - - Object obj = value.getValue(); - if (obj != null) { - multi.add(obj.toString()); - continue; - } - } - return multi; - } - - /** - * Parses this jCal value as an object property value. - * @return the object or an empty map if not found - */ - public ListMultimap asObject() { - if (values.isEmpty()) { - return new ListMultimap(0); - } - - Map map = values.get(0).getObject(); - if (map == null) { - return new ListMultimap(0); - } - - ListMultimap values = new ListMultimap(); - for (Map.Entry entry : map.entrySet()) { - String key = entry.getKey(); - JsonValue value = entry.getValue(); - - if (value.isNull()) { - values.put(key, ""); - continue; - } - - Object obj = value.getValue(); - if (obj != null) { - values.put(key, obj.toString()); - continue; - } - - List array = value.getArray(); - if (array != null) { - for (JsonValue element : array) { - if (element.isNull()) { - values.put(key, ""); - continue; - } - - obj = element.getValue(); - if (obj != null) { - values.put(key, obj.toString()); - } - } - } - } - return values; - } -} diff --git a/app/src/main/java/biweekly/io/json/JCalWriter.java b/app/src/main/java/biweekly/io/json/JCalWriter.java deleted file mode 100644 index 4c52be4e1c..0000000000 --- a/app/src/main/java/biweekly/io/json/JCalWriter.java +++ /dev/null @@ -1,250 +0,0 @@ -package biweekly.io.json; - -import java.io.File; -import java.io.Flushable; -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.util.Collection; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.component.VTimezone; -import biweekly.io.SkipMeException; -import biweekly.io.StreamWriter; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.property.Version; -import biweekly.util.Utf8Writer; - -import com.fasterxml.jackson.core.JsonGenerator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Writes {@link ICalendar} objects to a JSON data stream (jCal). - *

- *

- * Example: - *

- * - *
- * ICalendar ical1 = ...
- * ICalendar ical2 = ...
- * File file = new File("icals.json");
- * JCalWriter writer = null;
- * try {
- *   writer = new JCalWriter(file);
- *   writer.write(ical1);
- *   writer.write(ical2);
- * } finally {
- *   if (writer != null) writer.close();
- * }
- * 
- * @author Michael Angstadt - * @see RFC 7265 - */ -public class JCalWriter extends StreamWriter implements Flushable { - private final JCalRawWriter writer; - private final ICalVersion targetVersion = ICalVersion.V2_0; - - /** - * @param out the output stream to write to (UTF-8 encoding will be used) - */ - public JCalWriter(OutputStream out) { - this(new Utf8Writer(out)); - } - - /** - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param wrapInArray true to wrap all iCalendar objects in a parent array, - * false not to (useful when writing more than one iCalendar object) - */ - public JCalWriter(OutputStream out, boolean wrapInArray) { - this(new Utf8Writer(out), wrapInArray); - } - - /** - * @param file the file to write to (UTF-8 encoding will be used) - * @throws IOException if the file cannot be written to - */ - public JCalWriter(File file) throws IOException { - this(new Utf8Writer(file)); - } - - /** - * @param file the file to write to (UTF-8 encoding will be used) - * @param wrapInArray true to wrap all iCalendar objects in a parent array, - * false not to (useful when writing more than one iCalendar object) - * @throws IOException if the file cannot be written to - */ - public JCalWriter(File file, boolean wrapInArray) throws IOException { - this(new Utf8Writer(file), wrapInArray); - } - - /** - * @param writer the writer to write to - */ - public JCalWriter(Writer writer) { - this(writer, false); - } - - /** - * @param writer the writer to write to - * @param wrapInArray true to wrap all iCalendar objects in a parent array, - * false not to (useful when writing more than one iCalendar object) - */ - public JCalWriter(Writer writer, boolean wrapInArray) { - this.writer = new JCalRawWriter(writer, wrapInArray); - } - - /** - * @param generator the generator to write to - */ - public JCalWriter(JsonGenerator generator) { - this.writer = new JCalRawWriter(generator); - } - - /** - * Gets whether or not the JSON will be pretty-printed. - * @return true if it will be pretty-printed, false if not (defaults to - * false) - */ - public boolean isPrettyPrint() { - return writer.isPrettyPrint(); - } - - /** - * Sets whether or not to pretty-print the JSON. - * @param prettyPrint true to pretty-print it, false not to (defaults to - * false) - */ - public void setPrettyPrint(boolean prettyPrint) { - writer.setPrettyPrint(prettyPrint); - } - - @Override - protected void _write(ICalendar ical) throws IOException { - writeComponent(ical); - } - - @Override - protected ICalVersion getTargetVersion() { - return targetVersion; - } - - /** - * Writes a component to the data stream. - * @param component the component to write - * @throws IllegalArgumentException if the scribe class for a component or - * property object cannot be found (only happens when an experimental - * property/component scribe is not registered with the - * {@code registerScribe} method.) - * @throws IOException if there's a problem writing to the data stream - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void writeComponent(ICalComponent component) throws IOException { - ICalComponentScribe componentScribe = index.getComponentScribe(component); - writer.writeStartComponent(componentScribe.getComponentName().toLowerCase()); - - List propertyObjs = componentScribe.getProperties(component); - if (component instanceof ICalendar && component.getProperty(Version.class) == null) { - propertyObjs.add(0, new Version(targetVersion)); - } - - //write properties - for (Object propertyObj : propertyObjs) { - context.setParent(component); //set parent here incase a scribe resets the parent - ICalProperty property = (ICalProperty) propertyObj; - ICalPropertyScribe propertyScribe = index.getPropertyScribe(property); - - //marshal property - ICalParameters parameters; - JCalValue value; - try { - parameters = propertyScribe.prepareParameters(property, context); - value = propertyScribe.writeJson(property, context); - } catch (SkipMeException e) { - continue; - } - - //write property - String propertyName = propertyScribe.getPropertyName(targetVersion).toLowerCase(); - ICalDataType dataType = propertyScribe.dataType(property, targetVersion); - writer.writeProperty(propertyName, parameters, dataType, value); - } - - //write sub-components - List subComponents = componentScribe.getComponents(component); - if (component instanceof ICalendar) { - //add the VTIMEZONE components that were auto-generated by TimezoneOptions - Collection tzs = getTimezoneComponents(); - for (VTimezone tz : tzs) { - if (!subComponents.contains(tz)) { - subComponents.add(0, tz); - } - } - } - for (Object subComponentObj : subComponents) { - ICalComponent subComponent = (ICalComponent) subComponentObj; - writeComponent(subComponent); - } - - writer.writeEndComponent(); - } - - /** - * Flushes the stream. - * @throws IOException if there's a problem flushing the stream - */ - public void flush() throws IOException { - writer.flush(); - } - - /** - * Finishes writing the JSON document and closes the underlying - * {@link Writer} object. - * @throws IOException if there's a problem closing the stream - */ - public void close() throws IOException { - writer.close(); - } - - /** - * Finishes writing the JSON document so that it is syntactically correct. - * No more iCalendar objects can be written once this method is called. - * @throws IOException if there's a problem writing to the data stream - */ - public void closeJsonStream() throws IOException { - writer.closeJsonStream(); - } -} diff --git a/app/src/main/java/biweekly/io/json/JsonValue.java b/app/src/main/java/biweekly/io/json/JsonValue.java deleted file mode 100644 index 729f51793d..0000000000 --- a/app/src/main/java/biweekly/io/json/JsonValue.java +++ /dev/null @@ -1,166 +0,0 @@ -package biweekly.io.json; - -import java.util.List; -import java.util.Map; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a JSON value, array, or object. - * @author Michael Angstadt - */ -public class JsonValue { - private final boolean isNull; - private final Object value; - private final List array; - private final Map object; - - /** - * Creates a JSON value (such as a string or integer). - * @param value the value - */ - public JsonValue(Object value) { - this.value = value; - array = null; - object = null; - isNull = (value == null); - } - - /** - * Creates a JSON array. - * @param array the array elements - */ - public JsonValue(List array) { - this.array = array; - value = null; - object = null; - isNull = (array == null); - } - - /** - * Creates a JSON object. - * @param object the object fields - */ - public JsonValue(Map object) { - this.object = object; - value = null; - array = null; - isNull = (object == null); - } - - /** - * Gets the JSON value. - * @return the value or null if it's not a JSON value - */ - public Object getValue() { - return value; - } - - /** - * Gets the JSON array elements. - * @return the array elements or null if it's not a JSON array - */ - public List getArray() { - return array; - } - - /** - * Gets the JSON object. - * @return the object or null if it's not a JSON object - */ - public Map getObject() { - return object; - } - - /** - * Determines if the value is "null" or not. - * @return true if the value is "null", false if not - */ - public boolean isNull() { - return isNull; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((array == null) ? 0 : array.hashCode()); - result = prime * result + (isNull ? 1231 : 1237); - result = prime * result + ((object == null) ? 0 : object.hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - JsonValue other = (JsonValue) obj; - if (array == null) { - if (other.array != null) - return false; - } else if (!array.equals(other.array)) - return false; - if (isNull != other.isNull) - return false; - if (object == null) { - if (other.object != null) - return false; - } else if (!object.equals(other.object)) - return false; - if (value == null) { - if (other.value != null) - return false; - } else if (!value.equals(other.value)) - return false; - return true; - } - - @Override - public String toString() { - if (isNull) { - return "NULL"; - } - - if (value != null) { - return "VALUE = " + value; - } - - if (array != null) { - return "ARRAY = " + array; - } - - if (object != null) { - return "OBJECT = " + object; - } - - return ""; - } -} diff --git a/app/src/main/java/biweekly/io/json/package-info.java b/app/src/main/java/biweekly/io/json/package-info.java deleted file mode 100644 index ce1a29df11..0000000000 --- a/app/src/main/java/biweekly/io/json/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes for reading and writing jCals (JSON-encoded iCalendar objects). - */ -package biweekly.io.json; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/package-info.java b/app/src/main/java/biweekly/io/package-info.java deleted file mode 100644 index 4b115d5669..0000000000 --- a/app/src/main/java/biweekly/io/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains I/O related classes. - */ -package biweekly.io; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/ScribeIndex.java b/app/src/main/java/biweekly/io/scribe/ScribeIndex.java deleted file mode 100644 index 417a7b66b9..0000000000 --- a/app/src/main/java/biweekly/io/scribe/ScribeIndex.java +++ /dev/null @@ -1,451 +0,0 @@ -package biweekly.io.scribe; - -import java.util.HashMap; -import java.util.Map; - -import javax.xml.namespace.QName; - -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.component.RawComponent; -import biweekly.io.scribe.component.DaylightSavingsTimeScribe; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.component.ICalendarScribe; -import biweekly.io.scribe.component.RawComponentScribe; -import biweekly.io.scribe.component.StandardTimeScribe; -import biweekly.io.scribe.component.VAlarmScribe; -import biweekly.io.scribe.component.VEventScribe; -import biweekly.io.scribe.component.VFreeBusyScribe; -import biweekly.io.scribe.component.VJournalScribe; -import biweekly.io.scribe.component.VTimezoneScribe; -import biweekly.io.scribe.component.VTodoScribe; -import biweekly.io.scribe.property.ActionScribe; -import biweekly.io.scribe.property.AttachmentScribe; -import biweekly.io.scribe.property.AttendeeScribe; -import biweekly.io.scribe.property.AudioAlarmScribe; -import biweekly.io.scribe.property.CalendarScaleScribe; -import biweekly.io.scribe.property.CategoriesScribe; -import biweekly.io.scribe.property.ClassificationScribe; -import biweekly.io.scribe.property.ColorScribe; -import biweekly.io.scribe.property.CommentScribe; -import biweekly.io.scribe.property.CompletedScribe; -import biweekly.io.scribe.property.ConferenceScribe; -import biweekly.io.scribe.property.ContactScribe; -import biweekly.io.scribe.property.CreatedScribe; -import biweekly.io.scribe.property.DateDueScribe; -import biweekly.io.scribe.property.DateEndScribe; -import biweekly.io.scribe.property.DateStartScribe; -import biweekly.io.scribe.property.DateTimeStampScribe; -import biweekly.io.scribe.property.DaylightScribe; -import biweekly.io.scribe.property.DescriptionScribe; -import biweekly.io.scribe.property.DisplayAlarmScribe; -import biweekly.io.scribe.property.DurationPropertyScribe; -import biweekly.io.scribe.property.EmailAlarmScribe; -import biweekly.io.scribe.property.ExceptionDatesScribe; -import biweekly.io.scribe.property.ExceptionRuleScribe; -import biweekly.io.scribe.property.FreeBusyScribe; -import biweekly.io.scribe.property.GeoScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.io.scribe.property.ImageScribe; -import biweekly.io.scribe.property.LastModifiedScribe; -import biweekly.io.scribe.property.LocationScribe; -import biweekly.io.scribe.property.MethodScribe; -import biweekly.io.scribe.property.NameScribe; -import biweekly.io.scribe.property.OrganizerScribe; -import biweekly.io.scribe.property.PercentCompleteScribe; -import biweekly.io.scribe.property.PriorityScribe; -import biweekly.io.scribe.property.ProcedureAlarmScribe; -import biweekly.io.scribe.property.ProductIdScribe; -import biweekly.io.scribe.property.RawPropertyScribe; -import biweekly.io.scribe.property.RecurrenceDatesScribe; -import biweekly.io.scribe.property.RecurrenceIdScribe; -import biweekly.io.scribe.property.RecurrenceRuleScribe; -import biweekly.io.scribe.property.RefreshIntervalScribe; -import biweekly.io.scribe.property.RelatedToScribe; -import biweekly.io.scribe.property.RepeatScribe; -import biweekly.io.scribe.property.RequestStatusScribe; -import biweekly.io.scribe.property.ResourcesScribe; -import biweekly.io.scribe.property.SequenceScribe; -import biweekly.io.scribe.property.SourceScribe; -import biweekly.io.scribe.property.StatusScribe; -import biweekly.io.scribe.property.SummaryScribe; -import biweekly.io.scribe.property.TimezoneIdScribe; -import biweekly.io.scribe.property.TimezoneNameScribe; -import biweekly.io.scribe.property.TimezoneOffsetFromScribe; -import biweekly.io.scribe.property.TimezoneOffsetToScribe; -import biweekly.io.scribe.property.TimezoneScribe; -import biweekly.io.scribe.property.TimezoneUrlScribe; -import biweekly.io.scribe.property.TransparencyScribe; -import biweekly.io.scribe.property.TriggerScribe; -import biweekly.io.scribe.property.UidScribe; -import biweekly.io.scribe.property.UrlScribe; -import biweekly.io.scribe.property.VersionScribe; -import biweekly.io.scribe.property.XmlScribe; -import biweekly.io.xml.XCalNamespaceContext; -import biweekly.property.ICalProperty; -import biweekly.property.RawProperty; -import biweekly.property.Xml; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Manages a listing of component and property scribes. This is useful for - * injecting the scribes of any experimental components or properties you have - * defined into a reader or writer object. The same ScribeIndex instance can be - * reused and injected into multiple reader/writer classes. - *

- *

- * Example: - *

- * - *
- * //init the index
- * ScribeIndex index = new ScribeIndex();
- * index.register(new CustomPropertyScribe());
- * index.register(new AnotherCustomPropertyScribe());
- * index.register(new CustomComponentScribe());
- * 
- * //inject into a reader class
- * ICalReader reader = new ICalReader(...);
- * reader.setScribeIndex(index);
- * List<ICalendar> icals = new ArrayList<ICalendar>();
- * ICalendar ical;
- * while ((ical = reader.readNext()) != null) {
- *   icals.add(ical);
- * }
- * 
- * //inject the same instance in another reader/writer class
- * JCalWriter writer = new JCalWriter(...);
- * writer.setScribeIndex(index);
- * for (ICalendar ical : icals) {
- *   writer.write(ical);
- * }
- * 
- * @author Michael Angstadt - */ -public class ScribeIndex { - //define standard component scribes - private static final Map> standardCompByName = new HashMap>(); - private static final Map, ICalComponentScribe> standardCompByClass = new HashMap, ICalComponentScribe>(); - static { - registerStandard(new ICalendarScribe()); - registerStandard(new VAlarmScribe()); - registerStandard(new VEventScribe()); - registerStandard(new VFreeBusyScribe()); - registerStandard(new VJournalScribe()); - registerStandard(new VTodoScribe()); - registerStandard(new VTimezoneScribe()); - registerStandard(new StandardTimeScribe()); - registerStandard(new DaylightSavingsTimeScribe()); - } - - //define standard property scribes - private static final Map> standardPropByName = new HashMap>(); - private static final Map, ICalPropertyScribe> standardPropByClass = new HashMap, ICalPropertyScribe>(); - private static final Map> standardPropByQName = new HashMap>(); - static { - //RFC 5545 - registerStandard(new ActionScribe()); - registerStandard(new AttachmentScribe()); - registerStandard(new AttendeeScribe()); - registerStandard(new CalendarScaleScribe()); - registerStandard(new CategoriesScribe()); - registerStandard(new ClassificationScribe()); - registerStandard(new CommentScribe()); - registerStandard(new CompletedScribe()); - registerStandard(new ContactScribe()); - registerStandard(new CreatedScribe()); - registerStandard(new DateDueScribe()); - registerStandard(new DateEndScribe()); - registerStandard(new DateStartScribe()); - registerStandard(new DateTimeStampScribe()); - registerStandard(new DescriptionScribe()); - registerStandard(new DurationPropertyScribe()); - registerStandard(new ExceptionDatesScribe()); - registerStandard(new FreeBusyScribe()); - registerStandard(new GeoScribe()); - registerStandard(new LastModifiedScribe()); - registerStandard(new LocationScribe()); - registerStandard(new MethodScribe()); - registerStandard(new OrganizerScribe()); - registerStandard(new PercentCompleteScribe()); - registerStandard(new PriorityScribe()); - registerStandard(new ProductIdScribe()); - registerStandard(new RecurrenceDatesScribe()); - registerStandard(new RecurrenceIdScribe()); - registerStandard(new RecurrenceRuleScribe()); - registerStandard(new RelatedToScribe()); - registerStandard(new RepeatScribe()); - registerStandard(new RequestStatusScribe()); - registerStandard(new ResourcesScribe()); - registerStandard(new SequenceScribe()); - registerStandard(new StatusScribe()); - registerStandard(new SummaryScribe()); - registerStandard(new TimezoneIdScribe()); - registerStandard(new TimezoneNameScribe()); - registerStandard(new TimezoneOffsetFromScribe()); - registerStandard(new TimezoneOffsetToScribe()); - registerStandard(new TimezoneUrlScribe()); - registerStandard(new TransparencyScribe()); - registerStandard(new TriggerScribe()); - registerStandard(new UidScribe()); - registerStandard(new UrlScribe()); - registerStandard(new VersionScribe()); - - //RFC 6321 - registerStandard(new XmlScribe()); - - //RFC 2445 - registerStandard(new ExceptionRuleScribe()); - - //vCal - registerStandard(new AudioAlarmScribe()); - registerStandard(new DaylightScribe()); - registerStandard(new DisplayAlarmScribe()); - registerStandard(new EmailAlarmScribe()); - registerStandard(new ProcedureAlarmScribe()); - registerStandard(new TimezoneScribe()); - - //draft-ietf-calext-extensions-01 - registerStandard(new ColorScribe()); - registerStandard(new ConferenceScribe()); - registerStandard(new ImageScribe()); - registerStandard(new NameScribe()); - registerStandard(new SourceScribe()); - registerStandard(new RefreshIntervalScribe()); - } - - private final Map> experimentalCompByName = new HashMap>(0); - private final Map, ICalComponentScribe> experimentalCompByClass = new HashMap, ICalComponentScribe>(0); - - private final Map> experimentalPropByName = new HashMap>(0); - private final Map, ICalPropertyScribe> experimentalPropByClass = new HashMap, ICalPropertyScribe>(0); - private final Map> experimentalPropByQName = new HashMap>(0); - - /** - * Gets a component scribe by name. - * @param componentName the component name (e.g. "VEVENT") - * @param version the version of the iCalendar object being parsed - * @return the component scribe or a {@link RawComponentScribe} if not found - */ - public ICalComponentScribe getComponentScribe(String componentName, ICalVersion version) { - componentName = componentName.toUpperCase(); - - ICalComponentScribe scribe = experimentalCompByName.get(componentName); - if (scribe == null) { - scribe = standardCompByName.get(componentName); - } - - if (scribe == null) { - return new RawComponentScribe(componentName); - } - - if (version != null && !scribe.getSupportedVersions().contains(version)) { - //treat the component as a raw component if the current iCal version doesn't support it - return new RawComponentScribe(componentName); - } - - return scribe; - } - - /** - * Gets a property scribe by name. - * @param propertyName the property name (e.g. "UID") - * @param version the version of the iCalendar object being parsed - * @return the property scribe or a {@link RawPropertyScribe} if not found - */ - public ICalPropertyScribe getPropertyScribe(String propertyName, ICalVersion version) { - propertyName = propertyName.toUpperCase(); - - String key = propertyNameKey(propertyName, version); - ICalPropertyScribe scribe = experimentalPropByName.get(key); - if (scribe == null) { - scribe = standardPropByName.get(key); - } - - if (scribe == null) { - return new RawPropertyScribe(propertyName); - } - - if (version != null && !scribe.getSupportedVersions().contains(version)) { - //treat the property as a raw property if the current iCal version doesn't support it - return new RawPropertyScribe(propertyName); - } - - return scribe; - } - - /** - * Gets a component scribe by class. - * @param clazz the component class - * @return the component scribe or null if not found - */ - public ICalComponentScribe getComponentScribe(Class clazz) { - ICalComponentScribe scribe = experimentalCompByClass.get(clazz); - if (scribe != null) { - return scribe; - } - - return standardCompByClass.get(clazz); - } - - /** - * Gets a property scribe by class. - * @param clazz the property class - * @return the property scribe or null if not found - */ - public ICalPropertyScribe getPropertyScribe(Class clazz) { - ICalPropertyScribe scribe = experimentalPropByClass.get(clazz); - if (scribe != null) { - return scribe; - } - - return standardPropByClass.get(clazz); - } - - /** - * Gets the appropriate component scribe for a given component instance. - * @param component the component instance - * @return the component scribe or null if not found - */ - public ICalComponentScribe getComponentScribe(ICalComponent component) { - if (component instanceof RawComponent) { - RawComponent raw = (RawComponent) component; - return new RawComponentScribe(raw.getName()); - } - - return getComponentScribe(component.getClass()); - } - - /** - * Gets the appropriate property scribe for a given property instance. - * @param property the property instance - * @return the property scribe or null if not found - */ - public ICalPropertyScribe getPropertyScribe(ICalProperty property) { - if (property instanceof RawProperty) { - RawProperty raw = (RawProperty) property; - return new RawPropertyScribe(raw.getName()); - } - - return getPropertyScribe(property.getClass()); - } - - /** - * Gets a property scribe by XML local name and namespace. - * @param qname the XML local name and namespace - * @return the property scribe or a {@link XmlScribe} if not found - */ - public ICalPropertyScribe getPropertyScribe(QName qname) { - ICalPropertyScribe scribe = experimentalPropByQName.get(qname); - if (scribe == null) { - scribe = standardPropByQName.get(qname); - } - - if (scribe == null || !scribe.getSupportedVersions().contains(ICalVersion.V2_0)) { - if (XCalNamespaceContext.XCAL_NS.equals(qname.getNamespaceURI())) { - return new RawPropertyScribe(qname.getLocalPart().toUpperCase()); - } - return getPropertyScribe(Xml.class); - } - - return scribe; - } - - /** - * Registers a component scribe. - * @param scribe the scribe to register - */ - public void register(ICalComponentScribe scribe) { - experimentalCompByName.put(scribe.getComponentName().toUpperCase(), scribe); - experimentalCompByClass.put(scribe.getComponentClass(), scribe); - } - - /** - * Registers a property scribe. - * @param scribe the scribe to register - */ - public void register(ICalPropertyScribe scribe) { - for (ICalVersion version : ICalVersion.values()) { - experimentalPropByName.put(propertyNameKey(scribe, version), scribe); - } - experimentalPropByClass.put(scribe.getPropertyClass(), scribe); - experimentalPropByQName.put(scribe.getQName(), scribe); - } - - /** - * Unregisters a component scribe. - * @param scribe the scribe to unregister - */ - public void unregister(ICalComponentScribe scribe) { - experimentalCompByName.remove(scribe.getComponentName().toUpperCase()); - experimentalCompByClass.remove(scribe.getComponentClass()); - } - - /** - * Unregisters a property scribe - * @param scribe the scribe to unregister - */ - public void unregister(ICalPropertyScribe scribe) { - for (ICalVersion version : ICalVersion.values()) { - experimentalPropByName.remove(propertyNameKey(scribe, version)); - } - experimentalPropByClass.remove(scribe.getPropertyClass()); - experimentalPropByQName.remove(scribe.getQName()); - } - - /** - * Convenience method for getting the scribe of the root iCalendar component - * ("VCALENDAR"). - * @return the scribe - */ - public static ICalendarScribe getICalendarScribe() { - return (ICalendarScribe) standardCompByClass.get(ICalendar.class); - } - - private static void registerStandard(ICalComponentScribe scribe) { - standardCompByName.put(scribe.getComponentName().toUpperCase(), scribe); - standardCompByClass.put(scribe.getComponentClass(), scribe); - } - - private static void registerStandard(ICalPropertyScribe scribe) { - for (ICalVersion version : ICalVersion.values()) { - standardPropByName.put(propertyNameKey(scribe, version), scribe); - } - standardPropByClass.put(scribe.getPropertyClass(), scribe); - standardPropByQName.put(scribe.getQName(), scribe); - } - - private static String propertyNameKey(ICalPropertyScribe scribe, ICalVersion version) { - return propertyNameKey(scribe.getPropertyName(version), version); - } - - private static String propertyNameKey(String propertyName, ICalVersion version) { - return version.ordinal() + propertyName.toUpperCase(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/DaylightSavingsTimeScribe.java b/app/src/main/java/biweekly/io/scribe/component/DaylightSavingsTimeScribe.java deleted file mode 100644 index 0be1f3c047..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/DaylightSavingsTimeScribe.java +++ /dev/null @@ -1,42 +0,0 @@ -package biweekly.io.scribe.component; - -import biweekly.component.DaylightSavingsTime; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class DaylightSavingsTimeScribe extends ObservanceScribe { - public DaylightSavingsTimeScribe() { - super(DaylightSavingsTime.class, "DAYLIGHT"); - } - - @Override - protected DaylightSavingsTime _newInstance() { - return new DaylightSavingsTime(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/ICalComponentScribe.java b/app/src/main/java/biweekly/io/scribe/component/ICalComponentScribe.java deleted file mode 100644 index f6d88309b4..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/ICalComponentScribe.java +++ /dev/null @@ -1,146 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.component.ICalComponent; -import biweekly.io.DataModelConversionException; -import biweekly.property.ICalProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Base class for iCalendar component scribes. - * @param the component class - * @author Michael Angstadt - */ -public abstract class ICalComponentScribe { - private static final Set allVersions = Collections.unmodifiableSet(EnumSet.allOf(ICalVersion.class)); - - protected final Class clazz; - protected final String componentName; - - /** - * Creates a new component scribe. - * @param clazz the component's class - * @param componentName the component's name (e.g. "VEVENT") - */ - public ICalComponentScribe(Class clazz, String componentName) { - this.clazz = clazz; - this.componentName = componentName; - } - - /** - * Gets the iCalendar versions that support this component. This method - * returns all iCalendar versions unless overridden by the child scribe. - * @return the iCalendar versions - */ - public Set getSupportedVersions() { - return allVersions; - } - - /** - * Gets the component class. - * @return the component class. - */ - public Class getComponentClass() { - return clazz; - } - - /** - * Gets the component's name. - * @return the compent's name (e.g. "VEVENT") - */ - public String getComponentName() { - return componentName; - } - - /** - * Creates a new instance of the component class that doesn't have any - * properties or sub-components. - * @return the new instance - */ - public T emptyInstance() { - T component = _newInstance(); - - //remove any properties/components that were created in the constructor - component.getProperties().clear(); - component.getComponents().clear(); - - return component; - } - - /** - * Creates a new instance of the component class. - * @return the new instance - */ - protected abstract T _newInstance(); - - /** - * Gets the sub-components to marshal. Child classes can override this for - * better control over which components are marshalled. - * @param component the component - * @return the sub-components to marshal - */ - public List getComponents(T component) { - return new ArrayList(component.getComponents().values()); - } - - /** - * Gets the properties to marshal. Child classes can override this for - * better control over which properties are marshalled. - * @param component the component - * @return the properties to marshal - */ - public List getProperties(T component) { - return new ArrayList(component.getProperties().values()); - } - - /** - *

- * Checks this component to see if it needs to be converted to a different - * data model before writing it out, throwing a - * {@link DataModelConversionException} if it does. - *

- *

- * Child classes should override this method if the component requires - * any such conversion. The default implementation of this method does - * nothing. - *

- * @param component the component being written - * @param parent the component's parent or null if it has no parent - * @param version the version iCalendar object being written - * @throws DataModelConversionException if the component needs to be - * converted - */ - public void checkForDataModelConversions(T component, ICalComponent parent, ICalVersion version) { - //empty - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/ICalendarScribe.java b/app/src/main/java/biweekly/io/scribe/component/ICalendarScribe.java deleted file mode 100644 index e9a946417c..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/ICalendarScribe.java +++ /dev/null @@ -1,70 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.ArrayList; -import java.util.List; - -import biweekly.ICalendar; -import biweekly.property.ICalProperty; -import biweekly.property.ProductId; -import biweekly.property.Version; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class ICalendarScribe extends ICalComponentScribe { - public ICalendarScribe() { - super(ICalendar.class, "VCALENDAR"); - } - - @Override - protected ICalendar _newInstance() { - return new ICalendar(); - } - - @Override - public List getProperties(ICalendar component) { - List properties = new ArrayList(component.getProperties().values()); - - /* - * Move VERSION properties to the front (if any are present), followed - * by PRODID properties. This is not required by the specs, but may help - * with interoperability because all the examples in the specs put the - * VERSION and PRODID at the very beginning of the iCalendar. - */ - moveToFront(ProductId.class, component, properties); - moveToFront(Version.class, component, properties); - - return properties; - } - - private void moveToFront(Class clazz, ICalendar component, List properties) { - List toMove = component.getProperties(clazz); - properties.removeAll(toMove); - properties.addAll(0, toMove); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/ObservanceScribe.java b/app/src/main/java/biweekly/io/scribe/component/ObservanceScribe.java deleted file mode 100644 index 3911cc51c0..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/ObservanceScribe.java +++ /dev/null @@ -1,46 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.component.Observance; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public abstract class ObservanceScribe extends ICalComponentScribe { - protected ObservanceScribe(Class clazz, String componentName) { - super(clazz, componentName); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/RawComponentScribe.java b/app/src/main/java/biweekly/io/scribe/component/RawComponentScribe.java deleted file mode 100644 index 266e67f2cf..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/RawComponentScribe.java +++ /dev/null @@ -1,46 +0,0 @@ -package biweekly.io.scribe.component; - -import biweekly.component.RawComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class RawComponentScribe extends ICalComponentScribe { - /** - * Creates a new raw component scribe. - * @param componentName the component's name (e.g. "X-PARTY") - */ - public RawComponentScribe(String componentName) { - super(RawComponent.class, componentName); - } - - @Override - protected RawComponent _newInstance() { - return new RawComponent(componentName); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/StandardTimeScribe.java b/app/src/main/java/biweekly/io/scribe/component/StandardTimeScribe.java deleted file mode 100644 index 5acdfb2053..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/StandardTimeScribe.java +++ /dev/null @@ -1,42 +0,0 @@ -package biweekly.io.scribe.component; - -import biweekly.component.StandardTime; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class StandardTimeScribe extends ObservanceScribe { - public StandardTimeScribe() { - super(StandardTime.class, "STANDARD"); - } - - @Override - protected StandardTime _newInstance() { - return new StandardTime(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/VAlarmScribe.java b/app/src/main/java/biweekly/io/scribe/component/VAlarmScribe.java deleted file mode 100644 index 1b5bb31bbb..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/VAlarmScribe.java +++ /dev/null @@ -1,230 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.component.ICalComponent; -import biweekly.component.VAlarm; -import biweekly.io.DataModelConversionException; -import biweekly.parameter.Related; -import biweekly.property.Action; -import biweekly.property.Attachment; -import biweekly.property.Attendee; -import biweekly.property.AudioAlarm; -import biweekly.property.DateEnd; -import biweekly.property.DateStart; -import biweekly.property.Description; -import biweekly.property.DisplayAlarm; -import biweekly.property.DurationProperty; -import biweekly.property.EmailAlarm; -import biweekly.property.ProcedureAlarm; -import biweekly.property.Repeat; -import biweekly.property.Trigger; -import biweekly.property.VCalAlarmProperty; -import biweekly.property.ValuedProperty; -import biweekly.util.Duration; -import biweekly.util.StringUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class VAlarmScribe extends ICalComponentScribe { - public VAlarmScribe() { - super(VAlarm.class, "VALARM"); - } - - @Override - protected VAlarm _newInstance() { - return new VAlarm(null, null); - } - - @Override - public void checkForDataModelConversions(VAlarm component, ICalComponent parent, ICalVersion version) { - if (version != ICalVersion.V1_0) { - return; - } - - VCalAlarmProperty vcalAlarm = convert(component, parent); - if (vcalAlarm == null) { - return; - } - - DataModelConversionException e = new DataModelConversionException(null); - e.getProperties().add(vcalAlarm); - throw e; - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } - - /** - * Converts a {@link VAlarm} component to a vCal alarm property. - * @param valarm the component - * @param parent the component's parent - * @return the vCal alarm property or null if it cannot be converted - */ - private static VCalAlarmProperty convert(VAlarm valarm, ICalComponent parent) { - VCalAlarmProperty property = create(valarm); - if (property == null) { - return null; - } - - property.setStart(determineStartDate(valarm, parent)); - - DurationProperty duration = valarm.getDuration(); - if (duration != null) { - property.setSnooze(duration.getValue()); - } - - Repeat repeat = valarm.getRepeat(); - if (repeat != null) { - property.setRepeat(repeat.getValue()); - } - - return property; - } - - /** - * Creates a new {@link VCalAlarmProperty} based on the given {@link VAlarm} - * component, setting fields that are common to all - * {@link VCalAlarmProperty} classes. - * @param valarm the source component - * @return the property or null if it cannot be created - */ - private static VCalAlarmProperty create(VAlarm valarm) { - Action action = valarm.getAction(); - if (action == null) { - return null; - } - - if (action.isAudio()) { - AudioAlarm aalarm = new AudioAlarm(); - - List attaches = valarm.getAttachments(); - if (!attaches.isEmpty()) { - Attachment attach = attaches.get(0); - - String formatType = attach.getFormatType(); - aalarm.setParameter("TYPE", formatType); - - byte[] data = attach.getData(); - if (data != null) { - aalarm.setData(data); - } - - String uri = attach.getUri(); - if (uri != null) { - String contentId = StringUtils.afterPrefixIgnoreCase(uri, "cid:"); - if (contentId == null) { - aalarm.setUri(uri); - } else { - aalarm.setContentId(contentId); - } - } - } - - return aalarm; - } - - if (action.isDisplay()) { - Description description = valarm.getDescription(); - String text = ValuedProperty.getValue(description); - return new DisplayAlarm(text); - } - - if (action.isEmail()) { - List attendees = valarm.getAttendees(); - String email = attendees.isEmpty() ? null : attendees.get(0).getEmail(); - EmailAlarm malarm = new EmailAlarm(email); - - Description description = valarm.getDescription(); - String note = ValuedProperty.getValue(description); - malarm.setNote(note); - - return malarm; - } - - if (action.isProcedure()) { - Description description = valarm.getDescription(); - String path = ValuedProperty.getValue(description); - return new ProcedureAlarm(path); - } - - return null; - } - - /** - * Determines what the alarm property's start date should be. - * @param valarm the component that is being converted to a vCal alarm - * property - * @param parent the component's parent - * @return the start date or null if it cannot be determined - */ - private static Date determineStartDate(VAlarm valarm, ICalComponent parent) { - Trigger trigger = valarm.getTrigger(); - if (trigger == null) { - return null; - } - - Date triggerStart = trigger.getDate(); - if (triggerStart != null) { - return triggerStart; - } - - Duration triggerDuration = trigger.getDuration(); - if (triggerDuration == null) { - return null; - } - - if (parent == null) { - return null; - } - - Related related = trigger.getRelated(); - Date date = null; - if (related == Related.START) { - date = ValuedProperty.getValue(parent.getProperty(DateStart.class)); - } else if (related == Related.END) { - date = ValuedProperty.getValue(parent.getProperty(DateEnd.class)); - if (date == null) { - Date dateStart = ValuedProperty.getValue(parent.getProperty(DateStart.class)); - Duration duration = ValuedProperty.getValue(parent.getProperty(DurationProperty.class)); - if (duration != null && dateStart != null) { - date = duration.add(dateStart); - } - } - } - - return (date == null) ? null : triggerDuration.add(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/VEventScribe.java b/app/src/main/java/biweekly/io/scribe/component/VEventScribe.java deleted file mode 100644 index 9c64e34a81..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/VEventScribe.java +++ /dev/null @@ -1,42 +0,0 @@ -package biweekly.io.scribe.component; - -import biweekly.component.VEvent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class VEventScribe extends ICalComponentScribe { - public VEventScribe() { - super(VEvent.class, "VEVENT"); - } - - @Override - protected VEvent _newInstance() { - return new VEvent(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/VFreeBusyScribe.java b/app/src/main/java/biweekly/io/scribe/component/VFreeBusyScribe.java deleted file mode 100644 index a974a4e894..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/VFreeBusyScribe.java +++ /dev/null @@ -1,118 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.component.VFreeBusy; -import biweekly.property.FreeBusy; -import biweekly.property.ICalProperty; -import biweekly.util.Period; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class VFreeBusyScribe extends ICalComponentScribe { - public VFreeBusyScribe() { - super(VFreeBusy.class, "VFREEBUSY"); - } - - @Override - public List getProperties(VFreeBusy component) { - List properties = super.getProperties(component); - - List fb = new ArrayList(component.getFreeBusy()); - if (fb.isEmpty()) { - return properties; - } - - //sort FREEBUSY properties by start date (p.100) - Collections.sort(fb, new Comparator() { - public int compare(FreeBusy one, FreeBusy two) { - Date oneStart = getEarliestStartDate(one); - Date twoStart = getEarliestStartDate(two); - if (oneStart == null && twoStart == null) { - return 0; - } - if (oneStart == null) { - return 1; - } - if (twoStart == null) { - return -1; - } - return oneStart.compareTo(twoStart); - } - - private Date getEarliestStartDate(FreeBusy fb) { - Date date = null; - for (Period tp : fb.getValues()) { - if (tp.getStartDate() == null) { - continue; - } - if (date == null || date.compareTo(tp.getStartDate()) > 0) { - date = tp.getStartDate(); - } - } - return date; - } - }); - - //find index of first FREEBUSY instance - int index = 0; - for (ICalProperty prop : properties) { - if (prop instanceof FreeBusy) { - break; - } - index++; - } - - //remove and re-add the FREEBUSY instances in sorted order - properties = new ArrayList(properties); - for (FreeBusy f : fb) { - properties.remove(f); - properties.add(index++, f); - } - - return properties; - } - - @Override - protected VFreeBusy _newInstance() { - return new VFreeBusy(); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/VJournalScribe.java b/app/src/main/java/biweekly/io/scribe/component/VJournalScribe.java deleted file mode 100644 index 57722bfdc3..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/VJournalScribe.java +++ /dev/null @@ -1,51 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.component.VJournal; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class VJournalScribe extends ICalComponentScribe { - public VJournalScribe() { - super(VJournal.class, "VJOURNAL"); - } - - @Override - protected VJournal _newInstance() { - return new VJournal(); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/VTimezoneScribe.java b/app/src/main/java/biweekly/io/scribe/component/VTimezoneScribe.java deleted file mode 100644 index b79c0b2f98..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/VTimezoneScribe.java +++ /dev/null @@ -1,51 +0,0 @@ -package biweekly.io.scribe.component; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.component.VTimezone; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class VTimezoneScribe extends ICalComponentScribe { - public VTimezoneScribe() { - super(VTimezone.class, "VTIMEZONE"); - } - - @Override - protected VTimezone _newInstance() { - return new VTimezone((String) null); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/VTodoScribe.java b/app/src/main/java/biweekly/io/scribe/component/VTodoScribe.java deleted file mode 100644 index ed1e6e00de..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/VTodoScribe.java +++ /dev/null @@ -1,42 +0,0 @@ -package biweekly.io.scribe.component; - -import biweekly.component.VTodo; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @author Michael Angstadt - */ -public class VTodoScribe extends ICalComponentScribe { - public VTodoScribe() { - super(VTodo.class, "VTODO"); - } - - @Override - protected VTodo _newInstance() { - return new VTodo(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/component/package-info.java b/app/src/main/java/biweekly/io/scribe/component/package-info.java deleted file mode 100644 index b15a354ee1..0000000000 --- a/app/src/main/java/biweekly/io/scribe/component/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes that marshal and unmarshal components. - */ -package biweekly.io.scribe.component; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/package-info.java b/app/src/main/java/biweekly/io/scribe/package-info.java deleted file mode 100644 index b370957b0d..0000000000 --- a/app/src/main/java/biweekly/io/scribe/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes that marshal and unmarshal components and properties in various formats. - */ -package biweekly.io.scribe; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/ActionScribe.java b/app/src/main/java/biweekly/io/scribe/property/ActionScribe.java deleted file mode 100644 index 28827c8788..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ActionScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.Action; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Action} properties. - * @author Michael Angstadt - */ -public class ActionScribe extends TextPropertyScribe { - public ActionScribe() { - super(Action.class, "ACTION"); - } - - @Override - protected Action newInstance(String value, ICalVersion version) { - return new Action(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/AttachmentScribe.java b/app/src/main/java/biweekly/io/scribe/property/AttachmentScribe.java deleted file mode 100644 index 4b9799f6ff..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/AttachmentScribe.java +++ /dev/null @@ -1,137 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.property.Attachment; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Attachment} properties. - * @author Michael Angstadt - */ -public class AttachmentScribe extends BinaryPropertyScribe { - public AttachmentScribe() { - super(Attachment.class, "ATTACH"); - } - - @Override - protected ICalDataType _dataType(Attachment property, ICalVersion version) { - if (property.getContentId() != null) { - return (version == ICalVersion.V1_0) ? ICalDataType.CONTENT_ID : ICalDataType.URI; - } - return super._dataType(property, version); - } - - @Override - protected Attachment newInstance(byte[] data) { - /* - * Note: "formatType" will be set when the parameters are assigned to - * the property object. - */ - return new Attachment(null, data); - } - - @Override - protected Attachment newInstance(String value, ICalDataType dataType) { - /* - * Note: "formatType" will be set when the parameters are assigned to - * the property object. - */ - - if (dataType == ICalDataType.CONTENT_ID) { - String contentId = getCidUriValue(value); - if (contentId == null) { - contentId = value; - } - Attachment attach = new Attachment(null, (String) null); - attach.setContentId(contentId); - return attach; - } - - String contentId = getCidUriValue(value); - if (contentId != null) { - Attachment attach = new Attachment(null, (String) null); - attach.setContentId(contentId); - return attach; - } - - return new Attachment(null, value); - } - - @Override - protected String _writeText(Attachment property, WriteContext context) { - String contentId = property.getContentId(); - if (contentId != null) { - return (context.getVersion() == ICalVersion.V1_0) ? '<' + contentId + '>' : "cid:" + contentId; - } - - return super._writeText(property, context); - } - - @Override - protected void _writeXml(Attachment property, XCalElement element, WriteContext context) { - String contentId = property.getContentId(); - if (contentId != null) { - element.append(ICalDataType.URI, "cid:" + contentId); - return; - } - - super._writeXml(property, element, context); - } - - @Override - protected JCalValue _writeJson(Attachment property, WriteContext context) { - String contentId = property.getContentId(); - if (contentId != null) { - return JCalValue.single("cid:" + contentId); - } - - return super._writeJson(property, context); - } - - /** - * Gets the value of the given "cid" URI. - * @param uri the "cid" URI - * @return the URI value or null if the given string is not a "cid" URI - */ - private static String getCidUriValue(String uri) { - int colon = uri.indexOf(':'); - if (colon == 3) { - String scheme = uri.substring(0, colon); - return "cid".equalsIgnoreCase(scheme) ? uri.substring(colon + 1) : null; - } - - if (uri.length() > 0 && uri.charAt(0) == '<' && uri.charAt(uri.length() - 1) == '>') { - return uri.substring(1, uri.length() - 1); - } - - return null; - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/AttendeeScribe.java b/app/src/main/java/biweekly/io/scribe/property/AttendeeScribe.java deleted file mode 100644 index a6b503cc45..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/AttendeeScribe.java +++ /dev/null @@ -1,340 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Iterator; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.DataModelConversionException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.parameter.ICalParameters; -import biweekly.parameter.ParticipationLevel; -import biweekly.parameter.ParticipationStatus; -import biweekly.parameter.Role; -import biweekly.property.Attendee; -import biweekly.property.Organizer; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Attendee} properties. - * @author Michael Angstadt - */ -public class AttendeeScribe extends ICalPropertyScribe { - public AttendeeScribe() { - super(Attendee.class, "ATTENDEE"); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - switch (version) { - case V1_0: - return null; - default: - return ICalDataType.CAL_ADDRESS; - } - } - - @Override - protected ICalDataType _dataType(Attendee property, ICalVersion version) { - if (version == ICalVersion.V1_0 && property.getUri() != null) { - return ICalDataType.URL; - } - return defaultDataType(version); - } - - @Override - protected ICalParameters _prepareParameters(Attendee property, WriteContext context) { - /* - * Note: Parameter values are assigned using "put()" instead of the - * appropriate "setter" methods so that any existing parameter values - * are not overwritten. - */ - - ICalParameters copy = new ICalParameters(property.getParameters()); - - //RSVP parameter - //1.0 - Uses the values "YES" and "NO" - //2.0 - Uses the values "TRUE" and "FALSE" - Boolean rsvp = property.getRsvp(); - if (rsvp != null) { - String value; - switch (context.getVersion()) { - case V1_0: - value = rsvp ? "YES" : "NO"; - break; - - default: - value = rsvp ? "TRUE" : "FALSE"; - break; - } - - copy.put(ICalParameters.RSVP, value); - } - - //ROLE and EXPECT parameters - //1.0 - Uses ROLE and EXPECT - //2.0 - Uses only ROLE - Role role = property.getRole(); - ParticipationLevel level = property.getParticipationLevel(); - switch (context.getVersion()) { - case V1_0: - if (role != null) { - copy.put(ICalParameters.ROLE, role.getValue()); - } - if (level != null) { - copy.put(ICalParameters.EXPECT, level.getValue(context.getVersion())); - } - break; - - default: - String value = null; - if (role == Role.CHAIR) { - value = role.getValue(); - } else if (level != null) { - value = level.getValue(context.getVersion()); - } else if (role != null) { - value = role.getValue(); - } - - if (value != null) { - copy.put(ICalParameters.ROLE, value); - } - break; - } - - //PARTSTAT vs STATUS - //1.0 - Calls the parameter "STATUS" - //2.0 - Calls the parameter "PARTSTAT" - ParticipationStatus partStat = property.getParticipationStatus(); - if (partStat != null) { - String paramName; - String paramValue; - - switch (context.getVersion()) { - case V1_0: - paramName = ICalParameters.STATUS; - paramValue = (partStat == ParticipationStatus.NEEDS_ACTION) ? "NEEDS ACTION" : partStat.getValue(); - break; - - default: - paramName = ICalParameters.PARTSTAT; - paramValue = partStat.getValue(); - break; - } - - copy.put(paramName, paramValue); - } - - //CN parameter - String name = property.getCommonName(); - if (name != null && context.getVersion() != ICalVersion.V1_0) { - copy.put(ICalParameters.CN, name); - } - - //EMAIL parameter - String uri = property.getUri(); - String email = property.getEmail(); - if (uri != null && email != null && context.getVersion() != ICalVersion.V1_0) { - copy.put(ICalParameters.EMAIL, email); - } - - return copy; - } - - @Override - protected Attendee _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String uri = null, name = null, email = null; - Boolean rsvp = null; - Role role = null; - ParticipationLevel participationLevel = null; - ParticipationStatus participationStatus = null; - - switch (context.getVersion()) { - case V1_0: - Iterator it = parameters.get(ICalParameters.RSVP).iterator(); - while (it.hasNext()) { - String rsvpStr = it.next(); - - if ("YES".equalsIgnoreCase(rsvpStr)) { - rsvp = Boolean.TRUE; - it.remove(); - break; - } - - if ("NO".equalsIgnoreCase(rsvpStr)) { - rsvp = Boolean.FALSE; - it.remove(); - break; - } - } - - String roleStr = parameters.first(ICalParameters.ROLE); - if (roleStr != null) { - role = Role.get(roleStr); - parameters.remove(ICalParameters.ROLE, roleStr); - } - - String expectStr = parameters.getExpect(); - if (expectStr != null) { - participationLevel = ParticipationLevel.get(expectStr); - parameters.remove(ICalParameters.EXPECT, expectStr); - } - - String statusStr = parameters.getStatus(); - if (statusStr != null) { - participationStatus = ParticipationStatus.get(statusStr); - parameters.remove(ICalParameters.STATUS, statusStr); - } - - int bracketStart = value.lastIndexOf('<'); - int bracketEnd = value.lastIndexOf('>'); - if (bracketStart >= 0 && bracketEnd >= 0 && bracketStart < bracketEnd) { - name = value.substring(0, bracketStart).trim(); - email = value.substring(bracketStart + 1, bracketEnd).trim(); - } else if (dataType == ICalDataType.URL) { - uri = value; - } else { - email = value; - } - - break; - - default: - it = parameters.get(ICalParameters.RSVP).iterator(); - while (it.hasNext()) { - String rsvpStr = it.next(); - - if ("TRUE".equalsIgnoreCase(rsvpStr)) { - rsvp = Boolean.TRUE; - it.remove(); - break; - } - - if ("FALSE".equalsIgnoreCase(rsvpStr)) { - rsvp = Boolean.FALSE; - it.remove(); - break; - } - } - - roleStr = parameters.first(ICalParameters.ROLE); - if (roleStr != null) { - if (roleStr.equalsIgnoreCase(Role.CHAIR.getValue())) { - role = Role.CHAIR; - } else { - ParticipationLevel l = ParticipationLevel.find(roleStr); - if (l == null) { - role = Role.get(roleStr); - } else { - participationLevel = l; - } - } - parameters.remove(ICalParameters.ROLE, roleStr); - } - - String participationStatusStr = parameters.getParticipationStatus(); - if (participationStatusStr != null) { - participationStatus = ParticipationStatus.get(participationStatusStr); - parameters.remove(ICalParameters.PARTSTAT, participationStatusStr); - } - - name = parameters.getCommonName(); - if (name != null) { - parameters.remove(ICalParameters.CN, name); - } - - email = parameters.getEmail(); - if (email == null) { - int colon = value.indexOf(':'); - if (colon == 6) { - String scheme = value.substring(0, colon); - if (scheme.equalsIgnoreCase("mailto")) { - email = value.substring(colon + 1); - } else { - uri = value; - } - } else { - uri = value; - } - } else { - uri = value; - parameters.remove(ICalParameters.EMAIL, email); - } - - break; - } - - Attendee attendee = new Attendee(name, email, uri); - attendee.setParticipationStatus(participationStatus); - attendee.setParticipationLevel(participationLevel); - attendee.setRole(role); - attendee.setRsvp(rsvp); - - if (context.getVersion() == ICalVersion.V1_0 && attendee.getRole() == Role.ORGANIZER) { - Organizer organizer = new Organizer(attendee.getCommonName(), attendee.getEmail()); - organizer.setUri(attendee.getUri()); - organizer.setParameters(parameters); - - attendee.setParameters(parameters); - DataModelConversionException conversionException = new DataModelConversionException(attendee); - conversionException.getProperties().add(organizer); - throw conversionException; - } - - return attendee; - } - - @Override - protected String _writeText(Attendee property, WriteContext context) { - String uri = property.getUri(); - if (uri != null) { - return uri; - } - - String name = property.getCommonName(); - String email = property.getEmail(); - switch (context.getVersion()) { - case V1_0: - if (email != null) { - String value = (name == null) ? email : name + " <" + email + ">"; - return VObjectPropertyValues.escape(value); - } - - break; - - default: - if (email != null) { - return "mailto:" + email; - } - break; - } - - return ""; - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/AudioAlarmScribe.java b/app/src/main/java/biweekly/io/scribe/property/AudioAlarmScribe.java deleted file mode 100644 index 4573dd8c08..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/AudioAlarmScribe.java +++ /dev/null @@ -1,145 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Collections; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.component.VAlarm; -import biweekly.property.Action; -import biweekly.property.Attachment; -import biweekly.property.AudioAlarm; -import biweekly.util.org.apache.commons.codec.binary.Base64; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link AudioAlarm} properties. - * @author Michael Angstadt - */ -public class AudioAlarmScribe extends VCalAlarmPropertyScribe { - public AudioAlarmScribe() { - super(AudioAlarm.class, "AALARM"); - } - - @Override - protected ICalDataType _dataType(AudioAlarm property, ICalVersion version) { - if (property.getUri() != null) { - return ICalDataType.URL; - } - if (property.getData() != null) { - return ICalDataType.BINARY; - } - if (property.getContentId() != null) { - return ICalDataType.CONTENT_ID; - } - return null; - } - - @Override - protected List writeData(AudioAlarm property) { - String uri = property.getUri(); - if (uri != null) { - return Collections.singletonList(uri); - } - - byte[] data = property.getData(); - if (data != null) { - String base64Str = Base64.encodeBase64String(data); - return Collections.singletonList(base64Str); - } - - String contentId = property.getContentId(); - if (contentId != null) { - return Collections.singletonList(contentId); - } - - return Collections.emptyList(); - } - - @Override - protected AudioAlarm create(ICalDataType dataType, SemiStructuredValueIterator it) { - AudioAlarm aalarm = new AudioAlarm(); - String next = it.next(); - if (next == null) { - return aalarm; - } - - if (dataType == ICalDataType.BINARY) { - byte[] data = Base64.decodeBase64(next); - aalarm.setData(data); - } else if (dataType == ICalDataType.URL) { - aalarm.setUri(next); - } else if (dataType == ICalDataType.CONTENT_ID) { - aalarm.setContentId(next); - } else { - aalarm.setUri(next); - } - - return aalarm; - } - - @Override - protected void toVAlarm(VAlarm valarm, AudioAlarm property) { - Attachment attach = buildAttachment(property); - if (attach != null) { - valarm.addAttachment(attach); - } - } - - private static Attachment buildAttachment(AudioAlarm aalarm) { - String type = aalarm.getType(); - String contentType = (type == null) ? null : "audio/" + type.toLowerCase(); - Attachment attach = new Attachment(contentType, (String) null); - - byte[] data = aalarm.getData(); - if (data != null) { - attach.setData(data); - return attach; - } - - String contentId = aalarm.getContentId(); - if (contentId != null) { - attach.setContentId(contentId); - return attach; - } - - String uri = aalarm.getUri(); - if (uri != null) { - attach.setUri(uri); - return attach; - } - - return null; - } - - @Override - protected Action action() { - return Action.audio(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/BinaryPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/BinaryPropertyScribe.java deleted file mode 100644 index 462b0a2295..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/BinaryPropertyScribe.java +++ /dev/null @@ -1,175 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.Encoding; -import biweekly.parameter.ICalParameters; -import biweekly.property.BinaryProperty; -import biweekly.util.org.apache.commons.codec.binary.Base64; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link BinaryProperty} properties. - * @author Michael Angstadt - */ -public abstract class BinaryPropertyScribe extends ICalPropertyScribe { - public BinaryPropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName, ICalDataType.URI); - } - - @Override - protected ICalParameters _prepareParameters(T property, WriteContext context) { - ICalParameters copy = new ICalParameters(property.getParameters()); - - if (property.getUri() != null) { - copy.setEncoding(null); - } else if (property.getData() != null) { - copy.setEncoding(Encoding.BASE64); - } - - return copy; - } - - @Override - protected ICalDataType _dataType(T property, ICalVersion version) { - if (property.getUri() != null) { - return (version == ICalVersion.V1_0) ? ICalDataType.URL : ICalDataType.URI; - } - if (property.getData() != null) { - return ICalDataType.BINARY; - } - return defaultDataType(version); - } - - @Override - protected String _writeText(T property, WriteContext context) { - String uri = property.getUri(); - if (uri != null) { - return uri; - } - - byte[] data = property.getData(); - if (data != null) { - return Base64.encodeBase64String(data); - } - - return ""; - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - - if (dataType == ICalDataType.BINARY || parameters.getEncoding() == Encoding.BASE64) { - byte[] data = Base64.decodeBase64(value); - return newInstance(data); - } - - return newInstance(value, dataType); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - String uri = property.getUri(); - if (uri != null) { - element.append(ICalDataType.URI, uri); - return; - } - - byte[] data = property.getData(); - if (data != null) { - element.append(ICalDataType.BINARY, Base64.encodeBase64String(data)); - return; - } - - element.append(defaultDataType(context.getVersion()), ""); - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - String uri = element.first(ICalDataType.URI); - if (uri != null) { - return newInstance(uri, ICalDataType.URI); - } - - String base64Data = element.first(ICalDataType.BINARY); - if (base64Data != null) { - byte[] data = Base64.decodeBase64(base64Data); - return newInstance(data); - } - - throw missingXmlElements(ICalDataType.URI, ICalDataType.BINARY); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - String uri = property.getUri(); - if (uri != null) { - return JCalValue.single(uri); - } - - byte[] data = property.getData(); - if (data != null) { - return JCalValue.single(Base64.encodeBase64String(data)); - } - - return JCalValue.single(""); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = value.asSingle(); - - if (dataType == ICalDataType.BINARY) { - byte[] data = Base64.decodeBase64(valueStr); - return newInstance(data); - } - - return newInstance(valueStr, dataType); - } - - /** - * Creates a property object from the given binary data. - * @param data the data - * @return the property object - */ - protected abstract T newInstance(byte[] data); - - /** - * Creates a property object from the given string value. - * @param value the string value - * @param dataType the data type - * @return the property object - */ - protected abstract T newInstance(String value, ICalDataType dataType); -} diff --git a/app/src/main/java/biweekly/io/scribe/property/CalendarScaleScribe.java b/app/src/main/java/biweekly/io/scribe/property/CalendarScaleScribe.java deleted file mode 100644 index b96e8dc45b..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/CalendarScaleScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.CalendarScale; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link CalendarScale} properties. - * @author Michael Angstadt - */ -public class CalendarScaleScribe extends TextPropertyScribe { - public CalendarScaleScribe() { - super(CalendarScale.class, "CALSCALE"); - } - - @Override - protected CalendarScale newInstance(String value, ICalVersion version) { - return new CalendarScale(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/CategoriesScribe.java b/app/src/main/java/biweekly/io/scribe/property/CategoriesScribe.java deleted file mode 100644 index 470f01124d..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/CategoriesScribe.java +++ /dev/null @@ -1,45 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.parameter.ICalParameters; -import biweekly.property.Categories; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Categories} properties. - * @author Michael Angstadt - */ -public class CategoriesScribe extends TextListPropertyScribe { - public CategoriesScribe() { - super(Categories.class, "CATEGORIES"); - } - - @Override - public Categories newInstance(ICalDataType dataType, ICalParameters parameters) { - return new Categories(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ClassificationScribe.java b/app/src/main/java/biweekly/io/scribe/property/ClassificationScribe.java deleted file mode 100644 index f0fb96501e..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ClassificationScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Classification; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Classification} properties. - * @author Michael Angstadt - */ -public class ClassificationScribe extends TextPropertyScribe { - public ClassificationScribe() { - super(Classification.class, "CLASS"); - } - - @Override - protected Classification newInstance(String value, ICalVersion version) { - return new Classification(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/ColorScribe.java b/app/src/main/java/biweekly/io/scribe/property/ColorScribe.java deleted file mode 100644 index 64c966779f..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ColorScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Color; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Color} properties. - * @author Michael Angstadt - */ -public class ColorScribe extends TextPropertyScribe { - public ColorScribe() { - super(Color.class, "COLOR"); - } - - @Override - protected Color newInstance(String value, ICalVersion version) { - return new Color(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/CommentScribe.java b/app/src/main/java/biweekly/io/scribe/property/CommentScribe.java deleted file mode 100644 index 72e3b0df68..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/CommentScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.Comment; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Comment} properties. - * @author Michael Angstadt - */ -public class CommentScribe extends TextPropertyScribe { - public CommentScribe() { - super(Comment.class, "COMMENT"); - } - - @Override - protected Comment newInstance(String value, ICalVersion version) { - return new Comment(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/CompletedScribe.java b/app/src/main/java/biweekly/io/scribe/property/CompletedScribe.java deleted file mode 100644 index 0505d583ca..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/CompletedScribe.java +++ /dev/null @@ -1,46 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Date; - -import biweekly.property.Completed; - - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Completed} properties. - * @author Michael Angstadt - */ -public class CompletedScribe extends DateTimePropertyScribe { - public CompletedScribe() { - super(Completed.class, "COMPLETED"); - } - - @Override - protected Completed newInstance(Date date) { - return new Completed(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ConferenceScribe.java b/app/src/main/java/biweekly/io/scribe/property/ConferenceScribe.java deleted file mode 100644 index 1debb86704..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ConferenceScribe.java +++ /dev/null @@ -1,114 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.Conference; -import biweekly.util.DataUri; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Conference} properties. - * @author Michael Angstadt - */ -public class ConferenceScribe extends ICalPropertyScribe { - public ConferenceScribe() { - super(Conference.class, "CONFERENCE", ICalDataType.URI); - } - - @Override - protected String _writeText(Conference property, WriteContext context) { - return write(property); - } - - @Override - protected Conference _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value); - } - - @Override - protected void _writeXml(Conference property, XCalElement element, WriteContext context) { - element.append(ICalDataType.URI, write(property)); - } - - @Override - protected Conference _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - String uri = element.first(ICalDataType.URI); - if (uri != null) { - return parse(uri); - } - - throw missingXmlElements(ICalDataType.URI); - } - - @Override - protected JCalValue _writeJson(Conference property, WriteContext context) { - return JCalValue.single(write(property)); - } - - @Override - protected Conference _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String uri = value.asSingle(); - return parse(uri); - } - - private static String write(Conference property) { - String uri = property.getUri(); - if (uri != null) { - return uri; - } - - String text = property.getText(); - if (text != null) { - return new DataUri(text).toString(); - } - - return ""; - } - - private static Conference parse(String value) { - try { - DataUri uri = DataUri.parse(value); - String text = uri.getText(); - if (text != null) { - Conference property = new Conference((String) null); - property.setText(text); - return property; - } - } catch (IllegalArgumentException e) { - //not a data URI - } - - return new Conference(value); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ContactScribe.java b/app/src/main/java/biweekly/io/scribe/property/ContactScribe.java deleted file mode 100644 index e3f15f493b..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ContactScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.Contact; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Contact} properties. - * @author Michael Angstadt - */ -public class ContactScribe extends TextPropertyScribe { - public ContactScribe() { - super(Contact.class, "CONTACT"); - } - - @Override - protected Contact newInstance(String value, ICalVersion version) { - return new Contact(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/CreatedScribe.java b/app/src/main/java/biweekly/io/scribe/property/CreatedScribe.java deleted file mode 100644 index 2a9bdbea9f..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/CreatedScribe.java +++ /dev/null @@ -1,51 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Date; - -import biweekly.ICalVersion; -import biweekly.property.Created; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Created} properties. - * @author Michael Angstadt - */ -public class CreatedScribe extends DateTimePropertyScribe { - public CreatedScribe() { - super(Created.class, "CREATED"); - } - - @Override - public String getPropertyName(ICalVersion version) { - return (version == ICalVersion.V1_0) ? "DCREATED" : super.getPropertyName(version); - } - - @Override - protected Created newInstance(Date date) { - return new Created(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DateDueScribe.java b/app/src/main/java/biweekly/io/scribe/property/DateDueScribe.java deleted file mode 100644 index dd07259773..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DateDueScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.property.DateDue; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link DateDue} properties. - * @author Michael Angstadt - */ -public class DateDueScribe extends DateOrDateTimePropertyScribe { - public DateDueScribe() { - super(DateDue.class, "DUE"); - } - - @Override - protected DateDue newInstance(ICalDate date) { - return new DateDue(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DateEndScribe.java b/app/src/main/java/biweekly/io/scribe/property/DateEndScribe.java deleted file mode 100644 index 9c450a3fa1..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DateEndScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.property.DateEnd; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link DateEnd} properties. - * @author Michael Angstadt - */ -public class DateEndScribe extends DateOrDateTimePropertyScribe { - public DateEndScribe() { - super(DateEnd.class, "DTEND"); - } - - @Override - protected DateEnd newInstance(ICalDate date) { - return new DateEnd(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DateOrDateTimePropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/DateOrDateTimePropertyScribe.java deleted file mode 100644 index 78fe9cffc3..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DateOrDateTimePropertyScribe.java +++ /dev/null @@ -1,137 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.DateOrDateTimeProperty; -import biweekly.util.ICalDate; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that have either "date" or "date-time" values. - * @param the property class - * @author Michael Angstadt - */ -public abstract class DateOrDateTimePropertyScribe extends ICalPropertyScribe { - public DateOrDateTimePropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName, ICalDataType.DATE_TIME); - } - - @Override - protected ICalParameters _prepareParameters(T property, WriteContext context) { - ICalDate value = property.getValue(); - if (value == null) { - return property.getParameters(); - } - - return handleTzidParameter(property, value.hasTime(), context); - } - - @Override - protected ICalDataType _dataType(T property, ICalVersion version) { - ICalDate value = property.getValue(); - if (value == null) { - return ICalDataType.DATE_TIME; - } - - return value.hasTime() ? ICalDataType.DATE_TIME : ICalDataType.DATE; - } - - @Override - protected String _writeText(T property, WriteContext context) { - ICalDate value = property.getValue(); - return date(value, property, context).extended(false).write(); - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value, parameters, context); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - ICalDataType dataType = dataType(property, null); - ICalDate value = property.getValue(); - - String dateStr = date(value, property, context).extended(true).write(); - element.append(dataType, dateStr); - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - String value = element.first(ICalDataType.DATE_TIME); - if (value == null) { - value = element.first(ICalDataType.DATE); - } - - if (value != null) { - return parse(value, parameters, context); - } - - throw missingXmlElements(ICalDataType.DATE_TIME, ICalDataType.DATE); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - ICalDate value = property.getValue(); - String dateStr = date(value, property, context).extended(true).write(); - return JCalValue.single(dateStr); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = value.asSingle(); - return parse(valueStr, parameters, context); - } - - protected abstract T newInstance(ICalDate date); - - private T parse(String value, ICalParameters parameters, ParseContext context) { - if (value == null) { - return newInstance(null); - } - - ICalDate date; - try { - date = date(value).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(17); - } - - T property = newInstance(date); - context.addDate(date, property, parameters); - return property; - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DateStartScribe.java b/app/src/main/java/biweekly/io/scribe/property/DateStartScribe.java deleted file mode 100644 index 1235dcbdc7..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DateStartScribe.java +++ /dev/null @@ -1,90 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.DateStart; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link DateStart} properties. - * @author Michael Angstadt - */ -public class DateStartScribe extends DateOrDateTimePropertyScribe { - public DateStartScribe() { - super(DateStart.class, "DTSTART"); - } - - @Override - protected ICalParameters _prepareParameters(DateStart property, WriteContext context) { - if (isInObservance(context)) { - return property.getParameters(); - } - return super._prepareParameters(property, context); - } - - @Override - protected String _writeText(DateStart property, WriteContext context) { - if (isInObservance(context)) { - return write(property, false); - } - return super._writeText(property, context); - } - - @Override - protected void _writeXml(DateStart property, XCalElement element, WriteContext context) { - if (isInObservance(context)) { - String dateStr = write(property, true); - ICalDataType dataType = dataType(property, null); - element.append(dataType, dateStr); - return; - } - - super._writeXml(property, element, context); - } - - @Override - protected JCalValue _writeJson(DateStart property, WriteContext context) { - if (isInObservance(context)) { - return JCalValue.single(write(property, true)); - } - return super._writeJson(property, context); - } - - private String write(DateStart property, boolean extended) { - ICalDate value = property.getValue(); - return date(value).observance(true).extended(extended).write(); - } - - @Override - protected DateStart newInstance(ICalDate date) { - return new DateStart(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DateTimePropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/DateTimePropertyScribe.java deleted file mode 100644 index d309d11e68..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DateTimePropertyScribe.java +++ /dev/null @@ -1,112 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Date; - -import biweekly.ICalDataType; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.DateTimeProperty; -import biweekly.util.ICalDate; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that have "date-time" values. These values will always be - * formatted in the UTC timezone. - * @param the property class - * @author Michael Angstadt - */ -public abstract class DateTimePropertyScribe extends ICalPropertyScribe { - public DateTimePropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName, ICalDataType.DATE_TIME); - } - - @Override - protected String _writeText(T property, WriteContext context) { - Date value = property.getValue(); - return date(value).utc(true).extended(false).write(); - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value, parameters, context); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - ICalDataType dataType = dataType(property, null); - Date value = property.getValue(); - String dateStr = date(value).utc(true).extended(true).write(); - - element.append(dataType, dateStr); - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return parse(value, parameters, context); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - Date value = property.getValue(); - String dateStr = date(value).utc(true).extended(true).write(); - return JCalValue.single(dateStr); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = value.asSingle(); - return parse(valueStr, parameters, context); - } - - private T parse(String value, ICalParameters parameters, ParseContext context) { - ICalDate date; - try { - date = date(value).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(17); - } - - T property = newInstance(date); - context.addDate(date, property, parameters); - return property; - } - - protected abstract T newInstance(Date date); -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DateTimeStampScribe.java b/app/src/main/java/biweekly/io/scribe/property/DateTimeStampScribe.java deleted file mode 100644 index d07b1ba4f4..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DateTimeStampScribe.java +++ /dev/null @@ -1,63 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Date; -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.io.SkipMeException; -import biweekly.io.WriteContext; -import biweekly.property.DateTimeStamp; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link DateTimeStamp} properties. - * @author Michael Angstadt - */ -public class DateTimeStampScribe extends DateTimePropertyScribe { - public DateTimeStampScribe() { - super(DateTimeStamp.class, "DTSTAMP"); - } - - @Override - protected DateTimeStamp newInstance(Date date) { - return new DateTimeStamp(date); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } - - @Override - protected String _writeText(DateTimeStamp property, WriteContext context) { - if (context.getVersion() == ICalVersion.V1_0){ - throw new SkipMeException("This property is not used in vCal 1.0."); - } - return super._writeText(property, context); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DaylightScribe.java b/app/src/main/java/biweekly/io/scribe/property/DaylightScribe.java deleted file mode 100644 index 9c3762f28e..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DaylightScribe.java +++ /dev/null @@ -1,129 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.parameter.ICalParameters; -import biweekly.property.Daylight; -import biweekly.util.ICalDate; -import biweekly.util.UtcOffset; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Daylight} properties. - * @author Michael Angstadt - */ -public class DaylightScribe extends ICalPropertyScribe { - public DaylightScribe() { - super(Daylight.class, "DAYLIGHT"); - } - - @Override - protected String _writeText(Daylight property, WriteContext context) { - if (!property.isDaylight()) { - return "FALSE"; - } - - List values = new ArrayList(); - values.add("TRUE"); - - UtcOffset offset = property.getOffset(); - values.add((offset == null) ? "" : offset.toString()); - - ICalDate start = property.getStart(); - values.add((start == null || start.getRawComponents() == null) ? "" : start.getRawComponents().toString(true, false)); - - ICalDate end = property.getEnd(); - values.add((end == null || end.getRawComponents() == null) ? "" : end.getRawComponents().toString(true, false)); - - String standardName = property.getStandardName(); - values.add((standardName == null) ? "" : standardName); - - String daylightName = property.getDaylightName(); - values.add((daylightName == null) ? "" : daylightName); - - return VObjectPropertyValues.writeSemiStructured(values, false, true); - } - - @Override - protected Daylight _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - SemiStructuredValueIterator it = new SemiStructuredValueIterator(value); - - String next = it.next(); - boolean flag = (next == null) ? false : Boolean.parseBoolean(next); - - UtcOffset offset = null; - next = it.next(); - if (next != null) { - try { - offset = UtcOffset.parse(next); - } catch (IllegalArgumentException e) { - throw new CannotParseException(33, next); - } - } - - ICalDate start = null; - next = it.next(); - if (next != null) { - try { - start = date(next).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(34, next); - } - } - - ICalDate end = null; - next = it.next(); - if (next != null) { - try { - end = date(next).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(35, next); - } - } - - String standardName = it.next(); - String daylightName = it.next(); - - return new Daylight(flag, offset, start, end, standardName, daylightName); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V1_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DescriptionScribe.java b/app/src/main/java/biweekly/io/scribe/property/DescriptionScribe.java deleted file mode 100644 index 1f05f5ca6c..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DescriptionScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Description; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Description} properties. - * @author Michael Angstadt - */ -public class DescriptionScribe extends TextPropertyScribe { - public DescriptionScribe() { - super(Description.class, "DESCRIPTION"); - } - - @Override - protected Description newInstance(String value, ICalVersion version) { - return new Description(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/DisplayAlarmScribe.java b/app/src/main/java/biweekly/io/scribe/property/DisplayAlarmScribe.java deleted file mode 100644 index add2a7fe45..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DisplayAlarmScribe.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Collections; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.component.VAlarm; -import biweekly.property.Action; -import biweekly.property.DisplayAlarm; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link DisplayAlarm} properties. - * @author Michael Angstadt - */ -public class DisplayAlarmScribe extends VCalAlarmPropertyScribe { - public DisplayAlarmScribe() { - super(DisplayAlarm.class, "DALARM", ICalDataType.TEXT); - } - - @Override - protected List writeData(DisplayAlarm property) { - String text = property.getText(); - return (text == null) ? Collections.emptyList() : Collections.singletonList(text); - } - - @Override - protected DisplayAlarm create(ICalDataType dataType, SemiStructuredValueIterator it) { - return new DisplayAlarm(it.next()); - } - - @Override - protected void toVAlarm(VAlarm valarm, DisplayAlarm property) { - valarm.setDescription(property.getText()); - } - - @Override - protected Action action() { - return Action.display(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/DurationPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/DurationPropertyScribe.java deleted file mode 100644 index f4cdf4958e..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/DurationPropertyScribe.java +++ /dev/null @@ -1,116 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.DurationProperty; -import biweekly.util.Duration; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link DurationProperty} properties. - * @author Michael Angstadt - */ -public class DurationPropertyScribe extends ICalPropertyScribe { - public DurationPropertyScribe() { - super(DurationProperty.class, "DURATION", ICalDataType.DURATION); - } - - @Override - protected String _writeText(DurationProperty property, WriteContext context) { - Duration duration = property.getValue(); - if (duration != null) { - return duration.toString(); - } - - return ""; - } - - @Override - protected DurationProperty _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value); - } - - @Override - protected void _writeXml(DurationProperty property, XCalElement element, WriteContext context) { - String durationStr = null; - - Duration duration = property.getValue(); - if (duration != null) { - durationStr = duration.toString(); - } - - element.append(dataType(property, null), durationStr); - } - - @Override - protected DurationProperty _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return parse(value); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(DurationProperty property, WriteContext context) { - Duration value = property.getValue(); - if (value != null) { - return JCalValue.single(value.toString()); - } - - return JCalValue.single(""); - } - - @Override - protected DurationProperty _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = value.asSingle(); - return parse(valueStr); - } - - private DurationProperty parse(String value) { - if (value == null) { - return new DurationProperty((Duration) null); - } - - try { - Duration duration = Duration.parse(value); - return new DurationProperty(duration); - } catch (IllegalArgumentException e) { - throw new CannotParseException(18); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/EmailAlarmScribe.java b/app/src/main/java/biweekly/io/scribe/property/EmailAlarmScribe.java deleted file mode 100644 index c7c614043c..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/EmailAlarmScribe.java +++ /dev/null @@ -1,92 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.component.VAlarm; -import biweekly.property.Action; -import biweekly.property.Attendee; -import biweekly.property.EmailAlarm; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link EmailAlarm} properties. - * @author Michael Angstadt - */ -public class EmailAlarmScribe extends VCalAlarmPropertyScribe { - public EmailAlarmScribe() { - super(EmailAlarm.class, "MALARM"); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - return ICalDataType.TEXT; - } - - @Override - protected List writeData(EmailAlarm property) { - String email = property.getEmail(); - String note = property.getNote(); - if (email == null && note == null) { - return Collections.emptyList(); - } - - List dataValues = new ArrayList(2); - dataValues.add((email == null) ? "" : email); - dataValues.add((note == null) ? "" : note); - return dataValues; - } - - @Override - protected EmailAlarm create(ICalDataType dataType, SemiStructuredValueIterator it) { - String email = it.next(); - String note = it.next(); - - EmailAlarm property = new EmailAlarm(email); - property.setNote(note); - return property; - } - - @Override - protected void toVAlarm(VAlarm valarm, EmailAlarm property) { - String email = property.getEmail(); - if (email != null) { - valarm.addAttendee(new Attendee(null, email)); - } - valarm.setDescription(property.getNote()); - } - - @Override - protected Action action() { - return Action.email(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ExceptionDatesScribe.java b/app/src/main/java/biweekly/io/scribe/property/ExceptionDatesScribe.java deleted file mode 100644 index b3acdae457..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ExceptionDatesScribe.java +++ /dev/null @@ -1,191 +0,0 @@ -package biweekly.io.scribe.property; - -import static biweekly.ICalDataType.DATE; -import static biweekly.ICalDataType.DATE_TIME; - -import java.util.ArrayList; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.ExceptionDates; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link ExceptionDates} properties. - * @author Michael Angstadt - */ -public class ExceptionDatesScribe extends ListPropertyScribe { - public ExceptionDatesScribe() { - super(ExceptionDates.class, "EXDATE"); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - return DATE_TIME; - } - - @Override - protected ICalParameters _prepareParameters(ExceptionDates property, WriteContext context) { - if (isInObservance(context)) { - return property.getParameters(); - } - - boolean hasTime; - if (property.getValues().isEmpty()) { - hasTime = false; - } else { - hasTime = (dataType(property, context.getVersion()) == DATE_TIME); - } - return handleTzidParameter(property, hasTime, context); - } - - @Override - protected ICalDataType _dataType(ExceptionDates property, ICalVersion version) { - List dates = property.getValues(); - if (!dates.isEmpty()) { - return dates.get(0).hasTime() ? DATE_TIME : DATE; - } - - return defaultDataType(version); - } - - @Override - protected ExceptionDates newInstance(ICalDataType dataType, ICalParameters parameters) { - return new ExceptionDates(); - } - - @Override - protected String writeValue(ExceptionDates property, ICalDate value, WriteContext context) { - if (isInObservance(context)) { - return date(value).observance(true).extended(false).write(); - } - - return date(value, property, context).extended(false).write(); - } - - @Override - protected ICalDate readValue(ExceptionDates property, String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - ICalDate date; - try { - boolean hasTime = (dataType == DATE_TIME); - date = date(value).hasTime(hasTime).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(19); - } - context.addDate(date, property, parameters); - - return date; - } - - @Override - protected void _writeXml(ExceptionDates property, XCalElement element, WriteContext context) { - List values = property.getValues(); - if (values.isEmpty()) { - element.append(defaultDataType(context.getVersion()), ""); - return; - } - - if (isInObservance(context)) { - for (ICalDate value : values) { - String valueStr = date(value).observance(true).extended(true).write(); - element.append(DATE_TIME, valueStr); - } - return; - } - - for (ICalDate value : values) { - ICalDataType dataType = value.hasTime() ? DATE_TIME : DATE; - String dateStr = date(value, property, context).extended(true).write(); - element.append(dataType, dateStr); - } - } - - @Override - protected ExceptionDates _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - List dateTimeElements = element.all(DATE_TIME); - List dateElements = element.all(DATE); - if (dateTimeElements.isEmpty() && dateElements.isEmpty()) { - throw missingXmlElements(DATE_TIME, DATE); - } - - ExceptionDates property = new ExceptionDates(); - List values = property.getValues(); - for (String value : dateTimeElements) { - ICalDate datetime = readValue(property, value, DATE_TIME, parameters, context); - values.add(datetime); - } - for (String value : dateElements) { - ICalDate date = readValue(property, value, DATE, parameters, context); - values.add(date); - } - return property; - } - - @Override - protected JCalValue _writeJson(ExceptionDates property, WriteContext context) { - List values = property.getValues(); - if (values.isEmpty()) { - return JCalValue.single(""); - } - - List valuesStr = new ArrayList(); - if (isInObservance(context)) { - for (ICalDate value : values) { - String valueStr = date(value).observance(true).extended(true).write(); - valuesStr.add(valueStr); - } - return JCalValue.multi(valuesStr); - } - - for (ICalDate value : values) { - String dateStr = date(value, property, context).extended(true).write(); - valuesStr.add(dateStr); - } - return JCalValue.multi(valuesStr); - } - - @Override - protected ExceptionDates _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - List valueStrs = value.asMulti(); - - ExceptionDates property = new ExceptionDates(); - List values = property.getValues(); - for (String valueStr : valueStrs) { - ICalDate date = readValue(property, valueStr, dataType, parameters, context); - values.add(date); - } - return property; - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ExceptionRuleScribe.java b/app/src/main/java/biweekly/io/scribe/property/ExceptionRuleScribe.java deleted file mode 100644 index b816679a49..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ExceptionRuleScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.property.ExceptionRule; -import biweekly.util.Recurrence; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link ExceptionRule} properties. - * @author Michael Angstadt - */ -public class ExceptionRuleScribe extends RecurrencePropertyScribe { - public ExceptionRuleScribe() { - super(ExceptionRule.class, "EXRULE"); - } - - @Override - protected ExceptionRule newInstance(Recurrence recur) { - return new ExceptionRule(recur); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/FreeBusyScribe.java b/app/src/main/java/biweekly/io/scribe/property/FreeBusyScribe.java deleted file mode 100644 index 4977e4e8ea..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/FreeBusyScribe.java +++ /dev/null @@ -1,253 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.ArrayList; -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.FreeBusy; -import biweekly.util.Duration; -import biweekly.util.ICalDate; -import biweekly.util.Period; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link FreeBusy} properties. - * @author Michael Angstadt - */ -public class FreeBusyScribe extends ICalPropertyScribe { - public FreeBusyScribe() { - super(FreeBusy.class, "FREEBUSY"); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - return ICalDataType.PERIOD; - } - - @Override - protected String _writeText(final FreeBusy property, final WriteContext context) { - List values = property.getValues(); - List strValues = new ArrayList(values.size()); - for (Period period : values) { - StringBuilder sb = new StringBuilder(); - - Date start = period.getStartDate(); - if (start != null) { - String dateStr = date(start, property, context).extended(false).write(); - sb.append(dateStr); - } - - sb.append('/'); - - Date end = period.getEndDate(); - if (end != null) { - String dateStr = date(end, property, context).extended(false).write(); - sb.append(dateStr); - } else if (period.getDuration() != null) { - sb.append(period.getDuration()); - } - - strValues.add(sb.toString()); - } - - return VObjectPropertyValues.writeList(strValues); - } - - @Override - protected FreeBusy _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(VObjectPropertyValues.parseList(value), parameters, context); - } - - @Override - protected void _writeXml(FreeBusy property, XCalElement element, WriteContext context) { - for (Period period : property.getValues()) { - XCalElement periodElement = element.append(ICalDataType.PERIOD); - - Date start = period.getStartDate(); - if (start != null) { - String dateStr = date(start, property, context).extended(true).write(); - periodElement.append("start", dateStr); - } - - Date end = period.getEndDate(); - if (end != null) { - String dateStr = date(end, property, context).extended(true).write(); - periodElement.append("end", dateStr); - } - - Duration duration = period.getDuration(); - if (duration != null) { - periodElement.append("duration", duration.toString()); - } - } - } - - @Override - protected FreeBusy _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - List periodElements = element.children(ICalDataType.PERIOD); - if (periodElements.isEmpty()) { - throw missingXmlElements(ICalDataType.PERIOD); - } - - FreeBusy property = new FreeBusy(); - for (XCalElement periodElement : periodElements) { - String startStr = periodElement.first("start"); - if (startStr == null) { - throw new CannotParseException(9); - } - - ICalDate start; - try { - start = date(startStr).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(10, startStr); - } - - String endStr = periodElement.first("end"); - if (endStr != null) { - try { - ICalDate end = date(endStr).parse(); - property.getValues().add(new Period(start, end)); - context.addDate(start, property, parameters); - context.addDate(end, property, parameters); - } catch (IllegalArgumentException e) { - throw new CannotParseException(11, endStr); - } - continue; - } - - String durationStr = periodElement.first("duration"); - if (durationStr != null) { - try { - Duration duration = Duration.parse(durationStr); - property.getValues().add(new Period(start, duration)); - context.addDate(start, property, parameters); - } catch (IllegalArgumentException e) { - throw new CannotParseException(12, durationStr); - } - continue; - } - - throw new CannotParseException(13); - } - - return property; - } - - @Override - protected JCalValue _writeJson(FreeBusy property, WriteContext context) { - List values = property.getValues(); - if (values.isEmpty()) { - return JCalValue.single(""); - } - - List valuesStr = new ArrayList(); - for (Period period : values) { - StringBuilder sb = new StringBuilder(); - Date start = period.getStartDate(); - if (start != null) { - String dateStr = date(start, property, context).extended(true).write(); - sb.append(dateStr); - } - - sb.append('/'); - - Date end = period.getEndDate(); - if (end != null) { - String dateStr = date(end, property, context).extended(true).write(); - sb.append(dateStr); - } else if (period.getDuration() != null) { - sb.append(period.getDuration()); - } - - valuesStr.add(sb.toString()); - } - - return JCalValue.multi(valuesStr); - } - - @Override - protected FreeBusy _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(value.asMulti(), parameters, context); - } - - private FreeBusy parse(List periods, ICalParameters parameters, ParseContext context) { - FreeBusy property = new FreeBusy(); - - for (String period : periods) { - int slash = period.indexOf('/'); - if (slash < 0) { - throw new CannotParseException(13); - } - - String startStr = period.substring(0, slash); - ICalDate start; - try { - start = date(startStr).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(10, startStr); - } - - String endStr = period.substring(slash + 1); - ICalDate end; - try { - end = date(endStr).parse(); - property.getValues().add(new Period(start, end)); - context.addDate(start, property, parameters); - context.addDate(end, property, parameters); - } catch (IllegalArgumentException e) { - //must be a duration - try { - Duration duration = Duration.parse(endStr); - property.getValues().add(new Period(start, duration)); - context.addDate(start, property, parameters); - } catch (IllegalArgumentException e2) { - throw new CannotParseException(14, endStr); - } - } - } - - return property; - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/GeoScribe.java b/app/src/main/java/biweekly/io/scribe/property/GeoScribe.java deleted file mode 100644 index ed16ed0904..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/GeoScribe.java +++ /dev/null @@ -1,170 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.Geo; -import biweekly.util.ICalFloatFormatter; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.StructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Geo} properties. - * @author Michael Angstadt - */ -public class GeoScribe extends ICalPropertyScribe { - public GeoScribe() { - super(Geo.class, "GEO"); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - return ICalDataType.FLOAT; - } - - @Override - protected String _writeText(Geo property, WriteContext context) { - ICalFloatFormatter formatter = new ICalFloatFormatter(); - - Double latitude = property.getLatitude(); - if (latitude == null) { - latitude = 0.0; - } - String latitudeStr = formatter.format(latitude); - - Double longitude = property.getLongitude(); - if (longitude == null) { - longitude = 0.0; - } - String longitudeStr = formatter.format(longitude); - - char delimiter = getDelimiter(context.getVersion()); - return latitudeStr + delimiter + longitudeStr; - } - - @Override - protected Geo _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - char delimiter = getDelimiter(context.getVersion()); - int pos = value.indexOf(delimiter); - if (pos < 0) { - throw new CannotParseException(20); - } - - String latitudeStr = value.substring(0, pos); - String longitudeStr = value.substring(pos + 1); - return parse(latitudeStr, longitudeStr); - } - - @Override - protected void _writeXml(Geo property, XCalElement element, WriteContext context) { - ICalFloatFormatter formatter = new ICalFloatFormatter(); - - Double latitude = property.getLatitude(); - if (latitude == null) { - latitude = 0.0; - } - element.append("latitude", formatter.format(latitude)); - - Double longitude = property.getLongitude(); - if (longitude == null) { - longitude = 0.0; - } - element.append("longitude", formatter.format(longitude)); - } - - @Override - protected Geo _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - String latitudeStr = element.first("latitude"); - String longitudeStr = element.first("longitude"); - if (latitudeStr == null && longitudeStr == null) { - throw missingXmlElements("latitude", "longitude"); - } - if (latitudeStr == null) { - throw missingXmlElements("latitude"); - } - if (longitudeStr == null) { - throw missingXmlElements("longitude"); - } - - return parse(latitudeStr, longitudeStr); - } - - @Override - protected JCalValue _writeJson(Geo property, WriteContext context) { - Double latitude = property.getLatitude(); - if (latitude == null) { - latitude = 0.0; - } - - Double longitude = property.getLongitude(); - if (longitude == null) { - longitude = 0.0; - } - - return JCalValue.structured(latitude, longitude); - } - - @Override - protected Geo _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - StructuredValueIterator it = new StructuredValueIterator(value.asStructured()); - String latitudeStr = it.nextValue(); - String longitudeStr = it.nextValue(); - return parse(latitudeStr, longitudeStr); - } - - private char getDelimiter(ICalVersion version) { - return (version == ICalVersion.V1_0) ? ',' : ';'; - } - - private Geo parse(String latitudeStr, String longitudeStr) { - Double latitude = null; - if (latitudeStr != null) { - try { - latitude = Double.valueOf(latitudeStr); - } catch (NumberFormatException e) { - throw new CannotParseException(21, latitudeStr); - } - } - - Double longitude = null; - if (longitudeStr != null) { - try { - longitude = Double.valueOf(longitudeStr); - } catch (NumberFormatException e) { - throw new CannotParseException(22, longitudeStr); - } - } - - return new Geo(latitude, longitude); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ICalPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/ICalPropertyScribe.java deleted file mode 100644 index f07c570acd..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ICalPropertyScribe.java +++ /dev/null @@ -1,884 +0,0 @@ -package biweekly.io.scribe.property; - -import static biweekly.io.xml.XCalNamespaceContext.XCAL_NS; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; -import java.util.TimeZone; - -import javax.xml.namespace.QName; - -import org.w3c.dom.Element; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.ValidationWarning; -import biweekly.component.Observance; -import biweekly.component.VTimezone; -import biweekly.io.CannotParseException; -import biweekly.io.DataModelConversionException; -import biweekly.io.ParseContext; -import biweekly.io.SkipMeException; -import biweekly.io.TimezoneAssignment; -import biweekly.io.TimezoneInfo; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.json.JsonValue; -import biweekly.io.xml.XCalElement; -import biweekly.io.xml.XCalElement.XCalValue; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.property.ValuedProperty; -import biweekly.util.DateTimeComponents; -import biweekly.util.ICalDate; -import biweekly.util.ICalDateFormat; -import biweekly.util.ListMultimap; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Base class for iCalendar property scribes. - * @param the property class - * @author Michael Angstadt - */ -public abstract class ICalPropertyScribe { - private static final Set allVersions = Collections.unmodifiableSet(EnumSet.allOf(ICalVersion.class)); - - protected final Class clazz; - protected final String propertyName; - private final ICalDataType defaultDataType; - protected final QName qname; - - /** - * Creates a new scribe. - * @param clazz the property class - * @param propertyName the property name (e.g. "VERSION") - */ - public ICalPropertyScribe(Class clazz, String propertyName) { - this(clazz, propertyName, null); - } - - /** - * Creates a new scribe. - * @param clazz the property class - * @param propertyName the property name (e.g. "VERSION") - * @param defaultDataType the property's default data type (e.g. "text") or - * null if unknown - */ - public ICalPropertyScribe(Class clazz, String propertyName, ICalDataType defaultDataType) { - this(clazz, propertyName, defaultDataType, new QName(XCAL_NS, propertyName.toLowerCase())); - } - - /** - * Creates a new scribe. - * @param clazz the property class - * @param propertyName the property name (e.g. "VERSION") - * @param defaultDataType the property's default data type (e.g. "text") or - * null if unknown - * @param qname the XML element name and namespace to use for xCal documents - * (by default, the XML element name is set to the lower-cased property - * name, and the element namespace is set to the xCal namespace) - */ - public ICalPropertyScribe(Class clazz, String propertyName, ICalDataType defaultDataType, QName qname) { - this.clazz = clazz; - this.propertyName = propertyName; - this.defaultDataType = defaultDataType; - this.qname = qname; - } - - /** - * Gets the iCalendar versions that support this property. This method - * returns all iCalendar versions unless overridden by the child scribe. - * @return the iCalendar versions - */ - public Set getSupportedVersions() { - return allVersions; - } - - /** - * Gets the property class. - * @return the property class - */ - public Class getPropertyClass() { - return clazz; - } - - /** - * Gets the property name. Child classes should override this method if the - * property's name differs between versions. - * @param version the iCalendar version (a few properties have different - * names under different versions) - * @return the property name (e.g. "DTSTART") - */ - public String getPropertyName(ICalVersion version) { - return propertyName; - } - - /** - * Gets this property's local name and namespace for xCal documents. - * @return the XML local name and namespace - */ - public QName getQName() { - return qname; - } - - /** - * Sanitizes a property's parameters before the property is written. - * @param property the property to write - * @param context the context - * @return the sanitized parameters - */ - public final ICalParameters prepareParameters(T property, WriteContext context) { - return _prepareParameters(property, context); - } - - /** - * Determines the default data type of this property. - * @param version the version of the iCalendar object being generated - * @return the data type or null if unknown - */ - public final ICalDataType defaultDataType(ICalVersion version) { - return _defaultDataType(version); - } - - /** - * Determines the data type of a property instance. - * @param property the property - * @param version the version of the iCalendar object being generated - * @return the data type or null if unknown - */ - public final ICalDataType dataType(T property, ICalVersion version) { - return _dataType(property, version); - } - - /** - * Marshals a property's value to a string. - * @param property the property - * @param context the context - * @return the marshalled property value - * @throws SkipMeException if the property should not be written to the data - * stream - * @throws DataModelConversionException if the property needs to be - * converted to something different in order to adhere to the data model of - * the iCalendar version being written (only applicable when writing 1.0 - * vCals) - */ - public final String writeText(T property, WriteContext context) { - return _writeText(property, context); - } - - /** - * Marshals a property's value to an XML element (xCal). - * @param property the property - * @param element the property's XML element - * @param context the context - * @throws SkipMeException if the property should not be written to the data - * stream - */ - public final void writeXml(T property, Element element, WriteContext context) { - XCalElement xcalElement = new XCalElement(element); - _writeXml(property, xcalElement, context); - } - - /** - * Marshals a property's value to a JSON data stream (jCal). - * @param property the property - * @param context the context - * @return the marshalled value - * @throws SkipMeException if the property should not be written to the data - * stream - */ - public final JCalValue writeJson(T property, WriteContext context) { - return _writeJson(property, context); - } - - /** - * Unmarshals a property from a plain-text iCalendar data stream. - * @param value the value as read off the wire - * @param dataType the data type of the property value. The property's VALUE - * parameter is used to determine the data type. If the property has no - * VALUE parameter, then this parameter will be set to the property's - * default datatype. Note that the VALUE parameter is removed from the - * property's parameter list after it has been read. - * @param parameters the parsed parameters - * @param context the parse context - * @return the unmarshalled property - * @throws CannotParseException if the scribe could not parse the property's - * value - * @throws SkipMeException if the property should not be added to the final - * {@link ICalendar} object - * @throws DataModelConversionException if the property should be converted - * to something different in order to adhere to the 2.0 data model (only - * thrown when parsing 1.0 vCals) - */ - public final T parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - T property = _parseText(value, dataType, parameters, context); - property.setParameters(parameters); - return property; - } - - /** - * Unmarshals a property's value from an XML document (xCal). - * @param element the property's XML element - * @param parameters the property's parameters - * @param context the context - * @return the unmarshalled property - * @throws CannotParseException if the scribe could not parse the property's - * value - * @throws SkipMeException if the property should not be added to the final - * {@link ICalendar} object - */ - public final T parseXml(Element element, ICalParameters parameters, ParseContext context) { - T property = _parseXml(new XCalElement(element), parameters, context); - property.setParameters(parameters); - return property; - } - - /** - * Unmarshals a property's value from a JSON data stream (jCal). - * @param value the property's JSON value - * @param dataType the data type - * @param parameters the parsed parameters - * @param context the context - * @return the unmarshalled property - * @throws CannotParseException if the scribe could not parse the property's - * value - * @throws SkipMeException if the property should not be added to the final - * {@link ICalendar} object - */ - public final T parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - T property = _parseJson(value, dataType, parameters, context); - property.setParameters(parameters); - return property; - } - - /** - *

- * Sanitizes a property's parameters before the property is written. - *

- *

- * This method should be overridden by child classes that wish to tweak the - * property's parameters before the property is written. The default - * implementation of this method returns the property's parameters - * unmodified. - *

- * @param property the property to write - * @param context the context - * @return the sanitized parameters (this should be a *copy* of the - * property's parameters if modifications were made) - */ - protected ICalParameters _prepareParameters(T property, WriteContext context) { - return property.getParameters(); - } - - /** - *

- * Determines the default data type of this property. - *

- *

- * This method should be overridden by child classes if a property's default - * data type changes depending the iCalendar version. The default - * implementation of this method returns the data type that was passed into - * the {@link #ICalPropertyScribe(Class, String, ICalDataType)} constructor. - * Null is returned if this constructor was not invoked. - *

- * @param version the version of the iCalendar object being generated - * @return the data type or null if unknown - */ - protected ICalDataType _defaultDataType(ICalVersion version) { - return defaultDataType; - } - - /** - *

- * Determines the data type of a property instance. - *

- *

- * This method should be overridden by child classes if a property's data - * type changes depending on its value. The default implementation of this - * method returns the property's default data type. - *

- * @param property the property - * @param version the version of the iCalendar object being generated - * @return the data type or null if unknown - */ - protected ICalDataType _dataType(T property, ICalVersion version) { - return defaultDataType(version); - } - - /** - * Marshals a property's value to a string. - * @param property the property - * @param context the write context - * @return the marshalled value - * @throws SkipMeException if the property should not be written to the data - * stream - * @throws DataModelConversionException if the property needs to be - * converted to something different in order to adhere to the data model of - * the iCalendar version being written (only applicable when writing 1.0 - * vCals) - */ - protected abstract String _writeText(T property, WriteContext context); - - /** - *

- * Marshals a property's value to an XML element (xCal). - *

- *

- * This method should be overridden by child classes that wish to support - * xCal. The default implementation of this method will append one child - * element to the property's XML element. The child element's name will be - * that of the property's data type (retrieved using the {@link #dataType} - * method), and the child element's text content will be set to the - * property's marshalled plain-text value (retrieved using the - * {@link #writeText} method). - *

- * @param property the property - * @param element the property's XML element - * @param context the context - * @throws SkipMeException if the property should not be written to the data - * stream - */ - protected void _writeXml(T property, XCalElement element, WriteContext context) { - String value = writeText(property, context); - ICalDataType dataType = dataType(property, ICalVersion.V2_0); - element.append(dataType, value); - } - - /** - *

- * Marshals a property's value to a JSON data stream (jCal). - *

- *

- * This method should be overridden by child classes that wish to support - * jCal. The default implementation of this method will create a jCard - * property that has a single JSON string value (generated by the - * {@link #writeText} method). - *

- * @param property the property - * @param context the context - * @return the marshalled value - * @throws SkipMeException if the property should not be written to the data - * stream - */ - protected JCalValue _writeJson(T property, WriteContext context) { - String value = writeText(property, context); - return JCalValue.single(value); - } - - /** - * Unmarshals a property from a plain-text iCalendar data stream. - * @param value the value as read off the wire - * @param dataType the data type of the property value. The property's VALUE - * parameter is used to determine the data type. If the property has no - * VALUE parameter, then this parameter will be set to the property's - * default datatype. Note that the VALUE parameter is removed from the - * property's parameter list after it has been read. - * @param parameters the parsed parameters. These parameters will be - * assigned to the property object once this method returns. Therefore, do - * not assign any parameters to the property object itself whilst inside of - * this method, or else they will be overwritten. - * @param context the parse context - * @return the unmarshalled property object - * @throws CannotParseException if the scribe could not parse the property's - * value - * @throws SkipMeException if the property should not be added to the final - * {@link ICalendar} object - * @throws DataModelConversionException if the property should be converted - * to something different in order to adhere to the 2.0 data model (only - * thrown when parsing 1.0 vCals) - */ - protected abstract T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context); - - /** - *

- * Unmarshals a property from an XML document (xCal). - *

- *

- * This method should be overridden by child classes that wish to support - * xCal. The default implementation of this method will find the first child - * element with the xCal namespace. The element's name will be used as the - * property's data type and its text content will be passed into the - * {@link #_parseText} method. If no such child element is found, then the - * parent element's text content will be passed into {@link #_parseText} and - * the data type will be null. - *

- * @param element the property's XML element - * @param parameters the parsed parameters. These parameters will be - * assigned to the property object once this method returns. Therefore, do - * not assign any parameters to the property object itself whilst inside of - * this method, or else they will be overwritten. - * @param context the context - * @return the unmarshalled property object - * @throws CannotParseException if the scribe could not parse the property's - * value - * @throws SkipMeException if the property should not be added to the final - * {@link ICalendar} object - */ - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - XCalValue firstValue = element.firstValue(); - ICalDataType dataType = firstValue.getDataType(); - String value = VObjectPropertyValues.escape(firstValue.getValue()); - return _parseText(value, dataType, parameters, context); - } - - /** - *

- * Unmarshals a property from a JSON data stream (jCal). - *

- *

- * This method should be overridden by child classes that wish to support - * jCal. The default implementation of this method will convert the jCal - * property value to a string and pass it into the {@link #_parseText} - * method. - *

- * - *
- * - *

- * The following paragraphs describe the way in which this method's default - * implementation converts a jCal value to a string: - *

- *

- * If the jCal value consists of a single, non-array, non-object value, then - * the value is converted to a string. Special characters (backslashes, - * commas, and semicolons) are escaped in order to simulate what the value - * might look like in a plain-text iCalendar object.
- * ["x-foo", {}, "text", "the;value"] --> "the\;value"
- * ["x-foo", {}, "text", 2] --> "2" - *

- *

- * If the jCal value consists of multiple, non-array, non-object values, - * then all the values are appended together in a single string, separated - * by commas. Special characters (backslashes, commas, and semicolons) are - * escaped for each value in order to prevent commas from being treated as - * delimiters, and to simulate what the value might look like in a - * plain-text iCalendar object.
- * ["x-foo", {}, "text", "one", "two,three"] --> - * "one,two\,three" - *

- *

- * If the jCal value is a single array, then this array is treated as a - * "structured value", and converted its plain-text representation. Special - * characters (backslashes, commas, and semicolons) are escaped for each - * value in order to prevent commas and semicolons from being treated as - * delimiters.
- * ["x-foo", {}, "text", ["one", ["two", "three"], "four;five"]] - * --> "one;two,three;four\;five" - *

- *

- * If the jCal value starts with a JSON object, then the object is converted - * to a format identical to the one used in the RRULE and EXRULE properties. - * Special characters (backslashes, commas, semicolons, and equal signs) are - * escaped for each value in order to preserve the syntax of the string - * value.
- * ["x-foo", {}, "text", {"one": 1, "two": [2, 2.5]}] --> "ONE=1;TWO=2,2.5" - *

- *

- * For all other cases, behavior is undefined. - *

- * @param value the property's JSON value - * @param dataType the data type - * @param parameters the parsed parameters. These parameters will be - * assigned to the property object once this method returns. Therefore, do - * not assign any parameters to the property object itself whilst inside of - * this method, or else they will be overwritten. - * @param context the context - * @return the unmarshalled property object - * @throws CannotParseException if the scribe could not parse the property's - * value - * @throws SkipMeException if the property should not be added to the final - * {@link ICalendar} object - */ - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = jcalValueToString(value); - return _parseText(valueStr, dataType, parameters, context); - } - - /** - * Converts a jCal value to its plain-text format representation. - * @param value the jCal value - * @return the plain-text format representation (for example, "1,2,3" for a - * list of values) - */ - private static String jcalValueToString(JCalValue value) { - List values = value.getValues(); - if (values.size() > 1) { - List multi = value.asMulti(); - if (!multi.isEmpty()) { - return VObjectPropertyValues.writeList(multi); - } - } - - if (!values.isEmpty() && values.get(0).getArray() != null) { - List> structured = value.asStructured(); - if (!structured.isEmpty()) { - return VObjectPropertyValues.writeStructured(structured, true); - } - } - - if (values.get(0).getObject() != null) { - ListMultimap object = value.asObject(); - if (!object.isEmpty()) { - return VObjectPropertyValues.writeMultimap(object.getMap()); - } - } - - return VObjectPropertyValues.escape(value.asSingle()); - } - - /** - * Determines if the property is within an observance component. - * @param context the write context - * @return true if the property is within an observance, false if not - */ - protected static boolean isInObservance(WriteContext context) { - return context.getParent() instanceof Observance; - } - - /** - * Parses a date string. - * @param value the date string - * @return the factory object - */ - protected static DateParser date(String value) { - return new DateParser(value); - } - - /** - * Factory class for parsing dates. - */ - protected static class DateParser { - private String value; - private Boolean hasTime; - - /** - * Creates a new date writer object. - * @param value the date string to parse - */ - public DateParser(String value) { - this.value = value; - } - - /** - * Forces the value to be parsed as a date-time or date value. - * @param hasTime true to parsed as a date-time value, false to parse as - * a date value, null to parse as whatever value it is (defaults to - * null) - * @return this - */ - public DateParser hasTime(Boolean hasTime) { - this.hasTime = hasTime; - return this; - } - - /** - * Parses the date string. - * @return the parsed date - * @throws IllegalArgumentException if the date string is invalid - */ - public ICalDate parse() { - DateTimeComponents components = DateTimeComponents.parse(value, hasTime); - Date date = components.toDate(); - boolean hasTime = components.hasTime(); - - return new ICalDate(date, components, hasTime); - } - } - - /** - * Formats a date as a string. - * @param date the date - * @return the factory object - */ - protected static DateWriter date(Date date) { - return date((date == null) ? null : new ICalDate(date)); - } - - /** - * Formats a date as a string. - * @param date the date - * @return the factory object - */ - protected static DateWriter date(ICalDate date) { - return new DateWriter(date); - } - - protected static DateWriter date(Date date, ICalProperty property, WriteContext context) { - return date((date == null) ? null : new ICalDate(date), property, context); - } - - protected static DateWriter date(ICalDate date, ICalProperty property, WriteContext context) { - boolean floating; - TimeZone tz; - TimezoneAssignment globalTz = context.getGlobalTimezone(); - if (globalTz == null) { - TimezoneInfo tzinfo = context.getTimezoneInfo(); - floating = tzinfo.isFloating(property); - TimezoneAssignment assignment = tzinfo.getTimezoneToWriteIn(property); - tz = (assignment == null) ? null : assignment.getTimeZone(); - } else { - floating = false; - tz = globalTz.getTimeZone(); - } - - context.addDate(date, floating, tz); - return date(date).tz(floating, tz); - } - - /** - * Factory class for writing dates. - */ - protected static class DateWriter { - private ICalDate date; - private TimeZone timezone; - private boolean observance = false; - private boolean extended = false; - private boolean utc = false; - - /** - * Creates a new date writer object. - * @param date the date to format - */ - public DateWriter(ICalDate date) { - this.date = date; - } - - /** - * Sets whether the property is within an observance or not. - * @param observance true if it's in an observance, false if not - * (defaults to false) - * @return this - */ - public DateWriter observance(boolean observance) { - this.observance = observance; - return this; - } - - /** - * Sets whether to write the value in UTC or not. - * @param utc true to write in UTC, false not to - * @return this - */ - public DateWriter utc(boolean utc) { - this.utc = utc; - return this; - } - - /** - * Sets the timezone. - * @param floating true to use floating time, false not to - * @param timezone the timezone - * @return this - */ - public DateWriter tz(boolean floating, TimeZone timezone) { - if (floating) { - timezone = TimeZone.getDefault(); - } - this.timezone = timezone; - return this; - } - - /** - * Sets whether to use extended format or basic. - * @param extended true to use extended format, false to use basic - * (defaults to "false") - * @return this - */ - public DateWriter extended(boolean extended) { - this.extended = extended; - return this; - } - - /** - * Creates the date string. - * @return the date string - */ - public String write() { - if (date == null) { - return ""; - } - - if (observance) { - DateTimeComponents components = date.getRawComponents(); - if (components == null) { - ICalDateFormat format = extended ? ICalDateFormat.DATE_TIME_EXTENDED_WITHOUT_TZ : ICalDateFormat.DATE_TIME_BASIC_WITHOUT_TZ; - return format.format(date); - } - - return components.toString(true, extended); - } - - if (utc) { - ICalDateFormat format = extended ? ICalDateFormat.UTC_TIME_EXTENDED : ICalDateFormat.UTC_TIME_BASIC; - return format.format(date); - } - - ICalDateFormat format; - TimeZone timezone = this.timezone; - if (date.hasTime()) { - if (timezone == null) { - format = extended ? ICalDateFormat.UTC_TIME_EXTENDED : ICalDateFormat.UTC_TIME_BASIC; - } else { - format = extended ? ICalDateFormat.DATE_TIME_EXTENDED_WITHOUT_TZ : ICalDateFormat.DATE_TIME_BASIC_WITHOUT_TZ; - } - } else { - format = extended ? ICalDateFormat.DATE_EXTENDED : ICalDateFormat.DATE_BASIC; - timezone = null; - } - - return format.format(date, timezone); - } - } - - /** - * Adds a TZID parameter to a property's parameter list if necessary. - * @param property the property - * @param hasTime true if the property value has a time component, false if - * not - * @param context the write context - * @return the property's new set of parameters - */ - protected static ICalParameters handleTzidParameter(ICalProperty property, boolean hasTime, WriteContext context) { - ICalParameters parameters = property.getParameters(); - - //date values don't have timezones - if (!hasTime) { - return parameters; - } - - //vCal doesn't use the TZID parameter - if (context.getVersion() == ICalVersion.V1_0) { - return parameters; - } - - //floating values don't have timezones - TimezoneInfo tzinfo = context.getTimezoneInfo(); - boolean floating = tzinfo.isFloating(property); - if (floating) { - return parameters; - } - - TimezoneAssignment tz; - TimezoneAssignment globalTz = context.getGlobalTimezone(); - if (globalTz == null) { - tz = tzinfo.getTimezoneToWriteIn(property); - if (tz == null) { - //write in UTC - return parameters; - } - } else { - tz = globalTz; - } - - String tzid = null; - VTimezone component = tz.getComponent(); - String globalId = tz.getGlobalId(); - if (component != null) { - tzid = ValuedProperty.getValue(component.getTimezoneId()); - } else if (globalId != null) { - tzid = '/' + globalId; - } - - if (tzid == null) { - //should never happen - tzid = tz.getTimeZone().getID(); - } - - parameters = new ICalParameters(parameters); - parameters.setTimezoneId(tzid); - return parameters; - } - - /** - * Creates a {@link CannotParseException}, indicating that the XML elements - * that the parser expected to find are missing from the property's XML - * element. - * @param dataTypes the expected data types (null for "unknown") - * @return the exception - */ - protected static CannotParseException missingXmlElements(ICalDataType... dataTypes) { - String[] elements = new String[dataTypes.length]; - for (int i = 0; i < dataTypes.length; i++) { - ICalDataType dataType = dataTypes[i]; - elements[i] = (dataType == null) ? "unknown" : dataType.getName().toLowerCase(); - } - return missingXmlElements(elements); - } - - /** - * Creates a {@link CannotParseException}, indicating that the XML elements - * that the parser expected to find are missing from property's XML element. - * @param elements the names of the expected XML elements - * @return the exception - */ - protected static CannotParseException missingXmlElements(String... elements) { - return new CannotParseException(23, Arrays.toString(elements)); - } - - /** - * Represents the result of an unmarshal operation. - * @author Michael Angstadt - * @param the unmarshalled property class - */ - public static class Result { - private final T property; - private final List warnings; - - /** - * Creates a new result. - * @param property the property object - * @param warnings the warnings - */ - public Result(T property, List warnings) { - this.property = property; - this.warnings = warnings; - } - - /** - * Gets the warnings. - * @return the warnings - */ - public List getWarnings() { - return warnings; - } - - /** - * Gets the property object. - * @return the property object - */ - public T getProperty() { - return property; - } - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ImageScribe.java b/app/src/main/java/biweekly/io/scribe/property/ImageScribe.java deleted file mode 100644 index 66bb158e62..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ImageScribe.java +++ /dev/null @@ -1,57 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.property.Image; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Image} properties. - * @author Michael Angstadt - */ -public class ImageScribe extends BinaryPropertyScribe { - public ImageScribe() { - super(Image.class, "IMAGE"); - } - - @Override - protected Image newInstance(byte[] data) { - /* - * Note: "formatType" will be set when the parameters are assigned to - * the property object. - */ - return new Image(null, data); - } - - @Override - protected Image newInstance(String value, ICalDataType dataType) { - /* - * Note: "formatType" will be set when the parameters are assigned to - * the property object. - */ - return new Image(null, value); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/IntegerPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/IntegerPropertyScribe.java deleted file mode 100644 index 591db1da6a..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/IntegerPropertyScribe.java +++ /dev/null @@ -1,112 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.IntegerProperty; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that have integer values. - * @param the property class - * @author Michael Angstadt - */ -public abstract class IntegerPropertyScribe extends ICalPropertyScribe { - public IntegerPropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName, ICalDataType.INTEGER); - } - - @Override - protected String _writeText(T property, WriteContext context) { - Integer value = property.getValue(); - if (value != null) { - return value.toString(); - } - - return ""; - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - String valueStr = null; - - Integer value = property.getValue(); - if (value != null) { - valueStr = value.toString(); - } - - element.append(dataType(property, null), valueStr); - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return parse(value); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - return JCalValue.single(property.getValue()); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(value.asSingle()); - } - - private T parse(String value) { - if (value == null || value.isEmpty()) { - return newInstance(null); - } - - try { - Integer intValue = Integer.valueOf(value); - return newInstance(intValue); - } catch (NumberFormatException e) { - throw new CannotParseException(24); - } - } - - protected abstract T newInstance(Integer value); -} diff --git a/app/src/main/java/biweekly/io/scribe/property/LastModifiedScribe.java b/app/src/main/java/biweekly/io/scribe/property/LastModifiedScribe.java deleted file mode 100644 index 9ea5751c38..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/LastModifiedScribe.java +++ /dev/null @@ -1,46 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Date; - -import biweekly.property.LastModified; - - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link LastModified} properties. - * @author Michael Angstadt - */ -public class LastModifiedScribe extends DateTimePropertyScribe { - public LastModifiedScribe() { - super(LastModified.class, "LAST-MODIFIED"); - } - - @Override - protected LastModified newInstance(Date date) { - return new LastModified(date); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ListPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/ListPropertyScribe.java deleted file mode 100644 index b454a94bef..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ListPropertyScribe.java +++ /dev/null @@ -1,139 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.ArrayList; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.ListProperty; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that contain a list of values. - * @param the property class - * @param the value class - * @author Michael Angstadt - */ -public abstract class ListPropertyScribe, V> extends ICalPropertyScribe { - public ListPropertyScribe(Class clazz, String propertyName) { - this(clazz, propertyName, ICalDataType.TEXT); - } - - public ListPropertyScribe(Class clazz, String propertyName, ICalDataType dataType) { - super(clazz, propertyName, dataType); - } - - @Override - protected String _writeText(final T property, WriteContext context) { - List values = property.getValues(); - List valuesStr = new ArrayList(values.size()); - for (V value : values) { - String valueStr = writeValue(property, value, context); - valuesStr.add(valueStr); - } - - switch (context.getVersion()) { - case V1_0: - return VObjectPropertyValues.writeSemiStructured(valuesStr, false, true); - default: - return VObjectPropertyValues.writeList(valuesStr); - } - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - List values; - switch (context.getVersion()) { - case V1_0: - values = VObjectPropertyValues.parseSemiStructured(value); - break; - default: - values = VObjectPropertyValues.parseList(value); - break; - } - - return parse(values, dataType, parameters, context); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - for (V value : property.getValues()) { - String valueStr = writeValue(property, value, null); - element.append(dataType(property, null), valueStr); - } - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - List values = element.all(dataType); - if (!values.isEmpty()) { - return parse(values, dataType, parameters, context); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - List values = property.getValues(); - if (!values.isEmpty()) { - return JCalValue.multi(property.getValues()); - } - - return JCalValue.single(""); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(value.asMulti(), dataType, parameters, context); - } - - private T parse(List valueStrs, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - T property = newInstance(dataType, parameters); - - List values = property.getValues(); - for (String valueStr : valueStrs) { - V value = readValue(property, valueStr, dataType, parameters, context); - values.add(value); - } - - return property; - } - - protected abstract T newInstance(ICalDataType dataType, ICalParameters parameters); - - protected abstract String writeValue(T property, V value, WriteContext context); - - protected abstract V readValue(T property, String value, ICalDataType dataType, ICalParameters parameters, ParseContext context); -} diff --git a/app/src/main/java/biweekly/io/scribe/property/LocationScribe.java b/app/src/main/java/biweekly/io/scribe/property/LocationScribe.java deleted file mode 100644 index 834cb0104e..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/LocationScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Location; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Location} properties. - * @author Michael Angstadt - */ -public class LocationScribe extends TextPropertyScribe { - public LocationScribe() { - super(Location.class, "LOCATION"); - } - - @Override - protected Location newInstance(String value, ICalVersion version) { - return new Location(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/MethodScribe.java b/app/src/main/java/biweekly/io/scribe/property/MethodScribe.java deleted file mode 100644 index e640df5293..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/MethodScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.Method; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Method} properties. - * @author Michael Angstadt - */ -public class MethodScribe extends TextPropertyScribe { - public MethodScribe() { - super(Method.class, "METHOD"); - } - - @Override - protected Method newInstance(String value, ICalVersion version) { - return new Method(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/NameScribe.java b/app/src/main/java/biweekly/io/scribe/property/NameScribe.java deleted file mode 100644 index 02b0cc2c26..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/NameScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Name; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Name} properties. - * @author Michael Angstadt - */ -public class NameScribe extends TextPropertyScribe { - public NameScribe() { - super(Name.class, "NAME"); - } - - @Override - protected Name newInstance(String value, ICalVersion version) { - return new Name(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/OrganizerScribe.java b/app/src/main/java/biweekly/io/scribe/property/OrganizerScribe.java deleted file mode 100644 index 155009d972..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/OrganizerScribe.java +++ /dev/null @@ -1,118 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.DataModelConversionException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.parameter.ICalParameters; -import biweekly.parameter.Role; -import biweekly.property.Attendee; -import biweekly.property.Organizer; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Organizer} properties. - * @author Michael Angstadt - */ -public class OrganizerScribe extends ICalPropertyScribe { - public OrganizerScribe() { - super(Organizer.class, "ORGANIZER", ICalDataType.CAL_ADDRESS); - } - - @Override - protected ICalParameters _prepareParameters(Organizer property, WriteContext context) { - //CN parameter - String name = property.getCommonName(); - if (name != null) { - ICalParameters copy = new ICalParameters(property.getParameters()); - copy.put(ICalParameters.CN, name); - return copy; - } - - return super._prepareParameters(property, context); - } - - @Override - protected Organizer _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String name = parameters.getCommonName(); - if (name != null) { - parameters.remove(ICalParameters.CN, name); - } - - String uri = null, email = null; - int colon = value.indexOf(':'); - if (colon == 6) { - String scheme = value.substring(0, colon); - if (scheme.equalsIgnoreCase("mailto")) { - email = value.substring(colon + 1); - } else { - uri = value; - } - } else { - uri = value; - } - - Organizer organizer = new Organizer(name, email); - organizer.setUri(uri); - return organizer; - } - - @Override - protected String _writeText(Organizer property, WriteContext context) { - if (context.getVersion() == ICalVersion.V1_0) { - Attendee attendee = new Attendee(property.getCommonName(), property.getEmail()); - attendee.setRole(Role.ORGANIZER); - attendee.setUri(property.getUri()); - attendee.setParameters(property.getParameters()); - - DataModelConversionException conversionException = new DataModelConversionException(property); - conversionException.getProperties().add(attendee); - throw conversionException; - } - - String uri = property.getUri(); - if (uri != null) { - return uri; - } - - String email = property.getEmail(); - if (email != null) { - return "mailto:" + email; - } - - return ""; - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/PercentCompleteScribe.java b/app/src/main/java/biweekly/io/scribe/property/PercentCompleteScribe.java deleted file mode 100644 index 6461bb2a0b..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/PercentCompleteScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.PercentComplete; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link PercentComplete} properties. - * @author Michael Angstadt - */ -public class PercentCompleteScribe extends IntegerPropertyScribe { - public PercentCompleteScribe() { - super(PercentComplete.class, "PERCENT-COMPLETE"); - } - - @Override - protected PercentComplete newInstance(Integer value) { - return new PercentComplete(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/PriorityScribe.java b/app/src/main/java/biweekly/io/scribe/property/PriorityScribe.java deleted file mode 100644 index a5705b2769..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/PriorityScribe.java +++ /dev/null @@ -1,43 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.property.Priority; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Priority} properties. - * @author Michael Angstadt - */ -public class PriorityScribe extends IntegerPropertyScribe { - public PriorityScribe() { - super(Priority.class, "PRIORITY"); - } - - @Override - protected Priority newInstance(Integer value) { - return new Priority(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/ProcedureAlarmScribe.java b/app/src/main/java/biweekly/io/scribe/property/ProcedureAlarmScribe.java deleted file mode 100644 index 59085f3992..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ProcedureAlarmScribe.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Collections; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.component.VAlarm; -import biweekly.property.Action; -import biweekly.property.ProcedureAlarm; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link ProcedureAlarm} properties. - * @author Michael Angstadt - */ -public class ProcedureAlarmScribe extends VCalAlarmPropertyScribe { - public ProcedureAlarmScribe() { - super(ProcedureAlarm.class, "PALARM", ICalDataType.TEXT); - } - - @Override - protected List writeData(ProcedureAlarm property) { - String path = property.getPath(); - return (path == null) ? Collections.emptyList() : Collections.singletonList(path); - } - - @Override - protected ProcedureAlarm create(ICalDataType dataType, SemiStructuredValueIterator it) { - return new ProcedureAlarm(it.next()); - } - - @Override - protected void toVAlarm(VAlarm valarm, ProcedureAlarm property) { - valarm.setDescription(property.getPath()); - } - - @Override - protected Action action() { - return Action.procedure(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/ProductIdScribe.java b/app/src/main/java/biweekly/io/scribe/property/ProductIdScribe.java deleted file mode 100644 index d4703a6d89..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ProductIdScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.ProductId; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link ProductId} properties. - * @author Michael Angstadt - */ -public class ProductIdScribe extends TextPropertyScribe { - public ProductIdScribe() { - super(ProductId.class, "PRODID"); - } - - @Override - protected ProductId newInstance(String value, ICalVersion version) { - return new ProductId(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/RawPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/RawPropertyScribe.java deleted file mode 100644 index f7482dc2cb..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RawPropertyScribe.java +++ /dev/null @@ -1,117 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.json.JsonValue; -import biweekly.io.xml.XCalElement; -import biweekly.io.xml.XCalElement.XCalValue; -import biweekly.parameter.ICalParameters; -import biweekly.property.RawProperty; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RawProperty} properties. - * @author Michael Angstadt - */ -/* - * Note concerning escaping and unescaping special characters: - * - * Values are not escaped and unescaped for the following reason: If the - * experimental property's value is a list or structured list, then the escaping - * must be preserved or else escaped special characters will be lost. - * - * This is an inconvenience, considering the fact that most experimental - * properties contain simple text values. But it is necessary in order to - * prevent data loss. - */ -public class RawPropertyScribe extends ICalPropertyScribe { - public RawPropertyScribe(String propertyName) { - super(RawProperty.class, propertyName, null); - } - - @Override - protected ICalDataType _dataType(RawProperty property, ICalVersion version) { - return property.getDataType(); - } - - @Override - protected String _writeText(RawProperty property, WriteContext context) { - String value = property.getValue(); - return (value == null) ? "" : value; - } - - @Override - protected RawProperty _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return new RawProperty(propertyName, dataType, value); - } - - @Override - protected RawProperty _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - XCalValue firstValue = element.firstValue(); - ICalDataType dataType = firstValue.getDataType(); - String value = firstValue.getValue(); - - return new RawProperty(propertyName, dataType, value); - } - - @Override - protected RawProperty _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = jcardValueToString(value); - - return new RawProperty(propertyName, dataType, valueStr); - } - - private static String jcardValueToString(JCalValue value) { - /* - * ICalPropertyScribe.jcardValueToString() cannot be used because it - * escapes single values. - */ - List values = value.getValues(); - if (values.size() > 1) { - List multi = value.asMulti(); - if (!multi.isEmpty()) { - return VObjectPropertyValues.writeList(multi); - } - } - - if (!values.isEmpty() && values.get(0).getArray() != null) { - List> structured = value.asStructured(); - if (!structured.isEmpty()) { - return VObjectPropertyValues.writeStructured(structured, true); - } - } - - return value.asSingle(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/RecurrenceDatesScribe.java b/app/src/main/java/biweekly/io/scribe/property/RecurrenceDatesScribe.java deleted file mode 100644 index 8d63a36a2e..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RecurrenceDatesScribe.java +++ /dev/null @@ -1,377 +0,0 @@ -package biweekly.io.scribe.property; - -import static biweekly.ICalDataType.DATE; -import static biweekly.ICalDataType.DATE_TIME; -import static biweekly.ICalDataType.PERIOD; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.RecurrenceDates; -import biweekly.util.Duration; -import biweekly.util.ICalDate; -import biweekly.util.Period; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RecurrenceDates} properties. - * @author Michael Angstadt - */ -public class RecurrenceDatesScribe extends ICalPropertyScribe { - public RecurrenceDatesScribe() { - super(RecurrenceDates.class, "RDATE", DATE_TIME); - } - - @Override - protected ICalParameters _prepareParameters(RecurrenceDates property, WriteContext context) { - if (isInObservance(context)) { - return property.getParameters(); - } - - List periods = property.getPeriods(); - List dates = property.getDates(); - boolean hasTime; - if (periods.isEmpty() && dates.isEmpty()) { - hasTime = false; - } else { - ICalDataType dataType = dataType(property, context.getVersion()); - hasTime = (dataType == DATE_TIME || dataType == PERIOD); - } - return handleTzidParameter(property, hasTime, context); - } - - @Override - protected ICalDataType _dataType(RecurrenceDates property, ICalVersion version) { - List dates = property.getDates(); - if (!dates.isEmpty()) { - return dates.get(0).hasTime() ? DATE_TIME : DATE; - } - - if (!property.getPeriods().isEmpty()) { - return PERIOD; - } - - return defaultDataType(version); - } - - @Override - protected String _writeText(final RecurrenceDates property, final WriteContext context) { - List dates = property.getDates(); - if (!dates.isEmpty()) { - boolean inObservance = isInObservance(context); - List values = new ArrayList(dates.size()); - for (ICalDate date : dates) { - String value; - if (inObservance) { - value = date(date).observance(true).extended(false).write(); - } else { - value = date(date, property, context).extended(false).write(); - } - values.add(value); - } - return VObjectPropertyValues.writeList(values); - } - - //TODO vCal does not support periods - List periods = property.getPeriods(); - if (!periods.isEmpty()) { - List values = new ArrayList(periods.size()); - for (Period period : periods) { - StringBuilder sb = new StringBuilder(); - - Date start = period.getStartDate(); - if (start != null) { - String date = date(start, property, context).extended(false).write(); - sb.append(date); - } - - sb.append('/'); - - Date end = period.getEndDate(); - Duration duration = period.getDuration(); - if (end != null) { - String date = date(end, property, context).extended(false).write(); - sb.append(date); - } else if (duration != null) { - sb.append(duration); - } - - values.add(sb.toString()); - } - return VObjectPropertyValues.writeList(values); - } - - return ""; - } - - @Override - protected RecurrenceDates _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(VObjectPropertyValues.parseList(value), dataType, parameters, context); - } - - @Override - protected void _writeXml(RecurrenceDates property, XCalElement element, WriteContext context) { - ICalDataType dataType = dataType(property, context.getVersion()); - List dates = property.getDates(); - if (!dates.isEmpty()) { - boolean inObservance = isInObservance(context); - for (ICalDate date : dates) { - String dateStr; - if (inObservance) { - dateStr = date(date).observance(true).extended(true).write(); - } else { - dateStr = date(date, property, context).extended(true).write(); - } - - element.append(dataType, dateStr); - } - return; - } - - List periods = property.getPeriods(); - if (!periods.isEmpty()) { - for (Period period : periods) { - XCalElement periodElement = element.append(dataType); - - Date start = period.getStartDate(); - if (start != null) { - String dateStr = date(start, property, context).extended(true).write(); - periodElement.append("start", dateStr); - } - - Date end = period.getEndDate(); - if (end != null) { - String dateStr = date(end, property, context).extended(true).write(); - periodElement.append("end", dateStr); - } - - Duration duration = period.getDuration(); - if (duration != null) { - periodElement.append("duration", duration.toString()); - } - } - return; - } - - element.append(defaultDataType(context.getVersion()), ""); - } - - @Override - protected RecurrenceDates _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - List periodElements = element.children(PERIOD); - List dateTimeElements = element.all(DATE_TIME); - List dateElements = element.all(DATE); - if (periodElements.isEmpty() && dateTimeElements.isEmpty() && dateElements.isEmpty()) { - throw missingXmlElements(PERIOD, DATE_TIME, DATE); - } - - RecurrenceDates property = new RecurrenceDates(); - - //parse periods - for (XCalElement periodElement : periodElements) { - String startStr = periodElement.first("start"); - if (startStr == null) { - throw new CannotParseException(9); - } - - ICalDate start; - try { - start = date(startStr).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(10, startStr); - } - - String endStr = periodElement.first("end"); - if (endStr != null) { - try { - ICalDate end = date(endStr).parse(); - property.getPeriods().add(new Period(start, end)); - context.addDate(start, property, parameters); - context.addDate(end, property, parameters); - } catch (IllegalArgumentException e) { - throw new CannotParseException(11, endStr); - } - continue; - } - - String durationStr = periodElement.first("duration"); - if (durationStr != null) { - try { - Duration duration = Duration.parse(durationStr); - property.getPeriods().add(new Period(start, duration)); - context.addDate(start, property, parameters); - } catch (IllegalArgumentException e) { - throw new CannotParseException(12, durationStr); - } - continue; - } - - throw new CannotParseException(13); - } - - //parse date-times - for (String dateTimeStr : dateTimeElements) { - try { - ICalDate date = date(dateTimeStr).hasTime(true).parse(); - property.getDates().add(date); - context.addDate(date, property, parameters); - } catch (IllegalArgumentException e) { - throw new CannotParseException(15, dateTimeStr); - } - } - - //parse dates - for (String dateStr : dateElements) { - try { - ICalDate date = date(dateStr).hasTime(false).parse(); - property.getDates().add(date); - } catch (IllegalArgumentException e) { - throw new CannotParseException(15, dateStr); - } - } - - return property; - } - - @Override - protected JCalValue _writeJson(RecurrenceDates property, WriteContext context) { - List values = new ArrayList(); - List dates = property.getDates(); - List periods = property.getPeriods(); - if (!dates.isEmpty()) { - boolean inObservance = isInObservance(context); - for (ICalDate date : dates) { - String dateStr; - if (inObservance) { - dateStr = date(date).observance(true).extended(true).write(); - } else { - dateStr = date(date, property, context).extended(true).write(); - } - - values.add(dateStr); - } - } else if (!periods.isEmpty()) { - for (Period period : property.getPeriods()) { - StringBuilder sb = new StringBuilder(); - Date start = period.getStartDate(); - if (start != null) { - String dateStr = date(start, property, context).extended(true).write(); - sb.append(dateStr); - } - - sb.append('/'); - - Date end = period.getEndDate(); - Duration duration = period.getDuration(); - if (end != null) { - String dateStr = date(end, property, context).extended(true).write(); - sb.append(dateStr); - } else if (duration != null) { - sb.append(duration); - } - - values.add(sb.toString()); - } - } - - if (values.isEmpty()) { - values.add(""); - } - return JCalValue.multi(values); - } - - @Override - protected RecurrenceDates _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(value.asMulti(), dataType, parameters, context); - } - - private RecurrenceDates parse(List valueStrs, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - RecurrenceDates property = new RecurrenceDates(); - - if (dataType == PERIOD) { - //parse as periods - for (String timePeriodStr : valueStrs) { - int slash = timePeriodStr.indexOf('/'); - if (slash < 0) { - throw new CannotParseException(13); - } - - String startStr = timePeriodStr.substring(0, slash); - ICalDate start; - try { - start = date(startStr).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(10, startStr); - } - - String endStr = timePeriodStr.substring(slash + 1); - ICalDate end; - try { - end = date(endStr).parse(); - property.getPeriods().add(new Period(start, end)); - context.addDate(start, property, parameters); - context.addDate(end, property, parameters); - } catch (IllegalArgumentException e) { - //must be a duration - try { - Duration duration = Duration.parse(endStr); - property.getPeriods().add(new Period(start, duration)); - context.addDate(start, property, parameters); - } catch (IllegalArgumentException e2) { - throw new CannotParseException(14, endStr); - } - } - } - return property; - } - - //parse as dates - boolean hasTime = (dataType == DATE_TIME); - for (String valueStr : valueStrs) { - ICalDate date; - try { - date = date(valueStr).hasTime(hasTime).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(15, valueStr); - } - property.getDates().add(date); - context.addDate(date, property, parameters); - } - return property; - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/RecurrenceIdScribe.java b/app/src/main/java/biweekly/io/scribe/property/RecurrenceIdScribe.java deleted file mode 100644 index 462c127588..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RecurrenceIdScribe.java +++ /dev/null @@ -1,53 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.RecurrenceId; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RecurrenceId} properties. - * @author Michael Angstadt - */ -public class RecurrenceIdScribe extends DateOrDateTimePropertyScribe { - public RecurrenceIdScribe() { - super(RecurrenceId.class, "RECURRENCE-ID"); - } - - @Override - protected RecurrenceId newInstance(ICalDate date) { - return new RecurrenceId(date); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/RecurrencePropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/RecurrencePropertyScribe.java deleted file mode 100644 index a27742a93f..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RecurrencePropertyScribe.java +++ /dev/null @@ -1,1012 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.w3c.dom.Element; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.component.ICalComponent; -import biweekly.io.CannotParseException; -import biweekly.io.DataModelConversionException; -import biweekly.io.ParseContext; -import biweekly.io.ParseWarning; -import biweekly.io.TimezoneInfo; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.io.xml.XCalNamespaceContext; -import biweekly.parameter.ICalParameters; -import biweekly.property.DateStart; -import biweekly.property.ICalProperty; -import biweekly.property.RawProperty; -import biweekly.property.RecurrenceProperty; -import biweekly.util.ByDay; -import biweekly.util.DayOfWeek; -import biweekly.util.Frequency; -import biweekly.util.ICalDate; -import biweekly.util.ListMultimap; -import biweekly.util.Recurrence; -import biweekly.util.XmlUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties whose values are {@link Recurrence}. - * @param the property class - * @author Michael Angstadt - */ -public abstract class RecurrencePropertyScribe extends ICalPropertyScribe { - private static final String FREQ = "FREQ"; - private static final String UNTIL = "UNTIL"; - private static final String COUNT = "COUNT"; - private static final String INTERVAL = "INTERVAL"; - private static final String BYSECOND = "BYSECOND"; - private static final String BYMINUTE = "BYMINUTE"; - private static final String BYHOUR = "BYHOUR"; - private static final String BYDAY = "BYDAY"; - private static final String BYMONTHDAY = "BYMONTHDAY"; - private static final String BYYEARDAY = "BYYEARDAY"; - private static final String BYWEEKNO = "BYWEEKNO"; - private static final String BYMONTH = "BYMONTH"; - private static final String BYSETPOS = "BYSETPOS"; - private static final String WKST = "WKST"; - - public RecurrencePropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - return ICalDataType.RECUR; - } - - @Override - protected String _writeText(T property, WriteContext context) { - //null value - Recurrence recur = property.getValue(); - if (recur == null) { - return ""; - } - - switch (context.getVersion()) { - case V1_0: - return writeTextV1(property, context); - default: - return writeTextV2(property, context); - } - } - - private String writeTextV1(T property, WriteContext context) { - Recurrence recur = property.getValue(); - Frequency frequency = recur.getFrequency(); - if (frequency == null) { - return ""; - } - - StringBuilder sb = new StringBuilder(); - - Integer interval = recur.getInterval(); - if (interval == null) { - interval = 1; - } - - switch (frequency) { - case YEARLY: - if (!recur.getByMonth().isEmpty()) { - sb.append("YM").append(interval); - for (Integer month : recur.getByMonth()) { - sb.append(' ').append(month); - } - } else { - sb.append("YD").append(interval); - for (Integer day : recur.getByYearDay()) { - sb.append(' ').append(day); - } - } - break; - - case MONTHLY: - if (!recur.getByMonthDay().isEmpty()) { - sb.append("MD").append(interval); - for (Integer day : recur.getByMonthDay()) { - sb.append(' ').append(writeVCalInt(day)); - } - } else { - sb.append("MP").append(interval); - for (ByDay byDay : recur.getByDay()) { - DayOfWeek day = byDay.getDay(); - Integer prefix = byDay.getNum(); - if (prefix == null) { - prefix = 1; - } - - sb.append(' ').append(writeVCalInt(prefix)).append(' ').append(day.getAbbr()); - } - } - break; - - case WEEKLY: - sb.append("W").append(interval); - for (ByDay byDay : recur.getByDay()) { - sb.append(' ').append(byDay.getDay().getAbbr()); - } - break; - - case DAILY: - sb.append("D").append(interval); - break; - - case HOURLY: - sb.append("M").append(interval * 60); - break; - - case MINUTELY: - sb.append("M").append(interval); - break; - - default: - return ""; - } - - Integer count = recur.getCount(); - ICalDate until = recur.getUntil(); - sb.append(' '); - - if (count != null) { - sb.append('#').append(count); - } else if (until != null) { - String dateStr = date(until, property, context).extended(false).write(); - sb.append(dateStr); - } else { - sb.append("#0"); - } - - return sb.toString(); - } - - private String writeTextV2(T property, WriteContext context) { - ListMultimap components = buildComponents(property, context, false); - return VObjectPropertyValues.writeMultimap(components.getMap()); - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - if (value.isEmpty()) { - return newInstance(new Recurrence.Builder((Frequency) null).build()); - } - - switch (context.getVersion()) { - case V1_0: - handleVersion1Multivalued(value, dataType, parameters, context); - return parseTextV1(value, dataType, parameters, context); - default: - return parseTextV2(value, dataType, parameters, context); - } - } - - /** - * Version 1.0 allows multiple RRULE values to be defined inside of the same - * property. This method checks for this and, if multiple values are found, - * parses them and throws a {@link DataModelConversionException}. - * @param value the property value - * @param dataType the property data type - * @param parameters the property parameters - * @param context the parse context - * @throws DataModelConversionException if the property contains multiple - * RRULE values - */ - private void handleVersion1Multivalued(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - List rrules = splitRRULEValues(value); - if (rrules.size() == 1) { - return; - } - - DataModelConversionException conversionException = new DataModelConversionException(null); - for (String rrule : rrules) { - ICalParameters parametersCopy = new ICalParameters(parameters); - - ICalProperty property; - try { - property = parseTextV1(rrule, dataType, parametersCopy, context); - } catch (CannotParseException e) { - //@formatter:off - context.getWarnings().add(new ParseWarning.Builder(context) - .message(e) - .build() - ); - //@formatter:on - property = new RawProperty(getPropertyName(context.getVersion()), dataType, rrule); - property.setParameters(parametersCopy); - } - conversionException.getProperties().add(property); - } - - throw conversionException; - } - - /** - * Version 1.0 allows multiple RRULE values to be defined inside of the same - * property. This method extracts each RRULE value from the property value. - * @param value the property value - * @return the RRULE values - */ - private List splitRRULEValues(String value) { - List values = new ArrayList(); - Pattern p = Pattern.compile("#\\d+|\\d{8}T\\d{6}Z?"); - Matcher m = p.matcher(value); - - int prevIndex = 0; - while (m.find()) { - int end = m.end(); - String subValue = value.substring(prevIndex, end).trim(); - values.add(subValue); - prevIndex = end; - } - String subValue = value.substring(prevIndex).trim(); - if (subValue.length() > 0) { - values.add(subValue); - } - - return values; - } - - private T parseTextV1(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - final Recurrence.Builder builder = new Recurrence.Builder((Frequency) null); - - List splitValues = Arrays.asList(value.toUpperCase().split("\\s+")); - - //parse the frequency and interval from the first token (e.g. "W2") - String frequencyStr; - Integer interval; - { - String firstToken = splitValues.get(0); - Pattern p = Pattern.compile("^([A-Z]+)(\\d+)$"); - Matcher m = p.matcher(firstToken); - if (!m.find()) { - throw new CannotParseException(40, firstToken); - } - - frequencyStr = m.group(1); - interval = integerValueOf(m.group(2)); - - splitValues = splitValues.subList(1, splitValues.size()); - } - builder.interval(interval); - - Integer count = null; - ICalDate until = null; - if (splitValues.isEmpty()) { - count = 2; - } else { - String lastToken = splitValues.get(splitValues.size() - 1); - if (lastToken.startsWith("#")) { - String countStr = lastToken.substring(1); - count = integerValueOf(countStr); - if (count == 0) { - //infinite - count = null; - } - - splitValues = splitValues.subList(0, splitValues.size() - 1); - } else { - try { - //see if the value is an "until" date - until = date(lastToken).parse(); - splitValues = splitValues.subList(0, splitValues.size() - 1); - } catch (IllegalArgumentException e) { - //last token is a regular value - count = 2; - } - } - } - builder.count(count); - builder.until(until); - - //determine what frequency enum to use and how to treat each tokenized value - Frequency frequency; - Handler handler; - if ("YD".equals(frequencyStr)) { - frequency = Frequency.YEARLY; - handler = new Handler() { - public void handle(String value) { - if (value == null) { - return; - } - - Integer dayOfYear = integerValueOf(value); - builder.byYearDay(dayOfYear); - } - }; - } else if ("YM".equals(frequencyStr)) { - frequency = Frequency.YEARLY; - handler = new Handler() { - public void handle(String value) { - if (value == null) { - return; - } - - Integer month = integerValueOf(value); - builder.byMonth(month); - } - }; - } else if ("MD".equals(frequencyStr)) { - frequency = Frequency.MONTHLY; - handler = new Handler() { - public void handle(String value) { - if (value == null) { - return; - } - - try { - Integer date = "LD".equals(value) ? -1 : parseVCalInt(value); - builder.byMonthDay(date); - } catch (NumberFormatException e) { - throw new CannotParseException(40, value); - } - } - }; - } else if ("MP".equals(frequencyStr)) { - frequency = Frequency.MONTHLY; - handler = new Handler() { - private final List nums = new ArrayList(); - private final List days = new ArrayList(); - private boolean readNum = false; - - public void handle(String value) { - if (value == null) { - //end of list - for (Integer num : nums) { - for (DayOfWeek day : days) { - builder.byDay(num, day); - } - } - return; - } - - if (value.matches("\\d{4}")) { - readNum = false; - - Integer hour = integerValueOf(value.substring(0, 2)); - builder.byHour(hour); - - Integer minute = integerValueOf(value.substring(2, 4)); - builder.byMinute(minute); - return; - } - - try { - Integer curNum = parseVCalInt(value); - - if (!readNum) { - //reset lists, new segment - for (Integer num : nums) { - for (DayOfWeek day : days) { - builder.byDay(num, day); - } - } - nums.clear(); - days.clear(); - - readNum = true; - } - - nums.add(curNum); - } catch (NumberFormatException e) { - readNum = false; - - DayOfWeek day = parseDay(value); - days.add(day); - } - } - }; - } else if ("W".equals(frequencyStr)) { - frequency = Frequency.WEEKLY; - handler = new Handler() { - public void handle(String value) { - if (value == null) { - return; - } - - DayOfWeek day = parseDay(value); - builder.byDay(day); - } - }; - } else if ("D".equals(frequencyStr)) { - frequency = Frequency.DAILY; - handler = new Handler() { - public void handle(String value) { - if (value == null) { - return; - } - - Integer hour = integerValueOf(value.substring(0, 2)); - builder.byHour(hour); - - Integer minute = integerValueOf(value.substring(2, 4)); - builder.byMinute(minute); - } - }; - } else if ("M".equals(frequencyStr)) { - frequency = Frequency.MINUTELY; - handler = new Handler() { - public void handle(String value) { - //TODO can this ever have values? - } - }; - } else { - throw new CannotParseException(41, frequencyStr); - } - - builder.frequency(frequency); - - //parse the rest of the tokens - for (String splitValue : splitValues) { - //TODO not sure how to handle the "$" symbol, ignore it - if (splitValue.endsWith("$")) { - context.addWarning(36, splitValue); - splitValue = splitValue.substring(0, splitValue.length() - 1); - } - - handler.handle(splitValue); - } - handler.handle(null); - - T property = newInstance(builder.build()); - if (until != null) { - context.addDate(until, property, parameters); - } - - return property; - } - - private T parseTextV2(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - Recurrence.Builder builder = new Recurrence.Builder((Frequency) null); - ListMultimap rules = new ListMultimap(VObjectPropertyValues.parseMultimap(value)); - - parseFreq(rules, builder, context); - parseUntil(rules, builder, context); - parseCount(rules, builder, context); - parseInterval(rules, builder, context); - parseBySecond(rules, builder, context); - parseByMinute(rules, builder, context); - parseByHour(rules, builder, context); - parseByDay(rules, builder, context); - parseByMonthDay(rules, builder, context); - parseByYearDay(rules, builder, context); - parseByWeekNo(rules, builder, context); - parseByMonth(rules, builder, context); - parseBySetPos(rules, builder, context); - parseWkst(rules, builder, context); - parseXRules(rules, builder); //must be called last - - T property = newInstance(builder.build()); - - ICalDate until = property.getValue().getUntil(); - if (until != null) { - context.addDate(until, property, parameters); - } - - return property; - } - - /** - * Parses an integer string, where the sign is at the end of the string - * instead of at the beginning (for example, "5-"). - * @param value the string - * @return the value - * @throws NumberFormatException if the string cannot be parsed as an - * integer - */ - private static int parseVCalInt(String value) { - int negate = 1; - if (value.endsWith("+")) { - value = value.substring(0, value.length() - 1); - } else if (value.endsWith("-")) { - value = value.substring(0, value.length() - 1); - negate = -1; - } - - return Integer.parseInt(value) * negate; - } - - /** - * Same as {@link Integer#valueOf(String)}, but throws a - * {@link CannotParseException} when it fails. - * @param value the string to parse - * @return the parse integer - * @throws CannotParseException if the string cannot be parsed - */ - private static Integer integerValueOf(String value) { - try { - return Integer.valueOf(value); - } catch (NumberFormatException e) { - throw new CannotParseException(40, value); - } - } - - private static String writeVCalInt(Integer value) { - if (value > 0) { - return value + "+"; - } - - if (value < 0) { - return Math.abs(value) + "-"; - } - - return value.toString(); - } - - private DayOfWeek parseDay(String value) { - DayOfWeek day = DayOfWeek.valueOfAbbr(value); - if (day == null) { - throw new CannotParseException(42, value); - } - - return day; - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - XCalElement recurElement = element.append(dataType(property, null)); - - Recurrence recur = property.getValue(); - if (recur == null) { - return; - } - - ListMultimap components = buildComponents(property, context, true); - for (Map.Entry> component : components) { - String name = component.getKey().toLowerCase(); - for (Object value : component.getValue()) { - recurElement.append(name, value.toString()); - } - } - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - XCalElement value = element.child(dataType); - if (value == null) { - throw missingXmlElements(dataType); - } - - ListMultimap rules = new ListMultimap(); - for (Element child : XmlUtils.toElementList(value.getElement().getChildNodes())) { - if (!XCalNamespaceContext.XCAL_NS.equals(child.getNamespaceURI())) { - continue; - } - - String name = child.getLocalName().toUpperCase(); - String text = child.getTextContent(); - rules.put(name, text); - } - - Recurrence.Builder builder = new Recurrence.Builder((Frequency) null); - - parseFreq(rules, builder, context); - parseUntil(rules, builder, context); - parseCount(rules, builder, context); - parseInterval(rules, builder, context); - parseBySecond(rules, builder, context); - parseByMinute(rules, builder, context); - parseByHour(rules, builder, context); - parseByDay(rules, builder, context); - parseByMonthDay(rules, builder, context); - parseByYearDay(rules, builder, context); - parseByWeekNo(rules, builder, context); - parseByMonth(rules, builder, context); - parseBySetPos(rules, builder, context); - parseWkst(rules, builder, context); - parseXRules(rules, builder); //must be called last - - T property = newInstance(builder.build()); - - ICalDate until = property.getValue().getUntil(); - if (until != null) { - context.addDate(until, property, parameters); - } - - return property; - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - Recurrence recur = property.getValue(); - if (recur == null) { - return JCalValue.object(new ListMultimap(0)); - } - - ListMultimap components = buildComponents(property, context, true); - - //lower-case all the keys - ListMultimap object = new ListMultimap(components.keySet().size()); - for (Map.Entry> entry : components) { - String key = entry.getKey().toLowerCase(); - object.putAll(key, entry.getValue()); - } - - return JCalValue.object(object); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - Recurrence.Builder builder = new Recurrence.Builder((Frequency) null); - - //upper-case the keys - ListMultimap object = value.asObject(); - ListMultimap rules = new ListMultimap(object.keySet().size()); - for (Map.Entry> entry : object) { - String key = entry.getKey().toUpperCase(); - rules.putAll(key, entry.getValue()); - } - - parseFreq(rules, builder, context); - parseUntil(rules, builder, context); - parseCount(rules, builder, context); - parseInterval(rules, builder, context); - parseBySecond(rules, builder, context); - parseByMinute(rules, builder, context); - parseByHour(rules, builder, context); - parseByDay(rules, builder, context); - parseByMonthDay(rules, builder, context); - parseByYearDay(rules, builder, context); - parseByWeekNo(rules, builder, context); - parseByMonth(rules, builder, context); - parseBySetPos(rules, builder, context); - parseWkst(rules, builder, context); - parseXRules(rules, builder); //must be called last - - T property = newInstance(builder.build()); - - ICalDate until = property.getValue().getUntil(); - if (until != null) { - context.addDate(until, property, parameters); - } - - return property; - } - - /** - * Creates a new instance of the recurrence property. - * @param recur the recurrence value - * @return the new instance - */ - protected abstract T newInstance(Recurrence recur); - - private void parseFreq(ListMultimap rules, final Recurrence.Builder builder, final ParseContext context) { - parseFirst(rules, FREQ, new Handler() { - public void handle(String value) { - value = value.toUpperCase(); - try { - builder.frequency(Frequency.valueOf(value)); - } catch (IllegalArgumentException e) { - context.addWarning(7, FREQ, value); - } - } - }); - } - - private void parseUntil(ListMultimap rules, final Recurrence.Builder builder, final ParseContext context) { - parseFirst(rules, UNTIL, new Handler() { - public void handle(String value) { - try { - builder.until(date(value).parse()); - } catch (IllegalArgumentException e) { - context.addWarning(7, UNTIL, value); - } - } - }); - } - - private void parseCount(ListMultimap rules, final Recurrence.Builder builder, final ParseContext context) { - parseFirst(rules, COUNT, new Handler() { - public void handle(String value) { - try { - builder.count(Integer.valueOf(value)); - } catch (NumberFormatException e) { - context.addWarning(7, COUNT, value); - } - } - }); - } - - private void parseInterval(ListMultimap rules, final Recurrence.Builder builder, final ParseContext context) { - parseFirst(rules, INTERVAL, new Handler() { - public void handle(String value) { - try { - builder.interval(Integer.valueOf(value)); - } catch (NumberFormatException e) { - context.addWarning(7, INTERVAL, value); - } - } - }); - } - - private void parseBySecond(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYSECOND, rules, context, new Handler() { - public void handle(Integer value) { - builder.bySecond(value); - } - }); - } - - private void parseByMinute(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYMINUTE, rules, context, new Handler() { - public void handle(Integer value) { - builder.byMinute(value); - } - }); - } - - private void parseByHour(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYHOUR, rules, context, new Handler() { - public void handle(Integer value) { - builder.byHour(value); - } - }); - } - - private void parseByDay(ListMultimap rules, Recurrence.Builder builder, ParseContext context) { - Pattern p = Pattern.compile("^([-+]?\\d+)?(.*)$"); - for (String value : rules.removeAll(BYDAY)) { - Matcher m = p.matcher(value); - if (!m.find()) { - //this should never happen - //the regex contains a "match-all" pattern and should never not find anything - context.addWarning(7, BYDAY, value); - continue; - } - - String dayStr = m.group(2); - DayOfWeek day = DayOfWeek.valueOfAbbr(dayStr); - if (day == null) { - context.addWarning(7, BYDAY, value); - continue; - } - - String prefixStr = m.group(1); - Integer prefix = (prefixStr == null) ? null : Integer.valueOf(prefixStr); //no need to catch NumberFormatException because the regex guarantees that it will be a number - - builder.byDay(prefix, day); - } - } - - private void parseByMonthDay(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYMONTHDAY, rules, context, new Handler() { - public void handle(Integer value) { - builder.byMonthDay(value); - } - }); - } - - private void parseByYearDay(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYYEARDAY, rules, context, new Handler() { - public void handle(Integer value) { - builder.byYearDay(value); - } - }); - } - - private void parseByWeekNo(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYWEEKNO, rules, context, new Handler() { - public void handle(Integer value) { - builder.byWeekNo(value); - } - }); - } - - private void parseByMonth(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYMONTH, rules, context, new Handler() { - public void handle(Integer value) { - builder.byMonth(value); - } - }); - } - - private void parseBySetPos(ListMultimap rules, final Recurrence.Builder builder, ParseContext context) { - parseIntegerList(BYSETPOS, rules, context, new Handler() { - public void handle(Integer value) { - builder.bySetPos(value); - } - }); - } - - private void parseWkst(ListMultimap rules, final Recurrence.Builder builder, final ParseContext context) { - parseFirst(rules, WKST, new Handler() { - public void handle(String value) { - DayOfWeek day = DayOfWeek.valueOfAbbr(value); - if (day == null) { - context.addWarning(7, WKST, value); - return; - } - - builder.workweekStarts(day); - } - }); - } - - private void parseXRules(ListMultimap rules, Recurrence.Builder builder) { - for (Map.Entry> rule : rules) { - String name = rule.getKey(); - for (String value : rule.getValue()) { - builder.xrule(name, value); - } - } - } - - private ListMultimap buildComponents(T property, WriteContext context, boolean extended) { - ListMultimap components = new ListMultimap(); - Recurrence recur = property.getValue(); - - //FREQ must come first - if (recur.getFrequency() != null) { - components.put(FREQ, recur.getFrequency().name()); - } - - ICalDate until = recur.getUntil(); - if (until != null) { - components.put(UNTIL, writeUntil(until, context, extended)); - } - - if (recur.getCount() != null) { - components.put(COUNT, recur.getCount()); - } - - if (recur.getInterval() != null) { - components.put(INTERVAL, recur.getInterval()); - } - - components.putAll(BYSECOND, recur.getBySecond()); - components.putAll(BYMINUTE, recur.getByMinute()); - components.putAll(BYHOUR, recur.getByHour()); - - for (ByDay byDay : recur.getByDay()) { - Integer prefix = byDay.getNum(); - DayOfWeek day = byDay.getDay(); - - String value = day.getAbbr(); - if (prefix != null) { - value = prefix + value; - } - components.put(BYDAY, value); - } - - components.putAll(BYMONTHDAY, recur.getByMonthDay()); - components.putAll(BYYEARDAY, recur.getByYearDay()); - components.putAll(BYWEEKNO, recur.getByWeekNo()); - components.putAll(BYMONTH, recur.getByMonth()); - components.putAll(BYSETPOS, recur.getBySetPos()); - - if (recur.getWorkweekStarts() != null) { - components.put(WKST, recur.getWorkweekStarts().getAbbr()); - } - - for (Map.Entry> entry : recur.getXRules().entrySet()) { - String name = entry.getKey(); - List values = entry.getValue(); - components.putAll(name, values); - } - - return components; - } - - private String writeUntil(ICalDate until, WriteContext context, boolean extended) { - if (!until.hasTime()) { - return date(until).extended(extended).write(); - } - - /* - * RFC 5545 p.41 - * - * In the case of the "STANDARD" and "DAYLIGHT" sub-components the UNTIL - * rule part MUST always be specified as a date with UTC time. If - * specified as a DATE-TIME value, then it MUST be specified in a UTC - * time format. - */ - - if (isInObservance(context)) { - return date(until).utc(true).extended(extended).write(); - } - - /* - * RFC 2445 p.42 - * - * If specified as a date-time value, then it MUST be specified in an - * UTC time format. - */ - if (context.getVersion() == ICalVersion.V2_0_DEPRECATED) { - return date(until).extended(extended).utc(true).write(); - } - - /* - * RFC 5545 p.41 - * - * Furthermore, if the "DTSTART" property is specified as a date with - * local time, then the UNTIL rule part MUST also be specified as a date - * with local time. If the "DTSTART" property is specified as a date - * with UTC time or a date with local time and time zone reference, then - * the UNTIL rule part MUST be specified as a date with UTC time. - */ - - ICalComponent parent = context.getParent(); - if (parent == null) { - return date(until).extended(extended).utc(true).write(); - } - - DateStart dtstart = parent.getProperty(DateStart.class); - if (dtstart == null) { - return date(until).extended(extended).utc(true).write(); - } - - /* - * If DTSTART is floating, then UNTIL should be floating. - */ - TimezoneInfo tzinfo = context.getTimezoneInfo(); - boolean dtstartFloating = tzinfo.isFloating(dtstart); - if (dtstartFloating) { - return date(until).extended(extended).tz(true, null).write(); - } - - /* - * Otherwise, UNTIL should be UTC. - */ - return date(until).extended(extended).utc(true).write(); - } - - private void parseFirst(ListMultimap rules, String name, Handler handler) { - List values = rules.removeAll(name); - if (values.isEmpty()) { - return; - } - - String value = values.get(0); - handler.handle(value); - } - - private void parseIntegerList(String name, ListMultimap rules, ParseContext context, Handler handler) { - List values = rules.removeAll(name); - for (String value : values) { - try { - handler.handle(Integer.valueOf(value)); - } catch (NumberFormatException e) { - context.addWarning(8, name, value); - } - } - } - - private interface Handler { - void handle(T value); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/RecurrenceRuleScribe.java b/app/src/main/java/biweekly/io/scribe/property/RecurrenceRuleScribe.java deleted file mode 100644 index 684d005ef2..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RecurrenceRuleScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.property.RecurrenceRule; -import biweekly.util.Recurrence; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RecurrenceRule} properties. - * @author Michael Angstadt - */ -public class RecurrenceRuleScribe extends RecurrencePropertyScribe { - public RecurrenceRuleScribe() { - super(RecurrenceRule.class, "RRULE"); - } - - @Override - protected RecurrenceRule newInstance(Recurrence recur) { - return new RecurrenceRule(recur); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/RefreshIntervalScribe.java b/app/src/main/java/biweekly/io/scribe/property/RefreshIntervalScribe.java deleted file mode 100644 index 7a83f6d88d..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RefreshIntervalScribe.java +++ /dev/null @@ -1,116 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.RefreshInterval; -import biweekly.util.Duration; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RefreshInterval} properties. - * @author Michael Angstadt - */ -public class RefreshIntervalScribe extends ICalPropertyScribe { - public RefreshIntervalScribe() { - super(RefreshInterval.class, "REFRESH-INTERVAL", ICalDataType.DURATION); - } - - @Override - protected String _writeText(RefreshInterval property, WriteContext context) { - Duration duration = property.getValue(); - if (duration != null) { - return duration.toString(); - } - - return ""; - } - - @Override - protected RefreshInterval _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value); - } - - @Override - protected void _writeXml(RefreshInterval property, XCalElement element, WriteContext context) { - String durationStr = null; - - Duration duration = property.getValue(); - if (duration != null) { - durationStr = duration.toString(); - } - - element.append(dataType(property, null), durationStr); - } - - @Override - protected RefreshInterval _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return parse(value); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(RefreshInterval property, WriteContext context) { - Duration value = property.getValue(); - if (value != null) { - return JCalValue.single(value.toString()); - } - - return JCalValue.single(""); - } - - @Override - protected RefreshInterval _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = value.asSingle(); - return parse(valueStr); - } - - private RefreshInterval parse(String value) { - if (value == null) { - return new RefreshInterval((Duration) null); - } - - try { - Duration duration = Duration.parse(value); - return new RefreshInterval(duration); - } catch (IllegalArgumentException e) { - throw new CannotParseException(18); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/RelatedToScribe.java b/app/src/main/java/biweekly/io/scribe/property/RelatedToScribe.java deleted file mode 100644 index 6052331033..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RelatedToScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.RelatedTo; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RelatedTo} properties. - * @author Michael Angstadt - */ -public class RelatedToScribe extends TextPropertyScribe { - public RelatedToScribe() { - super(RelatedTo.class, "RELATED-TO"); - } - - @Override - protected RelatedTo newInstance(String value, ICalVersion version) { - return new RelatedTo(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/RepeatScribe.java b/app/src/main/java/biweekly/io/scribe/property/RepeatScribe.java deleted file mode 100644 index 14948b39dc..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RepeatScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.Repeat; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Repeat} properties. - * @author Michael Angstadt - */ -public class RepeatScribe extends IntegerPropertyScribe { - public RepeatScribe() { - super(Repeat.class, "REPEAT"); - } - - @Override - protected Repeat newInstance(Integer value) { - return new Repeat(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/RequestStatusScribe.java b/app/src/main/java/biweekly/io/scribe/property/RequestStatusScribe.java deleted file mode 100644 index 1526061588..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/RequestStatusScribe.java +++ /dev/null @@ -1,123 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.RequestStatus; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueBuilder; -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.StructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link RequestStatus} properties. - * @author Michael Angstadt - */ -public class RequestStatusScribe extends ICalPropertyScribe { - public RequestStatusScribe() { - super(RequestStatus.class, "REQUEST-STATUS", ICalDataType.TEXT); - } - - @Override - protected String _writeText(RequestStatus property, WriteContext context) { - SemiStructuredValueBuilder builder = new SemiStructuredValueBuilder(); - builder.append(property.getStatusCode()); - builder.append(property.getDescription()); - builder.append(property.getExceptionText()); - boolean escapeCommas = (context.getVersion() != ICalVersion.V1_0); - return builder.build(escapeCommas, true); - } - - @Override - protected RequestStatus _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - SemiStructuredValueIterator it = new SemiStructuredValueIterator(value); - - RequestStatus requestStatus = new RequestStatus(it.next()); - requestStatus.setDescription(it.next()); - requestStatus.setExceptionText(it.next()); - return requestStatus; - } - - @Override - protected void _writeXml(RequestStatus property, XCalElement element, WriteContext context) { - String code = property.getStatusCode(); - element.append("code", code); - - String description = property.getDescription(); - element.append("description", description); - - String data = property.getExceptionText(); - if (data != null) { - element.append("data", data); - } - } - - @Override - protected RequestStatus _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - String code = element.first("code"); - if (code == null) { - throw missingXmlElements("code"); - } - - RequestStatus requestStatus = new RequestStatus(s(code)); - requestStatus.setDescription(s(element.first("description"))); //optional field - requestStatus.setExceptionText(s(element.first("data"))); //optional field - return requestStatus; - } - - @Override - protected JCalValue _writeJson(RequestStatus property, WriteContext context) { - return JCalValue.structured(property.getStatusCode(), property.getDescription(), property.getExceptionText()); - } - - @Override - protected RequestStatus _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - StructuredValueIterator it = new StructuredValueIterator(value.asStructured()); - - RequestStatus requestStatus = new RequestStatus(it.nextValue()); - requestStatus.setDescription(it.nextValue()); - requestStatus.setExceptionText(it.nextValue()); - return requestStatus; - } - - private static String s(String str) { - return (str == null || str.isEmpty()) ? null : str; - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/ResourcesScribe.java b/app/src/main/java/biweekly/io/scribe/property/ResourcesScribe.java deleted file mode 100644 index 9ec0fbc3ca..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/ResourcesScribe.java +++ /dev/null @@ -1,45 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.parameter.ICalParameters; -import biweekly.property.Resources; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Resources} properties. - * @author Michael Angstadt - */ -public class ResourcesScribe extends TextListPropertyScribe { - public ResourcesScribe() { - super(Resources.class, "RESOURCES"); - } - - @Override - public Resources newInstance(ICalDataType dataType, ICalParameters parameters) { - return new Resources(); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/SequenceScribe.java b/app/src/main/java/biweekly/io/scribe/property/SequenceScribe.java deleted file mode 100644 index 6977f7d924..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/SequenceScribe.java +++ /dev/null @@ -1,43 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.property.Sequence; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Sequence} properties. - * @author Michael Angstadt - */ -public class SequenceScribe extends IntegerPropertyScribe { - public SequenceScribe() { - super(Sequence.class, "SEQUENCE"); - } - - @Override - protected Sequence newInstance(Integer value) { - return new Sequence(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/SourceScribe.java b/app/src/main/java/biweekly/io/scribe/property/SourceScribe.java deleted file mode 100644 index d88cce74bf..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/SourceScribe.java +++ /dev/null @@ -1,45 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.property.Source; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Source} properties. - * @author Michael Angstadt - */ -public class SourceScribe extends TextPropertyScribe { - public SourceScribe() { - super(Source.class, "SOURCE", ICalDataType.URI); - } - - @Override - protected Source newInstance(String value, ICalVersion version) { - return new Source(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/StatusScribe.java b/app/src/main/java/biweekly/io/scribe/property/StatusScribe.java deleted file mode 100644 index e9d738a546..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/StatusScribe.java +++ /dev/null @@ -1,58 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.io.WriteContext; -import biweekly.property.Status; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Status} properties. - * @author Michael Angstadt - */ -public class StatusScribe extends TextPropertyScribe { - public StatusScribe() { - super(Status.class, "STATUS"); - } - - @Override - protected String _writeText(Status property, WriteContext context) { - if (context.getVersion() == ICalVersion.V1_0 && property.isNeedsAction()) { - //vCal doesn't have a hyphen in the value - return "NEEDS ACTION"; - } - return super._writeText(property, context); - } - - @Override - protected Status newInstance(String value, ICalVersion version) { - if (version == ICalVersion.V1_0 && "NEEDS ACTION".equalsIgnoreCase(value)) { - //vCal doesn't have a hyphen in the value - return Status.needsAction(); - } - return new Status(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/SummaryScribe.java b/app/src/main/java/biweekly/io/scribe/property/SummaryScribe.java deleted file mode 100644 index 71eea603b4..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/SummaryScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Summary; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Summary} properties. - * @author Michael Angstadt - */ -public class SummaryScribe extends TextPropertyScribe { - public SummaryScribe() { - super(Summary.class, "SUMMARY"); - } - - @Override - protected Summary newInstance(String value, ICalVersion version) { - return new Summary(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TextListPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/TextListPropertyScribe.java deleted file mode 100644 index cdfe264d72..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TextListPropertyScribe.java +++ /dev/null @@ -1,59 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.parameter.ICalParameters; -import biweekly.property.ListProperty; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that have a list of text values. - * @param the property class - * @author Michael Angstadt - */ -public abstract class TextListPropertyScribe> extends ListPropertyScribe { - public TextListPropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName); - } - - @Override - protected ICalDataType _defaultDataType(ICalVersion version) { - return ICalDataType.TEXT; - } - - @Override - protected String writeValue(T property, String value, WriteContext context) { - return value; - } - - @Override - protected String readValue(T property, String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return value; - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/TextPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/TextPropertyScribe.java deleted file mode 100644 index 0822933eca..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TextPropertyScribe.java +++ /dev/null @@ -1,96 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.TextProperty; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that have text values. - * @param the property class - * @author Michael Angstadt - */ -public abstract class TextPropertyScribe extends ICalPropertyScribe { - public TextPropertyScribe(Class clazz, String propertyName) { - this(clazz, propertyName, ICalDataType.TEXT); - } - - public TextPropertyScribe(Class clazz, String propertyName, ICalDataType dataType) { - super(clazz, propertyName, dataType); - } - - @Override - protected String _writeText(T property, WriteContext context) { - String value = property.getValue(); - if (value != null) { - return VObjectPropertyValues.escape(value); - } - - return ""; - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return newInstance(value, context.getVersion()); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - element.append(dataType(property, context.getVersion()), property.getValue()); - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return newInstance(value, context.getVersion()); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - return JCalValue.single(property.getValue()); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return newInstance(value.asSingle(), context.getVersion()); - } - - protected abstract T newInstance(String value, ICalVersion version); -} diff --git a/app/src/main/java/biweekly/io/scribe/property/TimezoneIdScribe.java b/app/src/main/java/biweekly/io/scribe/property/TimezoneIdScribe.java deleted file mode 100644 index e2bb876506..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TimezoneIdScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.TimezoneId; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link TimezoneId} properties. - * @author Michael Angstadt - */ -public class TimezoneIdScribe extends TextPropertyScribe { - public TimezoneIdScribe() { - super(TimezoneId.class, "TZID"); - } - - @Override - protected TimezoneId newInstance(String value, ICalVersion version) { - return new TimezoneId(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TimezoneNameScribe.java b/app/src/main/java/biweekly/io/scribe/property/TimezoneNameScribe.java deleted file mode 100644 index b439b01567..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TimezoneNameScribe.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.TimezoneName; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link TimezoneName} properties. - * @author Michael Angstadt - */ -public class TimezoneNameScribe extends TextPropertyScribe { - public TimezoneNameScribe() { - super(TimezoneName.class, "TZNAME"); - } - - @Override - protected TimezoneName newInstance(String value, ICalVersion version) { - return new TimezoneName(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TimezoneOffsetFromScribe.java b/app/src/main/java/biweekly/io/scribe/property/TimezoneOffsetFromScribe.java deleted file mode 100644 index 0e8f54a543..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TimezoneOffsetFromScribe.java +++ /dev/null @@ -1,53 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.TimezoneOffsetFrom; -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link TimezoneOffsetFrom} properties. - * @author Michael Angstadt - */ -public class TimezoneOffsetFromScribe extends UtcOffsetPropertyScribe { - public TimezoneOffsetFromScribe() { - super(TimezoneOffsetFrom.class, "TZOFFSETFROM"); - } - - @Override - protected TimezoneOffsetFrom newInstance(UtcOffset offset) { - return new TimezoneOffsetFrom(offset); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TimezoneOffsetToScribe.java b/app/src/main/java/biweekly/io/scribe/property/TimezoneOffsetToScribe.java deleted file mode 100644 index 14e9646afb..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TimezoneOffsetToScribe.java +++ /dev/null @@ -1,53 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.TimezoneOffsetTo; -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link TimezoneOffsetTo} properties. - * @author Michael Angstadt - */ -public class TimezoneOffsetToScribe extends UtcOffsetPropertyScribe { - public TimezoneOffsetToScribe() { - super(TimezoneOffsetTo.class, "TZOFFSETTO"); - } - - @Override - protected TimezoneOffsetTo newInstance(UtcOffset offset) { - return new TimezoneOffsetTo(offset); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TimezoneScribe.java b/app/src/main/java/biweekly/io/scribe/property/TimezoneScribe.java deleted file mode 100644 index 111d46953c..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TimezoneScribe.java +++ /dev/null @@ -1,53 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalVersion; -import biweekly.property.Timezone; -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Timezone} properties. - * @author Michael Angstadt - */ -public class TimezoneScribe extends UtcOffsetPropertyScribe { - public TimezoneScribe() { - super(Timezone.class, "TZ"); - } - - @Override - protected Timezone newInstance(UtcOffset offset) { - return new Timezone(offset); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V1_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/TimezoneUrlScribe.java b/app/src/main/java/biweekly/io/scribe/property/TimezoneUrlScribe.java deleted file mode 100644 index 7b560bb315..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TimezoneUrlScribe.java +++ /dev/null @@ -1,53 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.property.TimezoneUrl; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link TimezoneUrl} properties. - * @author Michael Angstadt - */ -public class TimezoneUrlScribe extends TextPropertyScribe { - public TimezoneUrlScribe() { - super(TimezoneUrl.class, "TZURL", ICalDataType.URI); - } - - @Override - protected TimezoneUrl newInstance(String value, ICalVersion version) { - return new TimezoneUrl(value); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TransparencyScribe.java b/app/src/main/java/biweekly/io/scribe/property/TransparencyScribe.java deleted file mode 100644 index e369ae4e24..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TransparencyScribe.java +++ /dev/null @@ -1,74 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.io.WriteContext; -import biweekly.property.Transparency; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Transparency} properties. - * @author Michael Angstadt - */ -public class TransparencyScribe extends TextPropertyScribe { - public TransparencyScribe() { - super(Transparency.class, "TRANSP"); - } - - @Override - protected String _writeText(Transparency property, WriteContext context) { - if (context.getVersion() == ICalVersion.V1_0) { - if (property.isOpaque()) { - return "0"; - } - if (property.isTransparent()) { - return "1"; - } - } - - return super._writeText(property, context); - } - - @Override - protected Transparency newInstance(String value, ICalVersion version) { - if (version == ICalVersion.V1_0) { - try { - int intValue = Integer.parseInt(value); - switch (intValue) { - case 0: - return Transparency.opaque(); - case 1: - //values greater than "1" provide implementation-specific semantics - return Transparency.transparent(); - } - } catch (NumberFormatException e) { - //ignore - } - } - - return new Transparency(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/TriggerScribe.java b/app/src/main/java/biweekly/io/scribe/property/TriggerScribe.java deleted file mode 100644 index 23d2990532..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/TriggerScribe.java +++ /dev/null @@ -1,177 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.Date; -import java.util.EnumSet; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.Trigger; -import biweekly.util.Duration; -import biweekly.util.ICalDate; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Trigger} properties. - * @author Michael Angstadt - */ -public class TriggerScribe extends ICalPropertyScribe { - public TriggerScribe() { - super(Trigger.class, "TRIGGER", ICalDataType.DURATION); - } - - @Override - protected ICalDataType _dataType(Trigger property, ICalVersion version) { - return (property.getDate() == null) ? ICalDataType.DURATION : ICalDataType.DATE_TIME; - } - - @Override - protected String _writeText(Trigger property, WriteContext context) { - Duration duration = property.getDuration(); - if (duration != null) { - return duration.toString(); - } - - Date date = property.getDate(); - return date(date, property, context).extended(false).write(); - } - - @Override - protected Trigger _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - - try { - ICalDate date = date(value).parse(); - Trigger property = new Trigger(date); - context.addDate(date, property, parameters); - return property; - } catch (IllegalArgumentException e) { - //unable to parse value as date, must be a duration - } - - try { - return new Trigger(Duration.parse(value), parameters.getRelated()); - } catch (IllegalArgumentException e) { - //unable to parse duration - } - - throw new CannotParseException(25); - } - - @Override - protected void _writeXml(Trigger property, XCalElement element, WriteContext context) { - Duration duration = property.getDuration(); - if (duration != null) { - element.append(ICalDataType.DURATION, duration.toString()); - return; - } - - Date date = property.getDate(); - if (date != null) { - String dateStr = date(date, property, context).extended(true).write(); - element.append(ICalDataType.DATE_TIME, dateStr); - return; - } - - element.append(defaultDataType(context.getVersion()), ""); - } - - @Override - protected Trigger _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - String value = element.first(ICalDataType.DURATION); - if (value != null) { - try { - return new Trigger(Duration.parse(value), parameters.getRelated()); - } catch (IllegalArgumentException e) { - throw new CannotParseException(26, value); - } - } - - value = element.first(ICalDataType.DATE_TIME); - if (value != null) { - try { - ICalDate date = date(value).parse(); - Trigger property = new Trigger(date); - context.addDate(date, property, parameters); - return property; - } catch (IllegalArgumentException e) { - throw new CannotParseException(27, value); - } - } - - throw missingXmlElements(ICalDataType.DURATION, ICalDataType.DATE_TIME); - } - - @Override - protected JCalValue _writeJson(Trigger property, WriteContext context) { - Duration duration = property.getDuration(); - if (duration != null) { - return JCalValue.single(duration.toString()); - } - - Date date = property.getDate(); - if (date != null) { - String dateStr = date(date, property, context).extended(true).write(); - return JCalValue.single(dateStr); - } - - return JCalValue.single(""); - } - - @Override - protected Trigger _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - String valueStr = value.asSingle(); - - try { - ICalDate date = date(valueStr).parse(); - Trigger property = new Trigger(date); - context.addDate(date, property, parameters); - return property; - } catch (IllegalArgumentException e) { - //must be a duration - } - - try { - return new Trigger(Duration.parse(valueStr), parameters.getRelated()); - } catch (IllegalArgumentException e) { - throw new CannotParseException(25); - } - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/UidScribe.java b/app/src/main/java/biweekly/io/scribe/property/UidScribe.java deleted file mode 100644 index b20e71c2ef..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/UidScribe.java +++ /dev/null @@ -1,44 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalVersion; -import biweekly.property.Uid; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Uid} properties. - * @author Michael Angstadt - */ -public class UidScribe extends TextPropertyScribe { - public UidScribe() { - super(Uid.class, "UID"); - } - - @Override - protected Uid newInstance(String value, ICalVersion version) { - return new Uid(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/UrlScribe.java b/app/src/main/java/biweekly/io/scribe/property/UrlScribe.java deleted file mode 100644 index 848ffbcfd9..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/UrlScribe.java +++ /dev/null @@ -1,45 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.property.Url; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Url} properties. - * @author Michael Angstadt - */ -public class UrlScribe extends TextPropertyScribe { - public UrlScribe() { - super(Url.class, "URL", ICalDataType.URI); - } - - @Override - protected Url newInstance(String value, ICalVersion version) { - return new Url(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/UtcOffsetPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/UtcOffsetPropertyScribe.java deleted file mode 100644 index 4b7086cd78..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/UtcOffsetPropertyScribe.java +++ /dev/null @@ -1,117 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.UtcOffsetProperty; -import biweekly.util.UtcOffset; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals properties that have UTC offset values. - * @param the property class - * @author Michael Angstadt - */ -public abstract class UtcOffsetPropertyScribe extends ICalPropertyScribe { - public UtcOffsetPropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName, ICalDataType.UTC_OFFSET); - } - - @Override - protected String _writeText(T property, WriteContext context) { - UtcOffset offset = property.getValue(); - if (offset != null) { - return offset.toString(false); - } - - return ""; - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - return parse(value); - } - - @Override - protected void _writeXml(T property, XCalElement element, WriteContext context) { - String offsetStr = null; - - UtcOffset offset = property.getValue(); - if (offset != null) { - offsetStr = offset.toString(true); - } - - element.append(dataType(property, null), offsetStr); - } - - @Override - protected T _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return parse(value); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(T property, WriteContext context) { - UtcOffset offset = property.getValue(); - if (offset != null) { - return JCalValue.single(offset.toString(true)); - } - - return JCalValue.single(""); - } - - @Override - protected T _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(value.asSingle()); - } - - protected abstract T newInstance(UtcOffset offset); - - private T parse(String value) { - if (value == null) { - return newInstance(null); - } - - try { - return newInstance(UtcOffset.parse(value)); - } catch (IllegalArgumentException e) { - throw new CannotParseException(28); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/VCalAlarmPropertyScribe.java b/app/src/main/java/biweekly/io/scribe/property/VCalAlarmPropertyScribe.java deleted file mode 100644 index 3efbf4b732..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/VCalAlarmPropertyScribe.java +++ /dev/null @@ -1,190 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.ArrayList; -import java.util.Date; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.component.VAlarm; -import biweekly.io.CannotParseException; -import biweekly.io.DataModelConversionException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.parameter.ICalParameters; -import biweekly.property.Action; -import biweekly.property.Trigger; -import biweekly.property.VCalAlarmProperty; -import biweekly.util.Duration; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link VCalAlarmProperty} properties. - * @author Michael Angstadt - */ -public abstract class VCalAlarmPropertyScribe extends ICalPropertyScribe { - public VCalAlarmPropertyScribe(Class clazz, String propertyName) { - super(clazz, propertyName); - } - - public VCalAlarmPropertyScribe(Class clazz, String propertyName, ICalDataType defaultDataType) { - super(clazz, propertyName, defaultDataType); - } - - @Override - protected String _writeText(T property, WriteContext context) { - List values = new ArrayList(); - - Date start = property.getStart(); - String value = date(start, property, context).extended(false).write(); - values.add(value); - - Duration snooze = property.getSnooze(); - value = (snooze == null) ? "" : snooze.toString(); - values.add(value); - - Integer repeat = property.getRepeat(); - value = (repeat == null) ? "" : repeat.toString(); - values.add(value); - - List dataValues = writeData(property); - values.addAll(dataValues); - - boolean escapeCommas = (context.getVersion() != ICalVersion.V1_0); - return VObjectPropertyValues.writeSemiStructured(values, escapeCommas, true); - } - - @Override - protected T _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - SemiStructuredValueIterator it = new SemiStructuredValueIterator(value); - - String next = next(it); - Date start; - try { - start = (next == null) ? null : date(next).parse(); - } catch (IllegalArgumentException e) { - throw new CannotParseException(27, next); - } - - next = next(it); - Duration snooze; - try { - snooze = (next == null) ? null : Duration.parse(next); - } catch (IllegalArgumentException e) { - throw new CannotParseException(26, next); - } - - next = next(it); - Integer repeat; - try { - repeat = (next == null) ? null : Integer.valueOf(next); - } catch (IllegalArgumentException e) { - throw new CannotParseException(24, next); - } - - T property = create(dataType, it); - property.setStart(start); - property.setSnooze(snooze); - property.setRepeat(repeat); - property.setParameters(parameters); - - DataModelConversionException conversionException = new DataModelConversionException(property); - VAlarm valarm = toVAlarm(property); - conversionException.getComponents().add(valarm); - throw conversionException; - } - - private String next(SemiStructuredValueIterator it) { - String next = it.next(); - if (next == null) { - return null; - } - - next = next.trim(); - return next.isEmpty() ? null : next; - } - - /** - * Converts an instance of a vCal alarm property into a {@link VAlarm} - * component. - * @param property the property to convert - * @return the component - */ - protected VAlarm toVAlarm(T property) { - Trigger trigger = new Trigger(property.getStart()); - VAlarm valarm = new VAlarm(action(), trigger); - valarm.setDuration(property.getSnooze()); - valarm.setRepeat(property.getRepeat()); - - toVAlarm(valarm, property); - return valarm; - } - - /** - * Generates the part of the property value that will be included after the - * part of the value that is common to all vCal alarm properties. - * @param property the property - * @return the values - */ - protected abstract List writeData(T property); - - /** - * Creates a new instance of the property and populates it with the portion - * of data that is specific to this vCal alarm property. - * @param dataType the data type - * @param it an iterator to the property value that is positioned at the - * "value" portion of the property value (after the values that are common - * to all vCal alarm properties) - * @return the new property - */ - protected abstract T create(ICalDataType dataType, SemiStructuredValueIterator it); - - /** - * Determines what kind of {@link Action} property this vCal alarm property - * maps to, and returns a new instance of this property. - * @return a new {@link Action} property - */ - protected abstract Action action(); - - /** - * Populates a {@link VAlarm} component with data that is unique to this - * specific kind of vCal alarm property. - * @param valarm the component - * @param property the property - */ - protected abstract void toVAlarm(VAlarm valarm, T property); - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V1_0); - } -} diff --git a/app/src/main/java/biweekly/io/scribe/property/VersionScribe.java b/app/src/main/java/biweekly/io/scribe/property/VersionScribe.java deleted file mode 100644 index e1be661dd4..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/VersionScribe.java +++ /dev/null @@ -1,118 +0,0 @@ -package biweekly.io.scribe.property; - -import biweekly.ICalDataType; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.parameter.ICalParameters; -import biweekly.property.Version; -import biweekly.util.VersionNumber; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues.SemiStructuredValueIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Version} properties. - * @author Michael Angstadt - */ -public class VersionScribe extends ICalPropertyScribe { - public VersionScribe() { - super(Version.class, "VERSION", ICalDataType.TEXT); - } - - @Override - protected String _writeText(Version property, WriteContext context) { - StringBuilder sb = new StringBuilder(); - - if (property.getMinVersion() != null) { - sb.append(property.getMinVersion()).append(';'); - } - if (property.getMaxVersion() != null) { - sb.append(property.getMaxVersion()); - } - - return sb.toString(); - } - - @Override - protected Version _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - SemiStructuredValueIterator it = new SemiStructuredValueIterator(value); - String one = it.next(); - String two = it.next(); - - String min = null; - String max; - if (two == null) { - max = one; - } else { - min = one; - max = two; - } - - return parse(min, max); - } - - @Override - protected void _writeXml(Version property, XCalElement element, WriteContext context) { - VersionNumber max = property.getMaxVersion(); - String value = (max == null) ? null : max.toString(); - element.append(dataType(property, null), value); - } - - @Override - protected Version _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - ICalDataType dataType = defaultDataType(context.getVersion()); - String value = element.first(dataType); - if (value != null) { - return parse(null, value); - } - - throw missingXmlElements(dataType); - } - - @Override - protected JCalValue _writeJson(Version property, WriteContext context) { - VersionNumber max = property.getMaxVersion(); - String value = (max == null) ? null : max.toString(); - return JCalValue.single(value); - } - - @Override - protected Version _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - return parse(null, value.asSingle()); - } - - private Version parse(String min, String max) { - try { - return new Version(min, max); - } catch (IllegalArgumentException e) { - throw new CannotParseException(30); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/XmlScribe.java b/app/src/main/java/biweekly/io/scribe/property/XmlScribe.java deleted file mode 100644 index 8780aac419..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/XmlScribe.java +++ /dev/null @@ -1,139 +0,0 @@ -package biweekly.io.scribe.property; - -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.xml.transform.OutputKeys; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.WriteContext; -import biweekly.io.json.JCalValue; -import biweekly.io.xml.XCalElement; -import biweekly.io.xml.XCalNamespaceContext; -import biweekly.parameter.ICalParameters; -import biweekly.property.Xml; -import biweekly.util.XmlUtils; - -import com.github.mangstadt.vinnie.io.VObjectPropertyValues; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Marshals {@link Xml} properties. - * @author Michael Angstadt - */ -public class XmlScribe extends ICalPropertyScribe { - //TODO on writing to plain text: convert to base64 if the string contains values that are illegal within a plain text value (p.17) - public XmlScribe() { - super(Xml.class, "XML", ICalDataType.TEXT); - } - - @Override - protected String _writeText(Xml property, WriteContext context) { - Document value = property.getValue(); - if (value != null) { - String xml = valueToString(value); - return VObjectPropertyValues.escape(xml); - } - - return ""; - } - - @Override - protected Xml _parseText(String value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - value = VObjectPropertyValues.unescape(value); - try { - return new Xml(value); - } catch (SAXException e) { - throw new CannotParseException(29); - } - } - - @Override - protected void _writeXml(Xml property, XCalElement element, WriteContext context) { - /* - * Note: Xml properties are handled as a special case when writing xCal - * documents, so this method should never get called. - */ - super._writeXml(property, element, context); - } - - @Override - protected Xml _parseXml(XCalElement element, ICalParameters parameters, ParseContext context) { - Xml xml = new Xml(element.getElement()); - - //remove the element - Element root = xml.getValue().getDocumentElement(); - for (Element child : XmlUtils.toElementList(root.getChildNodes())) { - if ("parameters".equals(child.getLocalName()) && XCalNamespaceContext.XCAL_NS.equals(child.getNamespaceURI())) { - root.removeChild(child); - } - } - - return xml; - } - - @Override - protected JCalValue _writeJson(Xml property, WriteContext context) { - Document value = property.getValue(); - if (value != null) { - String xml = valueToString(value); - return JCalValue.single(xml); - } - - return JCalValue.single(""); - } - - @Override - protected Xml _parseJson(JCalValue value, ICalDataType dataType, ICalParameters parameters, ParseContext context) { - try { - String xml = value.asSingle(); - return new Xml(xml); - } catch (SAXException e) { - throw new CannotParseException(29); - } - } - - private String valueToString(Document document) { - Map props = new HashMap(); - props.put(OutputKeys.OMIT_XML_DECLARATION, "yes"); - return XmlUtils.toString(document, props); - } - - @Override - public Set getSupportedVersions() { - return EnumSet.of(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/scribe/property/package-info.java b/app/src/main/java/biweekly/io/scribe/property/package-info.java deleted file mode 100644 index 96b06cda15..0000000000 --- a/app/src/main/java/biweekly/io/scribe/property/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes that marshal and unmarshal properties in various formats. - */ -package biweekly.io.scribe.property; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/text/ICalReader.java b/app/src/main/java/biweekly/io/text/ICalReader.java deleted file mode 100644 index de642667d9..0000000000 --- a/app/src/main/java/biweekly/io/text/ICalReader.java +++ /dev/null @@ -1,487 +0,0 @@ -package biweekly.io.text; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.CannotParseException; -import biweekly.io.DataModelConversionException; -import biweekly.io.ParseWarning; -import biweekly.io.SkipMeException; -import biweekly.io.StreamReader; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.io.scribe.property.RawPropertyScribe; -import biweekly.parameter.Encoding; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.util.Utf8Reader; - -import com.github.mangstadt.vinnie.VObjectProperty; -import com.github.mangstadt.vinnie.io.Context; -import com.github.mangstadt.vinnie.io.SyntaxRules; -import com.github.mangstadt.vinnie.io.VObjectDataListener; -import com.github.mangstadt.vinnie.io.VObjectReader; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Parses {@link ICalendar} objects from a plain-text iCalendar data stream. - *

- *

- * Example: - *

- * - *
- * File file = new File("icals.ics");
- * ICalReader reader = null;
- * try {
- *   reader = new ICalReader(file);
- *   ICalendar ical;
- *   while ((ical = reader.readNext()) != null) {
- *     //...
- *   }
- * } finally {
- *   if (reader != null) reader.close();
- * }
- * 
- * @author Michael Angstadt - * @see 1.0 specs - * @see RFC 2445 - * @see RFC 5545 - */ -public class ICalReader extends StreamReader { - private static final String VCALENDAR_COMPONENT_NAME = ScribeIndex.getICalendarScribe().getComponentName(); //"VCALENDAR" - - private final VObjectReader reader; - private final ICalVersion defaultVersion; - - /** - * Creates a new iCalendar reader. - * @param str the string to read from - */ - public ICalReader(String str) { - this(str, ICalVersion.V2_0); - } - - /** - * Creates a new iCalendar reader. - * @param str the string to read from - * @param defaultVersion the version to assume the iCalendar object is in - * until a VERSION property is encountered (defaults to 2.0) - */ - public ICalReader(String str, ICalVersion defaultVersion) { - this(new StringReader(str), defaultVersion); - } - - /** - * Creates a new iCalendar reader. - * @param in the input stream to read from - */ - public ICalReader(InputStream in) { - this(in, ICalVersion.V2_0); - } - - /** - * Creates a new iCalendar reader. - * @param defaultVersion the version to assume the iCalendar object is in - * until a VERSION property is encountered (defaults to 2.0) - * @param in the input stream to read from - */ - public ICalReader(InputStream in, ICalVersion defaultVersion) { - this(new Utf8Reader(in), defaultVersion); - } - - /** - * Creates a new iCalendar reader. - * @param file the file to read from - * @throws FileNotFoundException if the file doesn't exist - */ - public ICalReader(File file) throws FileNotFoundException { - this(file, ICalVersion.V2_0); - } - - /** - * Creates a new iCalendar reader. - * @param file the file to read from - * @param defaultVersion the version to assume the iCalendar object is in - * until a VERSION property is encountered (defaults to 2.0) - * @throws FileNotFoundException if the file doesn't exist - */ - public ICalReader(File file, ICalVersion defaultVersion) throws FileNotFoundException { - this(new BufferedReader(new Utf8Reader(file)), defaultVersion); - } - - /** - * Creates a new iCalendar reader. - * @param reader the reader to read from - */ - public ICalReader(Reader reader) { - this(reader, ICalVersion.V2_0); - } - - /** - * Creates a new iCalendar reader. - * @param reader the reader to read from - * @param defaultVersion the version to assume the iCalendar object is in - * until a VERSION property is encountered (defaults to 2.0) - */ - public ICalReader(Reader reader, ICalVersion defaultVersion) { - SyntaxRules rules = SyntaxRules.iCalendar(); - rules.setDefaultSyntaxStyle(defaultVersion.getSyntaxStyle()); - this.reader = new VObjectReader(reader, rules); - this.defaultVersion = defaultVersion; - } - - /** - * Gets whether the reader will decode parameter values that use circumflex - * accent encoding (enabled by default). This escaping mechanism allows - * newlines and double quotes to be included in parameter values. - * @return true if circumflex accent decoding is enabled, false if not - * @see VObjectReader#isCaretDecodingEnabled() - */ - public boolean isCaretDecodingEnabled() { - return reader.isCaretDecodingEnabled(); - } - - /** - * Sets whether the reader will decode parameter values that use circumflex - * accent encoding (enabled by default). This escaping mechanism allows - * newlines and double quotes to be included in parameter values. This only - * applies to version 2.0 iCalendar objects. - * @param enable true to use circumflex accent decoding, false not to - * @see VObjectReader#setCaretDecodingEnabled(boolean) - */ - public void setCaretDecodingEnabled(boolean enable) { - reader.setCaretDecodingEnabled(enable); - } - - /** - *

- * Gets the character set to use when decoding quoted-printable values if - * the property has no CHARSET parameter, or if the CHARSET parameter is not - * a valid character set. - *

- *

- * By default, the Reader's character encoding will be used. If the Reader - * has no character encoding, then the system's default character encoding - * will be used. - *

- * @return the character set - */ - public Charset getDefaultQuotedPrintableCharset() { - return reader.getDefaultQuotedPrintableCharset(); - } - - /** - *

- * Sets the character set to use when decoding quoted-printable values if - * the property has no CHARSET parameter, or if the CHARSET parameter is not - * a valid character set. - *

- *

- * By default, the Reader's character encoding will be used. If the Reader - * has no character encoding, then the system's default character encoding - * will be used. - *

- * @param charset the character set - */ - public void setDefaultQuotedPrintableCharset(Charset charset) { - reader.setDefaultQuotedPrintableCharset(charset); - } - - /** - *

- * Gets the iCalendar version that this reader will assume each iCalendar - * object is formatted in up until a VERSION property is encountered. - *

- *

- * All standards-compliant iCalendar objects contain a VERSION property at - * the very beginning of the object, so for the vast majority of iCalendar - * objects, this setting does nothing. This setting is needed for when the - * iCalendar object does not have a VERSION property or for when the VERSION - * property is not located at the beginning of the object. - *

- * @return the default version (defaults to "2.0") - */ - public ICalVersion getDefaultVersion() { - return defaultVersion; - } - - @Override - protected ICalendar _readNext() throws IOException { - VObjectDataListenerImpl listener = new VObjectDataListenerImpl(); - reader.parse(listener); - return listener.ical; - } - - private class VObjectDataListenerImpl implements VObjectDataListener { - private ICalendar ical = null; - private ICalVersion version = defaultVersion; - private ComponentStack stack = new ComponentStack(); - - public void onComponentBegin(String name, Context vobjectContext) { - //ignore everything until a VCALENDAR component is read - if (ical == null && !isVCalendarComponent(name)) { - return; - } - - ICalComponent parentComponent = stack.peek(); - - ICalComponentScribe scribe = index.getComponentScribe(name, version); - ICalComponent component = scribe.emptyInstance(); - stack.push(component); - - if (parentComponent == null) { - ical = (ICalendar) component; - context.setVersion(version); - } else { - parentComponent.addComponent(component); - } - } - - public void onComponentEnd(String name, Context vobjectContext) { - //VCALENDAR component not read yet, ignore - if (ical == null) { - return; - } - - /* - * VObjectDataListener guarantees correct ordering of component - * begin/end callback invocations (see javadocs), so we can pop - * blindly without checking if the component name matches. - */ - stack.pop(); - - //stop reading when "END:VCALENDAR" is reached - if (stack.isEmpty()) { - vobjectContext.stop(); - } - } - - public void onProperty(VObjectProperty vobjectProperty, Context vobjectContext) { - //VCALENDAR component not read yet, ignore - if (ical == null) { - return; - } - - String propertyName = vobjectProperty.getName(); - ICalParameters parameters = new ICalParameters(vobjectProperty.getParameters().getMap()); - String value = vobjectProperty.getValue(); - - context.getWarnings().clear(); - context.setLineNumber(vobjectContext.getLineNumber()); - context.setPropertyName(propertyName); - - ICalPropertyScribe scribe = index.getPropertyScribe(propertyName, version); - - //process nameless parameters - processNamelessParameters(parameters, version); - - //get the data type (VALUE parameter) - ICalDataType dataType = parameters.getValue(); - parameters.setValue(null); - if (dataType == null) { - //use the property's default data type if there is no VALUE parameter - dataType = scribe.defaultDataType(version); - } - - ICalComponent parentComponent = stack.peek(); - try { - ICalProperty property = scribe.parseText(value, dataType, parameters, context); - parentComponent.addProperty(property); - } catch (SkipMeException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(0, e.getMessage()) - .build() - ); - //@formatter:on - } catch (CannotParseException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(e) - .build() - ); - //@formatter:on - ICalProperty property = new RawPropertyScribe(propertyName).parseText(value, dataType, parameters, context); - parentComponent.addProperty(property); - } catch (DataModelConversionException e) { - for (ICalProperty property : e.getProperties()) { - parentComponent.addProperty(property); - } - for (ICalComponent component : e.getComponents()) { - parentComponent.addComponent(component); - } - } - - warnings.addAll(context.getWarnings()); - } - - public void onVersion(String value, Context vobjectContext) { - //ignore if we are not directly under the root VCALENDAR component - if (stack.size() != 1) { - return; - } - - version = ICalVersion.get(value); - context.setVersion(version); - } - - public void onWarning(com.github.mangstadt.vinnie.io.Warning warning, VObjectProperty property, Exception thrown, Context vobjectContext) { - //VCALENDAR component not read yet, ignore - if (ical == null) { - return; - } - - //@formatter:off - warnings.add(new ParseWarning.Builder() - .lineNumber(vobjectContext.getLineNumber()) - .propertyName((property == null) ? null : property.getName()) - .message(warning.getMessage()) - .build() - ); - //@formatter:on - } - - private boolean isVCalendarComponent(String componentName) { - return VCALENDAR_COMPONENT_NAME.equals(componentName); - } - - /** - * Assigns names to all nameless parameters. v2.0 requires all - * parameters to have names, but v1.0 does not. - * @param parameters the parameters - * @param version the iCal version - */ - private void processNamelessParameters(ICalParameters parameters, ICalVersion version) { - List namelessParamValues = parameters.removeAll(null); - if (namelessParamValues.isEmpty()) { - return; - } - - if (version != ICalVersion.V1_0) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(4, namelessParamValues) - .build() - ); - //@formatter:on - } - - for (String paramValue : namelessParamValues) { - String paramName = guessParameterName(paramValue); - parameters.put(paramName, paramValue); - } - } - - /** - * Makes a guess as to what a parameter value's name should be. - * @param value the parameter value - * @return the guessed name - */ - private String guessParameterName(String value) { - if (ICalDataType.find(value) != null) { - return ICalParameters.VALUE; - } - - if (Encoding.find(value) != null) { - return ICalParameters.ENCODING; - } - - //otherwise, assume it's a TYPE - return ICalParameters.TYPE; - } - } - - /** - * Keeps track of the hierarchy of nested components. - */ - private static class ComponentStack { - private final List components = new ArrayList(); - - /** - * Gets the top component from the stack. - * @return the component or null if the stack is empty - */ - public ICalComponent peek() { - return isEmpty() ? null : components.get(components.size() - 1); - } - - /** - * Adds a component to the stack - * @param component the component - */ - public void push(ICalComponent component) { - components.add(component); - } - - /** - * Removes the top component from the stack and returns it. - * @return the top component or null if the stack is empty - */ - public ICalComponent pop() { - return isEmpty() ? null : components.remove(components.size() - 1); - } - - /** - * Determines if the stack is empty. - * @return true if it's empty, false if not - */ - public boolean isEmpty() { - return components.isEmpty(); - } - - /** - * Gets the size of the stack. - * @return the size - */ - public int size() { - return components.size(); - } - } - - /** - * Closes the input stream. - * @throws IOException if there's a problem closing the input stream - */ - public void close() throws IOException { - reader.close(); - } -} diff --git a/app/src/main/java/biweekly/io/text/ICalWriter.java b/app/src/main/java/biweekly/io/text/ICalWriter.java deleted file mode 100644 index ea075a690c..0000000000 --- a/app/src/main/java/biweekly/io/text/ICalWriter.java +++ /dev/null @@ -1,345 +0,0 @@ -package biweekly.io.text; - -import static biweekly.io.DataModelConverter.convert; - -import java.io.File; -import java.io.FileWriter; -import java.io.Flushable; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Collection; -import java.util.List; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.component.VTimezone; -import biweekly.io.DataModelConversionException; -import biweekly.io.DataModelConverter.VCalTimezoneProperties; -import biweekly.io.SkipMeException; -import biweekly.io.StreamWriter; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.parameter.ICalParameters; -import biweekly.property.Daylight; -import biweekly.property.ICalProperty; -import biweekly.property.Timezone; -import biweekly.property.Version; -import biweekly.util.Utf8Writer; - -import com.github.mangstadt.vinnie.VObjectParameters; -import com.github.mangstadt.vinnie.io.VObjectWriter; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Writes {@link ICalendar} objects to a plain-text iCalendar data stream. - *

- *

- * Example: - *

- * - *
- * ICalendar ical1 = ...
- * ICalendar ical2 = ...
- * File file = new File("icals.ics");
- * ICalWriter writer = null;
- * try {
- *   writer = new ICalWriter(file, ICalVersion.V2_0);
- *   writer.write(ical1);
- *   writer.write(ical2);
- * } finally {
- *   if (writer != null) writer.close();
- * }
- * 
- * - *

- * Changing the line folding settings: - *

- * - *
- * ICalWriter writer = new ICalWriter(...);
- * 
- * //disable line folding
- * writer.getVObjectWriter().getFoldedLineWriter().setLineLength(null);
- * 
- * //set line length (defaults to 75)
- * writer.getVObjectWriter().getFoldedLineWriter().setLineLength(50);
- * 
- * //change folded line indent string (defaults to one space character)
- * writer.getVObjectWriter().getFoldedLineWriter().setIndent("\t");
- *
- * 
- * @author Michael Angstadt - * @see 1.0 specs - * @see RFC 2445 - * @see RFC 5545 - */ -public class ICalWriter extends StreamWriter implements Flushable { - private final VObjectWriter writer; - private ICalVersion targetVersion; - - /** - * Creates a new iCalendar writer. - * @param out the output stream to write to - * @param targetVersion the iCalendar version to adhere to - */ - public ICalWriter(OutputStream out, ICalVersion targetVersion) { - this((targetVersion == ICalVersion.V1_0) ? new OutputStreamWriter(out) : new Utf8Writer(out), targetVersion); - } - - /** - * Creates a new iCalendar writer. - * @param file the file to write to - * @param targetVersion the iCalendar version to adhere to - * @throws IOException if the file cannot be written to - */ - public ICalWriter(File file, ICalVersion targetVersion) throws IOException { - this(file, false, targetVersion); - } - - /** - * Creates a new iCalendar writer. - * @param file the file to write to - * @param targetVersion the iCalendar version to adhere to - * @param append true to append to the end of the file, false to overwrite - * it - * @throws IOException if the file cannot be written to - */ - public ICalWriter(File file, boolean append, ICalVersion targetVersion) throws IOException { - this((targetVersion == ICalVersion.V1_0) ? new FileWriter(file, append) : new Utf8Writer(file, append), targetVersion); - } - - /** - * Creates a new iCalendar writer. - * @param writer the writer to write to - * @param targetVersion the iCalendar version to adhere to - */ - public ICalWriter(Writer writer, ICalVersion targetVersion) { - this.writer = new VObjectWriter(writer, targetVersion.getSyntaxStyle()); - this.targetVersion = targetVersion; - } - - /** - * Gets the writer object that is used internally to write to the output - * stream. - * @return the raw writer - */ - public VObjectWriter getVObjectWriter() { - return writer; - } - - /** - * Gets the version that the written iCalendar objects will adhere to. - * @return the iCalendar version - */ - @Override - public ICalVersion getTargetVersion() { - return targetVersion; - } - - /** - * Sets the version that the written iCalendar objects will adhere to. - * @param targetVersion the iCalendar version - */ - public void setTargetVersion(ICalVersion targetVersion) { - this.targetVersion = targetVersion; - writer.setSyntaxStyle(targetVersion.getSyntaxStyle()); - } - - /** - *

- * Gets whether the writer will apply circumflex accent encoding on - * parameter values (disabled by default). This escaping mechanism allows - * for newlines and double quotes to be included in parameter values. It is - * only supported by iCalendar version 2.0. - *

- * @return true if circumflex accent encoding is enabled, false if not - * @see VObjectWriter#isCaretEncodingEnabled() - */ - public boolean isCaretEncodingEnabled() { - return writer.isCaretEncodingEnabled(); - } - - /** - *

- * Sets whether the writer will apply circumflex accent encoding on - * parameter values (disabled by default). This escaping mechanism allows - * for newlines and double quotes to be included in parameter values. It is - * only supported by iCalendar version 2.0. - *

- *

- * Note that this encoding mechanism is defined separately from the - * iCalendar specification and may not be supported by the consumer of the - * iCalendar object. - *

- * @param enable true to use circumflex accent encoding, false not to - * @see VObjectWriter#setCaretEncodingEnabled(boolean) - */ - public void setCaretEncodingEnabled(boolean enable) { - writer.setCaretEncodingEnabled(enable); - } - - @Override - protected void _write(ICalendar ical) throws IOException { - writeComponent(ical, null); - } - - /** - * Writes a component to the data stream. - * @param component the component to write - * @param parent the parent component - * @throws IOException if there's a problem writing to the data stream - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void writeComponent(ICalComponent component, ICalComponent parent) throws IOException { - boolean inICalendar = component instanceof ICalendar; - boolean inVCalRoot = inICalendar && getTargetVersion() == ICalVersion.V1_0; - boolean inICalRoot = inICalendar && getTargetVersion() != ICalVersion.V1_0; - - ICalComponentScribe componentScribe = index.getComponentScribe(component); - try { - componentScribe.checkForDataModelConversions(component, parent, getTargetVersion()); - } catch (DataModelConversionException e) { - for (ICalComponent c : e.getComponents()) { - writeComponent(c, parent); - } - for (ICalProperty p : e.getProperties()) { - writeProperty(p); - } - return; - } - - writer.writeBeginComponent(componentScribe.getComponentName()); - - List propertyObjs = componentScribe.getProperties(component); - if (inICalendar && component.getProperty(Version.class) == null) { - propertyObjs.add(0, new Version(getTargetVersion())); - } - - for (Object propertyObj : propertyObjs) { - context.setParent(component); //set parent here incase a scribe resets the parent - ICalProperty property = (ICalProperty) propertyObj; - writeProperty(property); - } - - List subComponents = componentScribe.getComponents(component); - if (inICalRoot) { - //add the VTIMEZONE components - Collection timezones = getTimezoneComponents(); - for (VTimezone timezone : timezones) { - if (!subComponents.contains(timezone)) { - subComponents.add(0, timezone); - } - } - } - - for (Object subComponentObj : subComponents) { - ICalComponent subComponent = (ICalComponent) subComponentObj; - writeComponent(subComponent, component); - } - - if (inVCalRoot) { - Collection timezones = getTimezoneComponents(); - if (!timezones.isEmpty()) { - VTimezone timezone = timezones.iterator().next(); - VCalTimezoneProperties props = convert(timezone, context.getDates()); - - Timezone tz = props.getTz(); - if (tz != null) { - writeProperty(tz); - } - for (Daylight daylight : props.getDaylights()) { - writeProperty(daylight); - } - } - } - - writer.writeEndComponent(componentScribe.getComponentName()); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void writeProperty(ICalProperty property) throws IOException { - ICalPropertyScribe scribe = index.getPropertyScribe(property); - - //marshal property - String value; - try { - value = scribe.writeText(property, context); - } catch (SkipMeException e) { - return; - } catch (DataModelConversionException e) { - for (ICalComponent c : e.getComponents()) { - writeComponent(c, context.getParent()); - } - for (ICalProperty p : e.getProperties()) { - writeProperty(p); - } - return; - } - - //get parameters - ICalParameters parameters = scribe.prepareParameters(property, context); - - /* - * Set the property's data type. - * - * Only add a VALUE parameter if the data type is: (1) not "unknown" (2) - * different from the property's default data type - */ - ICalDataType dataType = scribe.dataType(property, targetVersion); - if (dataType != null && dataType != scribe.defaultDataType(targetVersion)) { - parameters = new ICalParameters(parameters); - parameters.setValue(dataType); - } - - //get the property name - String propertyName = scribe.getPropertyName(getTargetVersion()); - - //write property to data stream - writer.writeProperty(null, propertyName, new VObjectParameters(parameters.getMap()), value); - } - - /** - * Flushes the output stream. - * @throws IOException if there's a problem flushing the output stream - */ - public void flush() throws IOException { - writer.flush(); - } - - /** - * Closes the output stream. - * @throws IOException if there's a problem closing the output stream - */ - public void close() throws IOException { - writer.close(); - } -} diff --git a/app/src/main/java/biweekly/io/text/package-info.java b/app/src/main/java/biweekly/io/text/package-info.java deleted file mode 100644 index 725dcfdb36..0000000000 --- a/app/src/main/java/biweekly/io/text/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes for reading and writing traditional, plain-text iCalendar objects. - */ -package biweekly.io.text; \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/xml/XCalDocument.java b/app/src/main/java/biweekly/io/xml/XCalDocument.java deleted file mode 100644 index 58e23e5ad0..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalDocument.java +++ /dev/null @@ -1,791 +0,0 @@ -package biweekly.io.xml; - -import static biweekly.io.xml.XCalNamespaceContext.XCAL_NS; -import static biweekly.io.xml.XCalQNames.COMPONENTS; -import static biweekly.io.xml.XCalQNames.ICALENDAR; -import static biweekly.io.xml.XCalQNames.PARAMETERS; -import static biweekly.io.xml.XCalQNames.PROPERTIES; -import static biweekly.io.xml.XCalQNames.VCALENDAR; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.XMLConstants; -import javax.xml.namespace.QName; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.component.VTimezone; -import biweekly.io.CannotParseException; -import biweekly.io.ParseWarning; -import biweekly.io.SkipMeException; -import biweekly.io.StreamReader; -import biweekly.io.StreamWriter; -import biweekly.io.scribe.ScribeIndex; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.component.ICalendarScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.property.Version; -import biweekly.property.Xml; -import biweekly.util.Utf8Writer; -import biweekly.util.XmlUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//@formatter:off -/** - *

- * Represents an XML document that contains iCalendar objects ("xCal" standard). - * This class can be used to read and write xCal documents. - *

- *

- * Examples: - *

- * - *
- * String xml =
- * "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
- * "<icalendar xmlns=\"urn:ietf:params:xml:ns:icalendar-2.0\">" +
- *   "<vcalendar>" +
- *     "<properties>" +
- *       "<prodid><text>-//Example Inc.//Example Client//EN</text></prodid>" +
- *       "<version><text>2.0</text></version>" +
- *     "</properties>" +
- *     "<components>" +
- *       "<vevent>" +
- *         "<properties>" +
- *           "<dtstart><date-time>2013-06-27T13:00:00Z</date-time></dtstart>" +
- *           "<dtend><date-time>2013-06-27T15:00:00Z</date-time></dtend>" +
- *           "<summary><text>Team Meeting</text></summary>" +
- *         "</properties>" +
- *       "</vevent>" +
- *     "</components>" +
- *   "</vcalendar>" +
- * "</icalendar>";
- *     
- * //parsing an existing xCal document
- * XCalDocument xcal = new XCalDocument(xml);
- * List<ICalendar> icals = xcal.getICalendars();
- * 
- * //creating an empty xCal document
- * XCalDocument xcal = new XCalDocument();
- * 
- * //ICalendar objects can be added at any time
- * ICalendar ical = new ICalendar();
- * xcal.addICalendar(ical);
- * 
- * //retrieving the raw XML DOM
- * Document document = xcal.getDocument();
- * 
- * //call one of the "write()" methods to output the xCal document
- * File file = new File("meeting.xml");
- * xcal.write(file);
- * 
- * @author Michael Angstadt - * @see RFC 6321 - */ -//@formatter:on -public class XCalDocument { - private static final ICalendarScribe icalMarshaller = ScribeIndex.getICalendarScribe(); - private static final XCalNamespaceContext nsContext = new XCalNamespaceContext("xcal"); - - private final Document document; - private Element icalendarRootElement; - - /** - * Parses an xCal document from a string. - * @param xml the xCal document in the form of a string - * @throws SAXException if there's a problem parsing the XML - */ - public XCalDocument(String xml) throws SAXException { - this(XmlUtils.toDocument(xml)); - } - - /** - * Parses an xCal document from an input stream. - * @param in the input stream to read the the xCal document from - * @throws IOException if there's a problem reading from the input stream - * @throws SAXException if there's a problem parsing the XML - */ - public XCalDocument(InputStream in) throws SAXException, IOException { - this(XmlUtils.toDocument(in)); - } - - /** - * Parses an xCal document from a file. - * @param file the file containing the xCal document - * @throws IOException if there's a problem reading from the file - * @throws SAXException if there's a problem parsing the XML - */ - public XCalDocument(File file) throws SAXException, IOException { - this(XmlUtils.toDocument(file)); - } - - /** - *

- * Parses an xCal document from a reader. - *

- *

- * Note that use of this constructor is discouraged. It ignores the - * character encoding that is defined within the XML document itself, and - * should only be used if the encoding is undefined or if the encoding needs - * to be ignored for whatever reason. The {@link #XCalDocument(InputStream)} - * constructor should be used instead, since it takes the XML document's - * character encoding into account when parsing. - *

- * @param reader the reader to read the xCal document from - * @throws IOException if there's a problem reading from the reader - * @throws SAXException if there's a problem parsing the XML - */ - public XCalDocument(Reader reader) throws SAXException, IOException { - this(XmlUtils.toDocument(reader)); - } - - /** - * Wraps an existing XML DOM object. - * @param document the XML DOM that contains the xCal document - */ - public XCalDocument(Document document) { - this.document = document; - - XPath xpath = XPathFactory.newInstance().newXPath(); - xpath.setNamespaceContext(nsContext); - - try { - //find the element - String prefix = nsContext.getPrefix(); - icalendarRootElement = (Element) xpath.evaluate("//" + prefix + ":" + ICALENDAR.getLocalPart(), document, XPathConstants.NODE); - } catch (XPathExpressionException e) { - //never thrown, xpath expression is hard coded - } - } - - /** - * Creates an empty xCal document. - */ - public XCalDocument() { - document = XmlUtils.createDocument(); - icalendarRootElement = document.createElementNS(ICALENDAR.getNamespaceURI(), ICALENDAR.getLocalPart()); - document.appendChild(icalendarRootElement); - } - - /** - * Gets the raw XML DOM object. - * @return the XML DOM - */ - public Document getDocument() { - return document; - } - - /** - * Parses all iCalendar objects from this XML document. - * @return the parsed iCalendar objects - */ - public List getICalendars() { - try { - return reader().readAll(); - } catch (IOException e) { - //not thrown because reading from DOM - throw new RuntimeException(e); - } - } - - /** - * Adds an iCalendar object to this XML document. - * @param ical the iCalendar object to add - */ - public void addICalendar(ICalendar ical) { - writer().write(ical); - } - - /** - * Creates a {@link StreamReader} object that parses iCalendar objects from - * this XML document. - * @return the reader - */ - public StreamReader reader() { - return new XCalDocumentStreamReader(); - } - - /** - * Creates a {@link StreamWriter} object that adds iCalendar objects to this - * XML document. - * @return the writer - */ - public XCalDocumentStreamWriter writer() { - return new XCalDocumentStreamWriter(); - } - - /** - * Writes the xCal document to a string. - * @return the XML string - */ - public String write() { - return write((Integer) null); - } - - /** - * Writes the xCal document to a string. - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @return the XML string - */ - public String write(Integer indent) { - return write(indent, null); - } - - /** - * Writes the xCal document to a string. - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - * @return the XML string - */ - public String write(Integer indent, String xmlVersion) { - return write(new XCalOutputProperties(indent, xmlVersion)); - } - - /** - * Writes the xCal document to a string. - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperty}) - * @return the XML string - */ - public String write(Map outputProperties) { - StringWriter sw = new StringWriter(); - try { - write(sw, outputProperties); - } catch (TransformerException e) { - //shouldn't be thrown because we're writing to a string - throw new RuntimeException(e); - } - return sw.toString(); - } - - /** - * Writes the xCal document to an output stream. - * @param out the output stream to write to (UTF-8 encoding will be used) - * @throws TransformerException if there's a problem writing to the output - * stream - */ - public void write(OutputStream out) throws TransformerException { - write(out, (Integer) null); - } - - /** - * Writes the xCal document to an output stream. - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @throws TransformerException if there's a problem writing to the output - * stream - */ - public void write(OutputStream out, Integer indent) throws TransformerException { - write(out, indent, null); - } - - /** - * Writes the xCal document to an output stream. - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - * @throws TransformerException if there's a problem writing to the output - * stream - */ - public void write(OutputStream out, Integer indent, String xmlVersion) throws TransformerException { - write(out, new XCalOutputProperties(indent, xmlVersion)); - } - - /** - * Writes the xCal document to an output stream. - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperty}) - * @throws TransformerException if there's a problem writing to the output - * stream - */ - public void write(OutputStream out, Map outputProperties) throws TransformerException { - write(new Utf8Writer(out), outputProperties); - } - - /** - * Writes the xCal document to a file. - * @param file the file to write to (UTF-8 encoding will be used) - * @throws IOException if there's a problem writing to the file - * @throws TransformerException if there's a problem writing the XML - */ - public void write(File file) throws TransformerException, IOException { - write(file, (Integer) null); - } - - /** - * Writes the xCal document to a file. - * @param file the file to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @throws IOException if there's a problem writing to the file - * @throws TransformerException if there's a problem writing the XML - */ - public void write(File file, Integer indent) throws TransformerException, IOException { - write(file, indent, null); - } - - /** - * Writes the xCal document to a file. - * @param file the file to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - * @throws IOException if there's a problem writing to the file - * @throws TransformerException if there's a problem writing the XML - */ - public void write(File file, Integer indent, String xmlVersion) throws TransformerException, IOException { - write(file, new XCalOutputProperties(indent, xmlVersion)); - } - - /** - * Writes the xCal document to a file. - * @param file the file to write to (UTF-8 encoding will be used) - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperty}) - * @throws IOException if there's a problem writing to the file - * @throws TransformerException if there's a problem writing the XML - */ - public void write(File file, Map outputProperties) throws TransformerException, IOException { - Writer writer = new Utf8Writer(file); - try { - write(writer, outputProperties); - } finally { - writer.close(); - } - } - - /** - * Writes the xCal document to a writer. - * @param writer the writer - * @throws TransformerException if there's a problem writing to the writer - */ - public void write(Writer writer) throws TransformerException { - write(writer, (Integer) null); - } - - /** - * Writes the xCal document to a writer. - * @param writer the writer - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @throws TransformerException if there's a problem writing to the writer - */ - public void write(Writer writer, Integer indent) throws TransformerException { - write(writer, indent, null); - } - - /** - * Writes the xCal document to a writer. - * @param writer the writer - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - * @throws TransformerException if there's a problem writing to the writer - */ - public void write(Writer writer, Integer indent, String xmlVersion) throws TransformerException { - write(writer, new XCalOutputProperties(indent, xmlVersion)); - } - - /** - * Writes the xCal document to a writer. - * @param writer the writer - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperty}) - * @throws TransformerException if there's a problem writing to the writer - */ - public void write(Writer writer, Map outputProperties) throws TransformerException { - throw new RuntimeException("Removed"); - } - - @Override - public String toString() { - return write(2); - } - - private class XCalDocumentStreamReader extends StreamReader { - private final Iterator vcalendarElements = getVCalendarElements().iterator(); - - @Override - protected ICalendar _readNext() throws IOException { - if (!vcalendarElements.hasNext()) { - return null; - } - - context.setVersion(ICalVersion.V2_0); - Element vcalendarElement = vcalendarElements.next(); - return parseICal(vcalendarElement); - } - - private ICalendar parseICal(Element icalElement) { - ICalComponent root = parseComponent(icalElement); - if (root instanceof ICalendar) { - return (ICalendar) root; - } - - //shouldn't happen, since only elements are passed into this method - ICalendar ical = icalMarshaller.emptyInstance(); - ical.addComponent(root); - return ical; - } - - private ICalComponent parseComponent(Element componentElement) { - //create the component object - ICalComponentScribe scribe = index.getComponentScribe(componentElement.getLocalName(), ICalVersion.V2_0); - ICalComponent component = scribe.emptyInstance(); - boolean isICalendar = component instanceof ICalendar; - - //parse properties - for (Element propertyWrapperElement : getChildElements(componentElement, PROPERTIES)) { //there should be only one element, but parse them all incase there are more - for (Element propertyElement : XmlUtils.toElementList(propertyWrapperElement.getChildNodes())) { - ICalProperty property = parseProperty(propertyElement); - if (property == null) { - continue; - } - - //set "ICalendar.version" if the value of the VERSION property is recognized - //otherwise, unmarshal VERSION like a normal property - if (isICalendar && property instanceof Version) { - Version version = (Version) property; - ICalVersion icalVersion = version.toICalVersion(); - if (icalVersion != null) { - context.setVersion(icalVersion); - continue; - } - } - - component.addProperty(property); - } - } - - //parse sub-components - for (Element componentWrapperElement : getChildElements(componentElement, COMPONENTS)) { //there should be only one element, but parse them all incase there are more - for (Element subComponentElement : XmlUtils.toElementList(componentWrapperElement.getChildNodes())) { - if (!XCAL_NS.equals(subComponentElement.getNamespaceURI())) { - continue; - } - - ICalComponent subComponent = parseComponent(subComponentElement); - component.addComponent(subComponent); - } - } - - return component; - } - - private ICalProperty parseProperty(Element propertyElement) { - ICalParameters parameters = parseParameters(propertyElement); - String propertyName = propertyElement.getLocalName(); - QName qname = new QName(propertyElement.getNamespaceURI(), propertyName); - - context.getWarnings().clear(); - context.setPropertyName(propertyName); - ICalPropertyScribe scribe = index.getPropertyScribe(qname); - try { - ICalProperty property = scribe.parseXml(propertyElement, parameters, context); - warnings.addAll(context.getWarnings()); - return property; - } catch (SkipMeException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(0, e.getMessage()) - .build() - ); - //@formatter:on - return null; - } catch (CannotParseException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(e) - .build() - ); - //@formatter:on - - scribe = index.getPropertyScribe(Xml.class); - return scribe.parseXml(propertyElement, parameters, context); - } - } - - private ICalParameters parseParameters(Element propertyElement) { - ICalParameters parameters = new ICalParameters(); - - for (Element parametersElement : getChildElements(propertyElement, PARAMETERS)) { //there should be only one element, but parse them all incase there are more - List paramElements = XmlUtils.toElementList(parametersElement.getChildNodes()); - for (Element paramElement : paramElements) { - if (!XCAL_NS.equals(paramElement.getNamespaceURI())) { - continue; - } - - String name = paramElement.getLocalName().toUpperCase(); - List valueElements = XmlUtils.toElementList(paramElement.getChildNodes()); - if (valueElements.isEmpty()) { - //this should never be true if the xCal follows the specs - String value = paramElement.getTextContent(); - parameters.put(name, value); - continue; - } - - for (Element valueElement : valueElements) { - if (!XCAL_NS.equals(valueElement.getNamespaceURI())) { - continue; - } - - String value = valueElement.getTextContent(); - parameters.put(name, value); - } - } - } - - return parameters; - } - - private List getVCalendarElements() { - return (icalendarRootElement == null) ? Collections. emptyList() : getChildElements(icalendarRootElement, VCALENDAR); - } - - private List getChildElements(Element parent, QName qname) { - List elements = new ArrayList(); - for (Element child : XmlUtils.toElementList(parent.getChildNodes())) { - QName childQName = new QName(child.getNamespaceURI(), child.getLocalName()); - if (qname.equals(childQName)) { - elements.add(child); - } - } - return elements; - } - - public void close() { - //do nothing - } - } - - public class XCalDocumentStreamWriter extends XCalWriterBase { - @Override - public void write(ICalendar ical) { - try { - super.write(ical); - } catch (IOException e) { - //won't be thrown because we're writing to DOM - } - } - - @Override - protected void _write(ICalendar ical) { - Element element = buildComponentElement(ical); - - if (icalendarRootElement == null) { - icalendarRootElement = buildElement(ICALENDAR); - Element documentRoot = document.getDocumentElement(); - if (documentRoot == null) { - document.appendChild(icalendarRootElement); - } else { - documentRoot.appendChild(icalendarRootElement); - } - } - icalendarRootElement.appendChild(element); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private Element buildComponentElement(ICalComponent component) { - ICalComponentScribe componentScribe = index.getComponentScribe(component); - Element componentElement = buildElement(componentScribe.getComponentName().toLowerCase()); - - Element propertiesWrapperElement = buildElement(PROPERTIES); - List propertyObjs = componentScribe.getProperties(component); - if (component instanceof ICalendar && component.getProperty(Version.class) == null) { - //add a version property - propertyObjs.add(0, new Version(targetVersion)); - } - - for (Object propertyObj : propertyObjs) { - context.setParent(component); //set parent here incase a scribe resets the parent - ICalProperty property = (ICalProperty) propertyObj; - - //create property element - Element propertyElement = buildPropertyElement(property); - if (propertyElement != null) { - propertiesWrapperElement.appendChild(propertyElement); - } - } - if (propertiesWrapperElement.hasChildNodes()) { - componentElement.appendChild(propertiesWrapperElement); - } - - List subComponents = componentScribe.getComponents(component); - if (component instanceof ICalendar) { - //add the VTIMEZONE components that were auto-generated by TimezoneOptions - Collection tzs = getTimezoneComponents(); - for (VTimezone tz : tzs) { - if (!subComponents.contains(tz)) { - subComponents.add(0, tz); - } - } - } - Element componentsWrapperElement = buildElement(COMPONENTS); - for (Object subComponentObj : subComponents) { - ICalComponent subComponent = (ICalComponent) subComponentObj; - Element subComponentElement = buildComponentElement(subComponent); - if (subComponentElement != null) { - componentsWrapperElement.appendChild(subComponentElement); - } - } - if (componentsWrapperElement.hasChildNodes()) { - componentElement.appendChild(componentsWrapperElement); - } - - return componentElement; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private Element buildPropertyElement(ICalProperty property) { - Element propertyElement; - ICalPropertyScribe scribe = index.getPropertyScribe(property); - - if (property instanceof Xml) { - Xml xml = (Xml) property; - - Document value = xml.getValue(); - if (value == null) { - return null; - } - - //import the XML element into the xCal DOM - propertyElement = value.getDocumentElement(); - propertyElement = (Element) document.importNode(propertyElement, true); - } else { - propertyElement = buildElement(scribe.getQName()); - - //marshal value - try { - scribe.writeXml(property, propertyElement, context); - } catch (SkipMeException e) { - return null; - } - } - - //build parameters - ICalParameters parameters = scribe.prepareParameters(property, context); - if (!parameters.isEmpty()) { - Element parametersElement = buildParametersElement(parameters); - propertyElement.insertBefore(parametersElement, propertyElement.getFirstChild()); - } - - return propertyElement; - } - - private Element buildParametersElement(ICalParameters parameters) { - Element parametersWrapperElement = buildElement(PARAMETERS); - - for (Map.Entry> parameter : parameters) { - String name = parameter.getKey().toLowerCase(); - ICalDataType dataType = parameterDataTypes.get(name); - String dataTypeStr = (dataType == null) ? "unknown" : dataType.getName().toLowerCase(); - - Element parameterElement = buildAndAppendElement(name, parametersWrapperElement); - for (String parameterValue : parameter.getValue()) { - Element parameterValueElement = buildAndAppendElement(dataTypeStr, parameterElement); - parameterValueElement.setTextContent(parameterValue); - } - } - - return parametersWrapperElement; - } - - private Element buildElement(String localName) { - return buildElement(new QName(XCAL_NS, localName)); - } - - private Element buildElement(QName qname) { - return document.createElementNS(qname.getNamespaceURI(), qname.getLocalPart()); - } - - private Element buildAndAppendElement(String localName, Element parent) { - return buildAndAppendElement(new QName(XCAL_NS, localName), parent); - } - - private Element buildAndAppendElement(QName qname, Element parent) { - Element child = document.createElementNS(qname.getNamespaceURI(), qname.getLocalPart()); - parent.appendChild(child); - return child; - } - - public void close() { - //do nothing - } - } -} diff --git a/app/src/main/java/biweekly/io/xml/XCalElement.java b/app/src/main/java/biweekly/io/xml/XCalElement.java deleted file mode 100644 index 156424a1ac..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalElement.java +++ /dev/null @@ -1,292 +0,0 @@ -package biweekly.io.xml; - -import static biweekly.io.xml.XCalNamespaceContext.XCAL_NS; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import biweekly.ICalDataType; -import biweekly.util.XmlUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Wraps xCal functionality around an XML {@link Element} object. - * @author Michael Angstadt - */ -public class XCalElement { - private final Element element; - private final Document document; - - /** - * Creates a new xCal element. - * @param element the XML element to wrap - */ - public XCalElement(Element element) { - this.element = element; - document = element.getOwnerDocument(); - } - - /** - * Gets the first value of the given data type. - * @param dataType the data type to look for or null for the "unknown" data - * type - * @return the value or null if not found - */ - public String first(ICalDataType dataType) { - String dataTypeStr = toLocalName(dataType); - return first(dataTypeStr); - } - - /** - * Gets the value of the first child element with the given name. - * @param localName the name of the element - * @return the element's text or null if not found - */ - public String first(String localName) { - for (Element child : children()) { - if (localName.equals(child.getLocalName()) && XCAL_NS.equals(child.getNamespaceURI())) { - return child.getTextContent(); - } - } - return null; - } - - /** - * Gets all the values of a given data type. - * @param dataType the data type to look for or null for the "unknown" data - * type - * @return the values - */ - public List all(ICalDataType dataType) { - String dataTypeStr = toLocalName(dataType); - return all(dataTypeStr); - } - - /** - * Gets the values of all child elements that have the given name. - * @param localName the element name - * @return the values of the child elements - */ - public List all(String localName) { - List childrenText = new ArrayList(); - for (Element child : children()) { - if (localName.equals(child.getLocalName()) && XCAL_NS.equals(child.getNamespaceURI())) { - String text = child.getTextContent(); - childrenText.add(text); - } - } - return childrenText; - } - - /** - * Adds a value. - * @param dataType the data type or null for the "unknown" data type - * @param value the value - * @return the created element - */ - public Element append(ICalDataType dataType, String value) { - String dataTypeStr = toLocalName(dataType); - return append(dataTypeStr, value); - } - - /** - * Adds a child element. - * @param name the name of the child element - * @param value the value of the child element. - * @return the created element - */ - public Element append(String name, String value) { - Element child = document.createElementNS(XCAL_NS, name); - child.setTextContent(value); - element.appendChild(child); - return child; - } - - /** - * Adds a child element. - * @param name the name of the child element - * @return the created element - */ - public XCalElement append(String name) { - return new XCalElement(append(name, (String) null)); - } - - /** - * Adds an empty value. - * @param dataType the data type - * @return the created element - */ - public XCalElement append(ICalDataType dataType) { - return append(dataType.getName().toLowerCase()); - } - - /** - * Adds multiple child elements, each with the same name. - * @param name the name for all the child elements - * @param values the values of each child element - * @return the created elements - */ - public List append(String name, Collection values) { - List elements = new ArrayList(values.size()); - for (String value : values) { - elements.add(append(name, value)); - } - return elements; - } - - /** - * Gets the owner document. - * @return the owner document - */ - public Document document() { - return document; - } - - /** - * Gets the wrapped XML element. - * @return the wrapped XML element - */ - public Element getElement() { - return element; - } - - /** - * Gets the child elements of the wrapped XML element. - * @return the child elements - */ - private List children() { - return XmlUtils.toElementList(element.getChildNodes()); - } - - /** - * Gets all child elements with the given data type. - * @param dataType the data type - * @return the child elements - */ - public List children(ICalDataType dataType) { - String localName = dataType.getName().toLowerCase(); - List children = new ArrayList(); - for (Element child : children()) { - if (localName.equals(child.getLocalName()) && XCAL_NS.equals(child.getNamespaceURI())) { - children.add(new XCalElement(child)); - } - } - return children; - } - - /** - * Gets the first child element with the given data type. - * @param dataType the data type - * @return the child element or null if not found - */ - public XCalElement child(ICalDataType dataType) { - String localName = dataType.getName().toLowerCase(); - for (Element child : children()) { - if (localName.equals(child.getLocalName()) && XCAL_NS.equals(child.getNamespaceURI())) { - return new XCalElement(child); - } - } - return null; - } - - /** - * Finds the first child element that has the xCard namespace and returns - * its data type and value. If no such element is found, the parent - * {@link XCalElement}'s text content, along with a null data type, is - * returned. - * @return the value and data type - */ - public XCalValue firstValue() { - for (Element child : children()) { - String childNamespace = child.getNamespaceURI(); - if (XCAL_NS.equals(childNamespace)) { - ICalDataType dataType = toDataType(child.getLocalName()); - String value = child.getTextContent(); - return new XCalValue(dataType, value); - } - } - - return new XCalValue(null, element.getTextContent()); - } - - /** - * Gets the appropriate XML local name of a {@link ICalDataType} object. - * @param dataType the data type or null for "unknown" - * @return the local name (e.g. "text") - */ - private String toLocalName(ICalDataType dataType) { - return (dataType == null) ? "unknown" : dataType.getName().toLowerCase(); - } - - /** - * Converts an XML local name to the appropriate {@link ICalDataType} - * object. - * @param localName the local name (e.g. "text") - * @return the data type or null for "unknown" - */ - private static ICalDataType toDataType(String localName) { - return "unknown".equals(localName) ? null : ICalDataType.get(localName); - } - - /** - * Represents the data type and value of a child element under an - * {@link XCalElement}. - */ - public static class XCalValue { - private final ICalDataType dataType; - private final String value; - - /** - * @param dataType the data type or null if "unknown" - * @param value the value - */ - public XCalValue(ICalDataType dataType, String value) { - this.dataType = dataType; - this.value = value; - } - - /** - * Gets the data type - * @return the data type or null if "unknown" - */ - public ICalDataType getDataType() { - return dataType; - } - - /** - * Get the value. - * @return the value - */ - public String getValue() { - return value; - } - } -} diff --git a/app/src/main/java/biweekly/io/xml/XCalNamespaceContext.java b/app/src/main/java/biweekly/io/xml/XCalNamespaceContext.java deleted file mode 100644 index 10322ae596..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalNamespaceContext.java +++ /dev/null @@ -1,83 +0,0 @@ -package biweekly.io.xml; - -import java.util.Collections; -import java.util.Iterator; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.xpath.XPath; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Used for xCal xpath expressions. - * @see XPath#setNamespaceContext(NamespaceContext) - * @author Michael Angstadt - */ -public class XCalNamespaceContext implements NamespaceContext { - /** - * The XML namespace for xCal documents. - */ - public static final String XCAL_NS = "urn:ietf:params:xml:ns:icalendar-2.0"; - - private final String prefix; - - /** - * Creates a new namespace context. - * @param prefix the prefix to use in xpath expressions - */ - public XCalNamespaceContext(String prefix) { - this.prefix = prefix; - } - - /** - * Gets the prefix to use in xpath expressions. - * @return the xpath prefix - */ - public String getPrefix() { - return prefix; - } - - //@Override - public String getNamespaceURI(String prefix) { - if (this.prefix.equals(prefix)) { - return XCAL_NS; - } - return null; - } - - //@Override - public String getPrefix(String ns) { - if (XCAL_NS.equals(ns)) { - return prefix; - } - return null; - } - - //@Override - public Iterator getPrefixes(String ns) { - return XCAL_NS.equals(ns) ? Collections.singletonList(prefix).iterator() : null; - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/io/xml/XCalOutputProperties.java b/app/src/main/java/biweekly/io/xml/XCalOutputProperties.java deleted file mode 100644 index d9e88360e7..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalOutputProperties.java +++ /dev/null @@ -1,126 +0,0 @@ -package biweekly.io.xml; - -import java.util.HashMap; - -import javax.xml.transform.OutputKeys; - -import biweekly.Messages; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Helper class for setting commonly-used JAXP output properties. - * @author Michael Angstadt - */ -public class XCalOutputProperties extends HashMap { - private static final long serialVersionUID = -1038397031136827278L; - private static final String INDENT_AMT = "{http://xml.apache.org/xslt}indent-amount"; - - public XCalOutputProperties() { - put(OutputKeys.METHOD, "xml"); - } - - /** - * @param indent the number of indent spaces to use for pretty-printing or - * null to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - * @throws IllegalArgumentException if the indent amount is less than zero - */ - public XCalOutputProperties(Integer indent, String xmlVersion) { - this(); - setIndent(indent); - setXmlVersion(xmlVersion); - } - - /** - * Gets the number of indent spaces to use for pretty-printing. - * @return the number of indent spaces or null if pretty-printing is - * disabled - */ - public Integer getIndent() { - if (!"yes".equals(get(OutputKeys.INDENT))) { - return null; - } - - String value = get(INDENT_AMT); - return (value == null) ? null : Integer.valueOf(value); - } - - /** - * Sets the number of indent spaces to use for pretty-printing (disabled by - * default). - * @param indent the number of indent spaces to use or null to disable - * pretty-printing - * @throws IllegalArgumentException if the indent amount is less than zero - */ - public void setIndent(Integer indent) { - if (indent == null) { - remove(OutputKeys.INDENT); - remove(INDENT_AMT); - return; - } - - if (indent < 0) { - throw Messages.INSTANCE.getIllegalArgumentException(11); - } - - put(OutputKeys.INDENT, "yes"); - put(INDENT_AMT, indent.toString()); - } - - /** - * Gets the XML version to use. - * @return the XML version or null if not set - */ - public String getXmlVersion() { - return get(OutputKeys.VERSION); - } - - /** - *

- * Sets the XML version to use (defaults to "1.0"). - *

- *

- * Note: Many JDKs only support 1.0 natively. For XML 1.1 support, add a - * JAXP library like xalan to your project. - *

- * @param version the XML version or null to remove - */ - public void setXmlVersion(String version) { - if (version == null) { - remove(OutputKeys.VERSION); - return; - } - - put(OutputKeys.VERSION, version); - } -} diff --git a/app/src/main/java/biweekly/io/xml/XCalQNames.java b/app/src/main/java/biweekly/io/xml/XCalQNames.java deleted file mode 100644 index ffbb4a65fa..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalQNames.java +++ /dev/null @@ -1,42 +0,0 @@ -package biweekly.io.xml; - -import static biweekly.io.xml.XCalNamespaceContext.XCAL_NS; - -import javax.xml.namespace.QName; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Contains the XML element names of some of the standard xCard elements. - * @author Michael Angstadt - */ -public interface XCalQNames { - QName ICALENDAR = new QName(XCAL_NS, "icalendar"); - QName VCALENDAR = new QName(XCAL_NS, "vcalendar"); - QName COMPONENTS = new QName(XCAL_NS, "components"); - QName PROPERTIES = new QName(XCAL_NS, "properties"); - QName PARAMETERS = new QName(XCAL_NS, "parameters"); -} diff --git a/app/src/main/java/biweekly/io/xml/XCalReader.java b/app/src/main/java/biweekly/io/xml/XCalReader.java deleted file mode 100644 index 56282526b0..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalReader.java +++ /dev/null @@ -1,605 +0,0 @@ -package biweekly.io.xml; - -import static biweekly.io.xml.XCalNamespaceContext.XCAL_NS; -import static biweekly.io.xml.XCalQNames.COMPONENTS; -import static biweekly.io.xml.XCalQNames.ICALENDAR; -import static biweekly.io.xml.XCalQNames.PARAMETERS; -import static biweekly.io.xml.XCalQNames.PROPERTIES; -import static biweekly.io.xml.XCalQNames.VCALENDAR; - -import java.io.BufferedInputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; - -import javax.xml.XMLConstants; -import javax.xml.namespace.QName; -import javax.xml.transform.ErrorListener; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamSource; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.io.CannotParseException; -import biweekly.io.ParseContext; -import biweekly.io.ParseWarning; -import biweekly.io.SkipMeException; -import biweekly.io.StreamReader; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.property.Version; -import biweekly.property.Xml; -import biweekly.util.XmlUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - */ - -/** - *

- * Reads xCals (XML-encoded iCalendar objects) in a streaming fashion. - *

- *

- * Example: - *

- * - *
- * File file = new File("icals.xml");
- * XCalReader reader = null;
- * try {
- *   reader = new XCalReader(file);
- *   ICalendar ical;
- *   while ((ical = reader.readNext()) != null) {
- *     //...
- *   }
- * } finally {
- *   if (reader != null) reader.close();
- * }
- * 
- * @author Michael Angstadt - * @see RFC 6321 - */ -public class XCalReader extends StreamReader { - private final Source source; - private final Closeable stream; - - private volatile ICalendar readICal; - private volatile TransformerException thrown; - - private final ReadThread thread = new ReadThread(); - private final Object lock = new Object(); - private final BlockingQueue readerBlock = new ArrayBlockingQueue(1); - private final BlockingQueue threadBlock = new ArrayBlockingQueue(1); - - /** - * @param str the string to read from - */ - public XCalReader(String str) { - this(new StringReader(str)); - } - - /** - * @param in the input stream to read from - */ - public XCalReader(InputStream in) { - source = new StreamSource(in); - stream = in; - } - - /** - * @param file the file to read from - * @throws FileNotFoundException if the file doesn't exist - */ - public XCalReader(File file) throws FileNotFoundException { - this(new BufferedInputStream(new FileInputStream(file))); - } - - /** - * @param reader the reader to read from - */ - public XCalReader(Reader reader) { - source = new StreamSource(reader); - stream = reader; - } - - /** - * @param node the DOM node to read from - */ - public XCalReader(Node node) { - source = new DOMSource(node); - stream = null; - } - - @Override - protected ICalendar _readNext() throws IOException { - readICal = null; - warnings.clear(); - context = new ParseContext(); - thrown = null; - - if (!thread.started) { - thread.start(); - } else { - if (thread.finished || thread.closed) { - return null; - } - - try { - threadBlock.put(lock); - } catch (InterruptedException e) { - return null; - } - } - - //wait until thread reads xCard - try { - readerBlock.take(); - } catch (InterruptedException e) { - return null; - } - - if (thrown != null) { - throw new IOException(thrown); - } - - return readICal; - } - - private class ReadThread extends Thread { - private final SAXResult result; - private final Transformer transformer; - private volatile boolean finished = false, started = false, closed = false; - - public ReadThread() { - throw new RuntimeException("Removed"); - } - - @Override - public void run() { - started = true; - - try { - transformer.transform(source, result); - } catch (TransformerException e) { - if (!thread.closed) { - thrown = e; - } - } finally { - finished = true; - try { - readerBlock.put(lock); - } catch (InterruptedException e) { - //ignore - } - } - } - } - - private class ContentHandlerImpl extends DefaultHandler { - private final Document DOC = XmlUtils.createDocument(); - private final XCalStructure structure = new XCalStructure(); - private final StringBuilder characterBuffer = new StringBuilder(); - private final LinkedList componentStack = new LinkedList(); - - private Element propertyElement, parent; - private QName paramName; - private ICalComponent curComponent; - private ICalParameters parameters; - - @Override - public void characters(char[] buffer, int start, int length) throws SAXException { - characterBuffer.append(buffer, start, length); - } - - @Override - public void startElement(String namespace, String localName, String qName, Attributes attributes) throws SAXException { - QName qname = new QName(namespace, localName); - String textContent = emptyCharacterBuffer(); - - if (structure.isEmpty()) { - // - if (ICALENDAR.equals(qname)) { - structure.push(ElementType.icalendar); - } - return; - } - - ElementType parentType = structure.peek(); - ElementType typeToPush = null; - if (parentType != null) { - switch (parentType) { - - case icalendar: - // - if (VCALENDAR.equals(qname)) { - ICalComponentScribe scribe = index.getComponentScribe(localName, ICalVersion.V2_0); - ICalComponent component = scribe.emptyInstance(); - - curComponent = component; - readICal = (ICalendar) component; - typeToPush = ElementType.component; - } - break; - - case component: - if (PROPERTIES.equals(qname)) { - // - typeToPush = ElementType.properties; - } else if (COMPONENTS.equals(qname)) { - // - componentStack.add(curComponent); - curComponent = null; - - typeToPush = ElementType.components; - } - break; - - case components: - //start component element - if (XCAL_NS.equals(namespace)) { - ICalComponentScribe scribe = index.getComponentScribe(localName, ICalVersion.V2_0); - curComponent = scribe.emptyInstance(); - - ICalComponent parent = componentStack.getLast(); - parent.addComponent(curComponent); - - typeToPush = ElementType.component; - } - break; - - case properties: - //start property element - propertyElement = createElement(namespace, localName, attributes); - parameters = new ICalParameters(); - parent = propertyElement; - typeToPush = ElementType.property; - break; - - case property: - // - if (PARAMETERS.equals(qname)) { - typeToPush = ElementType.parameters; - } - break; - - case parameters: - //inside of - if (XCAL_NS.equals(namespace)) { - paramName = qname; - typeToPush = ElementType.parameter; - } - break; - - case parameter: - //inside of a parameter element - if (XCAL_NS.equals(namespace)) { - typeToPush = ElementType.parameterValue; - } - break; - case parameterValue: - //should never have child elements - break; - } - } - - //append element to property element - if (propertyElement != null && typeToPush != ElementType.property && typeToPush != ElementType.parameters && !structure.isUnderParameters()) { - if (textContent.length() > 0) { - parent.appendChild(DOC.createTextNode(textContent)); - } - - Element element = createElement(namespace, localName, attributes); - parent.appendChild(element); - parent = element; - } - - structure.push(typeToPush); - } - - @Override - public void endElement(String namespace, String localName, String qName) throws SAXException { - String textContent = emptyCharacterBuffer(); - - if (structure.isEmpty()) { - //no elements were read yet - return; - } - - ElementType type = structure.pop(); - if (type == null && (propertyElement == null || structure.isUnderParameters())) { - //it's a non-xCal element - return; - } - - if (type != null) { - switch (type) { - case parameterValue: - parameters.put(paramName.getLocalPart(), textContent); - break; - - case parameter: - //do nothing - break; - - case parameters: - //do nothing - break; - - case property: - context.getWarnings().clear(); - context.setPropertyName(localName); - - propertyElement.appendChild(DOC.createTextNode(textContent)); - - //unmarshal property and add to parent component - QName propertyQName = new QName(propertyElement.getNamespaceURI(), propertyElement.getLocalName()); - ICalPropertyScribe scribe = index.getPropertyScribe(propertyQName); - try { - ICalProperty property = scribe.parseXml(propertyElement, parameters, context); - if (property instanceof Version && curComponent instanceof ICalendar) { - Version versionProp = (Version) property; - ICalVersion version = versionProp.toICalVersion(); - if (version != null) { - ICalendar ical = (ICalendar) curComponent; - ical.setVersion(version); - context.setVersion(version); - - propertyElement = null; - break; - } - } - - curComponent.addProperty(property); - warnings.addAll(context.getWarnings()); - } catch (SkipMeException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(0, e.getMessage()) - .build() - ); - //@formatter:on - } catch (CannotParseException e) { - //@formatter:off - warnings.add(new ParseWarning.Builder(context) - .message(e) - .build() - ); - //@formatter:on - - scribe = index.getPropertyScribe(Xml.class); - ICalProperty property = scribe.parseXml(propertyElement, parameters, context); - curComponent.addProperty(property); - } - - propertyElement = null; - break; - - case component: - curComponent = null; - - // - if (VCALENDAR.getNamespaceURI().equals(namespace) && VCALENDAR.getLocalPart().equals(localName)) { - //wait for readNext() to be called again - try { - readerBlock.put(lock); - threadBlock.take(); - } catch (InterruptedException e) { - throw new SAXException(e); - } - return; - } - break; - - case properties: - break; - - case components: - curComponent = componentStack.removeLast(); - break; - - case icalendar: - break; - } - } - - //append element to property element - if (propertyElement != null && type != ElementType.property && type != ElementType.parameters && !structure.isUnderParameters()) { - if (textContent.length() > 0) { - parent.appendChild(DOC.createTextNode(textContent)); - } - parent = (Element) parent.getParentNode(); - } - } - - private String emptyCharacterBuffer() { - String textContent = characterBuffer.toString(); - characterBuffer.setLength(0); - return textContent; - } - - private Element createElement(String namespace, String localName, Attributes attributes) { - Element element = DOC.createElementNS(namespace, localName); - applyAttributesTo(element, attributes); - return element; - } - - private void applyAttributesTo(Element element, Attributes attributes) { - for (int i = 0; i < attributes.getLength(); i++) { - String qname = attributes.getQName(i); - if (qname.startsWith("xmlns:")) { - continue; - } - - String name = attributes.getLocalName(i); - String value = attributes.getValue(i); - element.setAttribute(name, value); - } - } - } - - private enum ElementType { - /* - * Note: A value is missing for "vcalendar" because it is treated as a - * "component". - * - * Note: These enum values are in lower-case to make them stand out from - * the "XCalQNames" variable names, many of which are identically named. - */ - icalendar, components, properties, component, property, parameters, parameter, parameterValue; - } - - /** - *

- * Keeps track of the structure of an xCal XML document. - *

- * - *

- * Note that this class is here because you can't just do QName comparisons - * on a one-by-one basis. The location of an XML element within the XML - * document is important too. It's possible for two elements to have the - * same QName, but be treated differently depending on their location (e.g. - * the {@code } property has a {@code } data type) - *

- */ - private static class XCalStructure { - private final List stack = new ArrayList(); - - /** - * Pops the top element type off the stack. - * @return the element type or null if the stack is empty - */ - public ElementType pop() { - return isEmpty() ? null : stack.remove(stack.size() - 1); - } - - /** - * Looks at the top element type. - * @return the top element type or null if the stack is empty - */ - public ElementType peek() { - return isEmpty() ? null : stack.get(stack.size() - 1); - } - - /** - * Adds an element type to the stack. - * @param type the type to add or null if the XML element is not an xCal - * element - */ - public void push(ElementType type) { - stack.add(type); - } - - /** - * Determines if the leaf node is under a {@code } element. - * @return true if it is, false if not - */ - public boolean isUnderParameters() { - //get the first non-null type - ElementType nonNull = null; - for (int i = stack.size() - 1; i >= 0; i--) { - ElementType type = stack.get(i); - if (type != null) { - nonNull = type; - break; - } - } - - //@formatter:off - return - nonNull == ElementType.parameters || - nonNull == ElementType.parameter || - nonNull == ElementType.parameterValue; - //@formatter:on - } - - /** - * Determines if the stack is empty - * @return true if the stack is empty, false if not - */ - public boolean isEmpty() { - return stack.isEmpty(); - } - } - - /** - * An implementation of {@link ErrorListener} that doesn't do anything. - */ - private static class NoOpErrorListener implements ErrorListener { - public void error(TransformerException e) { - //do nothing - } - - public void fatalError(TransformerException e) { - //do nothing - } - - public void warning(TransformerException e) { - //do nothing - } - } - - /** - * Closes the underlying input stream. - */ - public void close() throws IOException { - if (thread.isAlive()) { - thread.closed = true; - thread.interrupt(); - } - - if (stream != null) { - stream.close(); - } - } -} diff --git a/app/src/main/java/biweekly/io/xml/XCalWriter.java b/app/src/main/java/biweekly/io/xml/XCalWriter.java deleted file mode 100644 index aef43c2e21..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalWriter.java +++ /dev/null @@ -1,539 +0,0 @@ -package biweekly.io.xml; - -import static biweekly.io.xml.XCalNamespaceContext.XCAL_NS; -import static biweekly.io.xml.XCalQNames.COMPONENTS; -import static biweekly.io.xml.XCalQNames.ICALENDAR; -import static biweekly.io.xml.XCalQNames.PARAMETERS; -import static biweekly.io.xml.XCalQNames.PROPERTIES; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.xml.namespace.QName; -import javax.xml.transform.Result; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; - -import biweekly.ICalDataType; -import biweekly.ICalendar; -import biweekly.component.ICalComponent; -import biweekly.component.VTimezone; -import biweekly.io.SkipMeException; -import biweekly.io.scribe.component.ICalComponentScribe; -import biweekly.io.scribe.property.ICalPropertyScribe; -import biweekly.parameter.ICalParameters; -import biweekly.property.ICalProperty; -import biweekly.property.Version; -import biweekly.property.Xml; -import biweekly.util.Utf8Writer; -import biweekly.util.XmlUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - */ - -/** - *

- * Writes xCards (XML-encoded iCalendar objects) in a streaming fashion. - *

- *

- * Example: - *

- * - *
- * ICalendar ical1 = ...
- * ICalendar ical2 = ...
- * File file = new File("icals.xml");
- * XCalWriter writer = null;
- * try {
- *   writer = new XCalWriter(file);
- *   writer.write(ical1);
- *   writer.write(ical2);
- * } finally {
- *   if (writer != null) writer.close();
- * }
- * 
- * @author Michael Angstadt - * @see RFC 6351 - */ -public class XCalWriter extends XCalWriterBase { - //How to use SAX to write XML: http://stackoverflow.com/q/4898590 - private final Document DOC = XmlUtils.createDocument(); - - private final Writer writer; - private final TransformerHandler handler; - private final boolean icalendarElementExists; - private boolean started = false; - - /** - * @param out the output stream to write to (UTF-8 encoding will be used) - */ - public XCalWriter(OutputStream out) { - this(out, (Integer) null); - } - - /** - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - */ - public XCalWriter(OutputStream out, Integer indent) { - this(out, indent, null); - } - - /** - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - */ - public XCalWriter(OutputStream out, Integer indent, String xmlVersion) { - this(new Utf8Writer(out), indent, xmlVersion); - } - - /** - * @param out the output stream to write to (UTF-8 encoding will be used) - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperties(Properties)}) - */ - public XCalWriter(OutputStream out, Map outputProperties) { - this(new Utf8Writer(out), outputProperties); - } - - /** - * @param file the file to write to (UTF-8 encoding will be used) - * @throws IOException if there's a problem opening the file - */ - public XCalWriter(File file) throws IOException { - this(file, (Integer) null); - } - - /** - * @param file the file to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @throws IOException if there's a problem opening the file - */ - public XCalWriter(File file, Integer indent) throws IOException { - this(file, indent, null); - } - - /** - * @param file the file to write to (UTF-8 encoding will be used) - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - * @throws IOException if there's a problem opening the file - */ - public XCalWriter(File file, Integer indent, String xmlVersion) throws IOException { - this(new Utf8Writer(file), indent, xmlVersion); - } - - /** - * @param file the file to write to (UTF-8 encoding will be used) - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperties(Properties)}) - * @throws IOException if there's a problem opening the file - */ - public XCalWriter(File file, Map outputProperties) throws IOException { - this(new Utf8Writer(file), outputProperties); - } - - /** - * @param writer the writer to write to - */ - public XCalWriter(Writer writer) { - this(writer, (Integer) null); - } - - /** - * @param writer the writer to write to - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - */ - public XCalWriter(Writer writer, Integer indent) { - this(writer, indent, null); - } - - /** - * @param writer the writer to write to - * @param indent the number of indent spaces to use for pretty-printing or - * "null" to disable pretty-printing (disabled by default) - * @param xmlVersion the XML version to use (defaults to "1.0") (Note: Many - * JDKs only support 1.0 natively. For XML 1.1 support, add a JAXP library - * like xalan to your project) - */ - public XCalWriter(Writer writer, Integer indent, String xmlVersion) { - this(writer, new XCalOutputProperties(indent, xmlVersion)); - } - - /** - * @param writer the writer to write to - * @param outputProperties properties to assign to the JAXP transformer (see - * {@link Transformer#setOutputProperties(Properties)}) - */ - public XCalWriter(Writer writer, Map outputProperties) { - this(writer, null, outputProperties); - } - - /** - * @param parent the DOM node to add child elements to - */ - public XCalWriter(Node parent) { - this(null, parent, new HashMap()); - } - - private XCalWriter(Writer writer, Node parent, Map outputProperties) { - this.writer = writer; - - if (parent instanceof Document) { - Node root = parent.getFirstChild(); - if (root != null) { - parent = root; - } - } - this.icalendarElementExists = isICalendarElement(parent); - - try { - SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance(); - handler = factory.newTransformerHandler(); - } catch (TransformerConfigurationException e) { - throw new RuntimeException(e); - } - - Transformer transformer = handler.getTransformer(); - - /* - * Using Transformer#setOutputProperties(Properties) doesn't work for - * some reason for setting the number of indentation spaces. - */ - for (Map.Entry entry : outputProperties.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - transformer.setOutputProperty(key, value); - } - - Result result = (writer == null) ? new DOMResult(parent) : new StreamResult(writer); - handler.setResult(result); - } - - private boolean isICalendarElement(Node node) { - if (node == null) { - return false; - } - - if (!(node instanceof Element)) { - return false; - } - - return XmlUtils.hasQName(node, ICALENDAR); - } - - @Override - protected void _write(ICalendar ical) throws IOException { - try { - if (!started) { - handler.startDocument(); - - if (!icalendarElementExists) { - //don't output a element if the parent is a element - start(ICALENDAR); - } - - started = true; - } - - write((ICalComponent) ical); - } catch (SAXException e) { - throw new IOException(e); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void write(ICalComponent component) throws SAXException { - ICalComponentScribe scribe = index.getComponentScribe(component); - String name = scribe.getComponentName().toLowerCase(); - - start(name); - - List properties = scribe.getProperties(component); - if (component instanceof ICalendar && component.getProperty(Version.class) == null) { - properties.add(0, new Version(targetVersion)); - } - - if (!properties.isEmpty()) { - start(PROPERTIES); - - for (Object propertyObj : properties) { - context.setParent(component); //set parent here incase a scribe resets the parent - ICalProperty property = (ICalProperty) propertyObj; - write(property); - } - - end(PROPERTIES); - } - - List subComponents = scribe.getComponents(component); - if (component instanceof ICalendar) { - //add the VTIMEZONE components that were auto-generated by TimezoneOptions - Collection tzs = getTimezoneComponents(); - for (VTimezone tz : tzs) { - if (!subComponents.contains(tz)) { - subComponents.add(0, tz); - } - } - } - if (!subComponents.isEmpty()) { - start(COMPONENTS); - for (Object subComponentObj : subComponents) { - ICalComponent subComponent = (ICalComponent) subComponentObj; - write(subComponent); - } - end(COMPONENTS); - } - - end(name); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void write(ICalProperty property) throws SAXException { - ICalPropertyScribe scribe = index.getPropertyScribe(property); - ICalParameters parameters = scribe.prepareParameters(property, context); - - //get the property element to write - Element propertyElement; - if (property instanceof Xml) { - Xml xml = (Xml) property; - Document value = xml.getValue(); - if (value == null) { - return; - } - propertyElement = value.getDocumentElement(); - } else { - QName qname = scribe.getQName(); - propertyElement = DOC.createElementNS(qname.getNamespaceURI(), qname.getLocalPart()); - try { - scribe.writeXml(property, propertyElement, context); - } catch (SkipMeException e) { - return; - } - } - - start(propertyElement); - - write(parameters); - write(propertyElement); - - end(propertyElement); - } - - private void write(Element propertyElement) throws SAXException { - NodeList children = propertyElement.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - - if (child instanceof Element) { - Element element = (Element) child; - - if (element.hasChildNodes()) { - start(element); - write(element); - end(element); - } else { - childless(element); - } - - continue; - } - - if (child instanceof Text) { - Text text = (Text) child; - text(text.getTextContent()); - continue; - } - } - } - - private void write(ICalParameters parameters) throws SAXException { - if (parameters.isEmpty()) { - return; - } - - start(PARAMETERS); - - for (Map.Entry> parameter : parameters) { - String parameterName = parameter.getKey().toLowerCase(); - start(parameterName); - - for (String parameterValue : parameter.getValue()) { - ICalDataType dataType = parameterDataTypes.get(parameterName); - String dataTypeElementName = (dataType == null) ? "unknown" : dataType.getName().toLowerCase(); - - start(dataTypeElementName); - text(parameterValue); - end(dataTypeElementName); - } - - end(parameterName); - } - - end(PARAMETERS); - } - - /** - * Makes an childless element appear as {@code } instead of - * {@code } - * @param element the element - * @throws SAXException if there's a problem creating the element - */ - private void childless(Element element) throws SAXException { - Attributes attributes = getElementAttributes(element); - handler.startElement(element.getNamespaceURI(), "", element.getLocalName(), attributes); - handler.endElement(element.getNamespaceURI(), "", element.getLocalName()); - } - - private void start(Element element) throws SAXException { - Attributes attributes = getElementAttributes(element); - start(element.getNamespaceURI(), element.getLocalName(), attributes); - } - - private void start(String element) throws SAXException { - start(element, new AttributesImpl()); - } - - private void start(QName qname) throws SAXException { - start(qname, new AttributesImpl()); - } - - private void start(QName qname, Attributes attributes) throws SAXException { - start(qname.getNamespaceURI(), qname.getLocalPart(), attributes); - } - - private void start(String element, Attributes attributes) throws SAXException { - start(XCAL_NS, element, attributes); - } - - private void start(String namespace, String element, Attributes attributes) throws SAXException { - handler.startElement(namespace, "", element, attributes); - } - - private void end(Element element) throws SAXException { - end(element.getNamespaceURI(), element.getLocalName()); - } - - private void end(String element) throws SAXException { - end(XCAL_NS, element); - } - - private void end(QName qname) throws SAXException { - end(qname.getNamespaceURI(), qname.getLocalPart()); - } - - private void end(String namespace, String element) throws SAXException { - handler.endElement(namespace, "", element); - } - - private void text(String text) throws SAXException { - handler.characters(text.toCharArray(), 0, text.length()); - } - - private static Attributes getElementAttributes(Element element) { - AttributesImpl attributes = new AttributesImpl(); - NamedNodeMap attributeNodes = element.getAttributes(); - for (int i = 0; i < attributeNodes.getLength(); i++) { - Node node = attributeNodes.item(i); - - String localName = node.getLocalName(); - if ("xmlns".equals(localName)) { - continue; - } - - attributes.addAttribute(node.getNamespaceURI(), "", node.getLocalName(), "", node.getNodeValue()); - } - return attributes; - } - - /** - * Terminates the XML document and closes the output stream. - */ - public void close() throws IOException { - try { - if (!started) { - handler.startDocument(); - - if (!icalendarElementExists) { - //don't output a element if the parent is a element - start(ICALENDAR); - } - } - - if (!icalendarElementExists) { - end(ICALENDAR); - } - handler.endDocument(); - } catch (SAXException e) { - throw new IOException(e); - } - - if (writer != null) { - writer.close(); - } - } -} diff --git a/app/src/main/java/biweekly/io/xml/XCalWriterBase.java b/app/src/main/java/biweekly/io/xml/XCalWriterBase.java deleted file mode 100644 index 02825b8f7e..0000000000 --- a/app/src/main/java/biweekly/io/xml/XCalWriterBase.java +++ /dev/null @@ -1,98 +0,0 @@ -package biweekly.io.xml; - -import java.util.HashMap; -import java.util.Map; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.io.StreamWriter; -import biweekly.parameter.ICalParameters; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Base class for xCal writers. - * @author Michael Angstadt - */ -abstract class XCalWriterBase extends StreamWriter { - protected final ICalVersion targetVersion = ICalVersion.V2_0; //xCal only supports 2.0 - - /** - * Defines the names of the XML elements that are used to hold each - * parameter's value. - */ - protected final Map parameterDataTypes = new HashMap(); - { - registerParameterDataType(ICalParameters.ALTREP, ICalDataType.URI); - //registerParameterDataType(ICalParameters.CHARSET, ICalDataType.TEXT); //not used by 2.0 - registerParameterDataType(ICalParameters.CN, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.CUTYPE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.DELEGATED_FROM, ICalDataType.CAL_ADDRESS); - registerParameterDataType(ICalParameters.DELEGATED_TO, ICalDataType.CAL_ADDRESS); - registerParameterDataType(ICalParameters.DIR, ICalDataType.URI); - registerParameterDataType(ICalParameters.DISPLAY, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.EMAIL, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.ENCODING, ICalDataType.TEXT); - //registerParameterDataType(ICalParameters.EXPECT, ICalDataType.TEXT); //not used by 2.0 - registerParameterDataType(ICalParameters.FEATURE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.FMTTYPE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.FBTYPE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.LABEL, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.LANGUAGE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.MEMBER, ICalDataType.CAL_ADDRESS); - registerParameterDataType(ICalParameters.PARTSTAT, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.RANGE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.RELATED, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.RELTYPE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.ROLE, ICalDataType.TEXT); - registerParameterDataType(ICalParameters.RSVP, ICalDataType.BOOLEAN); - registerParameterDataType(ICalParameters.SENT_BY, ICalDataType.CAL_ADDRESS); - //registerParameterDataType(ICalParameters.STATUS, ICalDataType.TEXT); //not used by 2.0 - //registerParameterDataType(ICalParameters.TYPE, ICalDataType.TEXT); //not used by 2.0 - registerParameterDataType(ICalParameters.TZID, ICalDataType.TEXT); - //registerParameterDataType(ICalParameters.VALUE, ICalDataType.TEXT); //not used in xCal - } - - @Override - protected ICalVersion getTargetVersion() { - return targetVersion; - } - - /** - * Registers the data type of an experimental parameter. Experimental - * parameters use the "unknown" data type by default. - * @param parameterName the parameter name (e.g. "x-foo") - * @param dataType the data type or null to remove - */ - public void registerParameterDataType(String parameterName, ICalDataType dataType) { - parameterName = parameterName.toLowerCase(); - if (dataType == null) { - parameterDataTypes.remove(parameterName); - } else { - parameterDataTypes.put(parameterName, dataType); - } - } -} diff --git a/app/src/main/java/biweekly/io/xml/package-info.java b/app/src/main/java/biweekly/io/xml/package-info.java deleted file mode 100644 index f2e73ef0d2..0000000000 --- a/app/src/main/java/biweekly/io/xml/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes for reading and writing xCals (XML-encoded iCalendar objects). - */ -package biweekly.io.xml; \ No newline at end of file diff --git a/app/src/main/java/biweekly/parameter/CalendarUserType.java b/app/src/main/java/biweekly/parameter/CalendarUserType.java deleted file mode 100644 index 4f3282c19e..0000000000 --- a/app/src/main/java/biweekly/parameter/CalendarUserType.java +++ /dev/null @@ -1,77 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the type of user an entity is. - * @author Michael Angstadt - * @see RFC 5545 p.16 - */ -public class CalendarUserType extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(CalendarUserType.class); - - public static final CalendarUserType INDIVIDUAL = new CalendarUserType("INDIVIDUAL"); - public static final CalendarUserType GROUP = new CalendarUserType("GROUP"); - public static final CalendarUserType RESOURCE = new CalendarUserType("RESOURCE"); - public static final CalendarUserType ROOM = new CalendarUserType("ROOM"); - public static final CalendarUserType UNKNOWN = new CalendarUserType("UNKNOWN"); - - private CalendarUserType(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static CalendarUserType find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static CalendarUserType get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/Display.java b/app/src/main/java/biweekly/parameter/Display.java deleted file mode 100644 index 8f853a9f30..0000000000 --- a/app/src/main/java/biweekly/parameter/Display.java +++ /dev/null @@ -1,97 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -import biweekly.property.Image; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the ways in which an {@link Image} can be displayed. - * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.13 - */ -public class Display extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(Display.class); - - /** - * The image should be displayed in-line with the component title. - */ - public static final Display BADGE = new Display("BADGE"); - - /** - * The image can be used as a replacement for the information in the - * component. - */ - public static final Display GRAPHIC = new Display("GRAPHIC"); - - /** - * The image enhances or accompanies the information in the component. - */ - public static final Display FULLSIZE = new Display("FULLSIZE"); - - /** - * A smaller version of the {@link #FULLSIZE} image. Used when there is not - * enough space to display the {@link #FULLSIZE} image. - */ - public static final Display THUMBNAIL = new Display("THUMBNAIL"); - - private Display(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static Display find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static Display get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/Encoding.java b/app/src/main/java/biweekly/parameter/Encoding.java deleted file mode 100644 index c0512ae85e..0000000000 --- a/app/src/main/java/biweekly/parameter/Encoding.java +++ /dev/null @@ -1,77 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines how a property value is encoded. - * @author Michael Angstadt - * @see RFC 5545 p.18-9 - */ -public class Encoding extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(Encoding.class); - - public static final Encoding BASE64 = new Encoding("BASE64"); - - public static final Encoding QUOTED_PRINTABLE = new Encoding("QUOTED-PRINTABLE"); //1.0 only - - public static final Encoding _8BIT = new Encoding("8BIT"); - - private Encoding(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static Encoding find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static Encoding get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/EnumParameterValue.java b/app/src/main/java/biweekly/parameter/EnumParameterValue.java deleted file mode 100644 index a4f8cd7287..0000000000 --- a/app/src/main/java/biweekly/parameter/EnumParameterValue.java +++ /dev/null @@ -1,58 +0,0 @@ -package biweekly.parameter; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a value from a parameter that has a list of pre-defined values - * (for example, the VALUE or ACTION parameters). - * @author Michael Angstadt - */ -public class EnumParameterValue { - /** - * The value (for example, "text"). - */ - protected final String value; - - /** - * @param value the value (e.g. "text") - */ - protected EnumParameterValue(String value) { - this.value = value; - } - - /** - * Gets the value of the parameter. - * @return the value of the parameter (e.g. "text") - */ - public String getValue() { - return value; - } - - @Override - public String toString() { - return value; - } -} diff --git a/app/src/main/java/biweekly/parameter/Feature.java b/app/src/main/java/biweekly/parameter/Feature.java deleted file mode 100644 index ba118ca8e0..0000000000 --- a/app/src/main/java/biweekly/parameter/Feature.java +++ /dev/null @@ -1,111 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -import biweekly.property.Conference; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the features of a {@link Conference}. - * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.15 - */ -public class Feature extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(Feature.class); - - /** - * The conference has audio. - */ - public static final Feature AUDIO = new Feature("AUDIO"); - - /** - * The conference has chat or instant messaging. - */ - public static final Feature CHAT = new Feature("CHAT"); - - /** - * The conference has some kind of feed, such as an Atom or RSS feed. - */ - public static final Feature FEED = new Feature("FEED"); - - /** - * Indicates that the property value is specific to the owner of the - * conference. - */ - public static final Feature MODERATOR = new Feature("MODERATOR"); - - /** - * The conference is a phone conference. - */ - public static final Feature PHONE = new Feature("PHONE"); - - /** - * The conference supports screen sharing. - */ - public static final Feature SCREEN = new Feature("SCREEN"); - - /** - * The conference is a video conference. - */ - public static final Feature VIDEO = new Feature("VIDEO"); - - private Feature(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static Feature find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static Feature get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/FreeBusyType.java b/app/src/main/java/biweekly/parameter/FreeBusyType.java deleted file mode 100644 index fbf77b3ac7..0000000000 --- a/app/src/main/java/biweekly/parameter/FreeBusyType.java +++ /dev/null @@ -1,76 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines whether a calendar user is free or busy over a time period. - * @author Michael Angstadt - * @see RFC 5545 p.20-1 - */ -public class FreeBusyType extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(FreeBusyType.class); - - public static final FreeBusyType FREE = new FreeBusyType("FREE"); - public static final FreeBusyType BUSY = new FreeBusyType("BUSY"); - public static final FreeBusyType BUSY_UNAVAILABLE = new FreeBusyType("BUSY-UNAVAILABLE"); - public static final FreeBusyType BUSY_TENTATIVE = new FreeBusyType("BUSY-TENTATIVE"); - - private FreeBusyType(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static FreeBusyType find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static FreeBusyType get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/ICalParameterCaseClasses.java b/app/src/main/java/biweekly/parameter/ICalParameterCaseClasses.java deleted file mode 100644 index 7646d9c39f..0000000000 --- a/app/src/main/java/biweekly/parameter/ICalParameterCaseClasses.java +++ /dev/null @@ -1,68 +0,0 @@ -package biweekly.parameter; - -import java.lang.reflect.Constructor; - -import biweekly.ICalVersion; -import biweekly.util.CaseClasses; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Manages the list of pre-defined values for a parameter (such as VALUE or - * ENCODING). - * @author Michael Angstadt - * @param the parameter class - */ -public class ICalParameterCaseClasses extends CaseClasses { - public ICalParameterCaseClasses(Class clazz) { - super(clazz); - } - - @Override - protected T create(String value) { - //reflection: return new ClassName(value); - try { - //try (String) constructor - Constructor constructor = clazz.getDeclaredConstructor(String.class); - constructor.setAccessible(true); - return constructor.newInstance(value); - } catch (Exception e) { - try { - //try (String, ICalVersion...) constructor - Constructor constructor = clazz.getDeclaredConstructor(String.class, ICalVersion[].class); - constructor.setAccessible(true); - return constructor.newInstance(value, new ICalVersion[] {}); - } catch (Exception e2) { - throw new RuntimeException(e2); - } - } - } - - @Override - protected boolean matches(T object, String value) { - return object.value.equalsIgnoreCase(value); - } -} diff --git a/app/src/main/java/biweekly/parameter/ICalParameters.java b/app/src/main/java/biweekly/parameter/ICalParameters.java deleted file mode 100644 index c2ecd4dc6f..0000000000 --- a/app/src/main/java/biweekly/parameter/ICalParameters.java +++ /dev/null @@ -1,1597 +0,0 @@ -package biweekly.parameter; - -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import com.github.mangstadt.vinnie.SyntaxStyle; -import com.github.mangstadt.vinnie.validate.AllowedCharacters; -import com.github.mangstadt.vinnie.validate.VObjectValidator; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.Messages; -import biweekly.ValidationWarning; -import biweekly.property.Attendee; -import biweekly.property.Conference; -import biweekly.property.FreeBusy; -import biweekly.property.Image; -import biweekly.property.Organizer; -import biweekly.property.RecurrenceId; -import biweekly.property.RelatedTo; -import biweekly.property.Trigger; -import biweekly.util.ListMultimap; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Stores the parameters that belong to a property. - * @author Michael Angstadt - */ -public class ICalParameters extends ListMultimap { - /** - * Contains a URI that points to additional information about the entity - * represented by the property. - * @see RFC 5545 - * p.14-5 - */ - public static final String ALTREP = "ALTREP"; - - /** - * Defines the character set that the property value is encoded in (for - * example, "UTF-8"). It is only used in the vCal 1.0 standard, and is - * typically used when a property value is encoded in quoted-printable - * encoding. - * @see vCal 1.0 p.16 - */ - public static final String CHARSET = "CHARSET"; - - /** - * Contains a human-readable, display name of the entity represented by this - * property (for example, "John Doe"). It is used by the {@link Attendee} - * and {@link Organizer} properties. - * @see RFC 5545 - * p.15-6 - */ - public static final String CN = "CN"; - - /** - * Used by the {@link Attendee} property. It defines the type of object that - * the attendee is (for example, an "individual" or a "room"). - * @see RFC 5545 - * p.16 - */ - public static final String CUTYPE = "CUTYPE"; - - /** - * Used by the {@link Attendee} property. It stores a list of people who - * have delegated their responsibility to the attendee. The values must be - * URIs. They are typically email URIs (for example, - * "mailto:janedoe@example.com"). - * @see RFC 5545 - * p.17 - */ - public static final String DELEGATED_FROM = "DELEGATED-FROM"; - - /** - * Used by the {@link Attendee} property. It stores a list of people to - * which the attendee has delegated his or her responsibility. The values - * must be URIs. They are typically email URIs (for example, - * "mailto:janedoe@example.com"). - * @see RFC 5545 - * p.17-8 - */ - public static final String DELEGATED_TO = "DELEGATED-TO"; - - /** - * Contains a URI (such as an LDAP URI) which points to additional - * information about the person that the property represents. It is used by - * the {@link Attendee} and {@link Organizer} properties. - * @see RFC 5545 - * p.18 - */ - public static final String DIR = "DIR"; - - /** - * Used by the {@link Image} property. It defines the ways in which the - * client application should display the image (for example, as a - * thumbnail-sized image). - * @see - * draft-ietf-calext-extensions p.13 - */ - public static final String DISPLAY = "DISPLAY"; - - /** - * Used by the {@link Attendee} property. Normally, this property's value - * contains the email address of the attendee. But if the property value - * must hold something else, this parameter can be used to store the - * attendee's email address. - * @see - * draft-ietf-calext-extensions p.14 - */ - public static final String EMAIL = "EMAIL"; - - /** - * Defines how the property value is encoded (for example, "base64" for a - * binary value). - * @see RFC 5545 - * p.18-9 - */ - public static final String ENCODING = "ENCODING"; - - /** - * Used by the {@link Attendee} property. It defines whether the event - * organizer expects the attendee to attend or not. It is only used in the - * vCal 1.0 standard. - * @see vCal 1.0 p.25 - */ - public static final String EXPECT = "EXPECT"; - - /** - * Used by the {@link Conference} property. It defines the features that the - * conference supports (for example, audio and video). - * @see - * draft-ietf-calext-extensions p.15 - */ - public static final String FEATURE = "FEATURE"; - - /** - * Defines the content type of the property value (for example, "image/jpg" - * if the property value is a JPEG image). - * @see RFC 5545 - * p.19-20 - */ - public static final String FMTTYPE = "FMTTYPE"; - - /** - * Used by the {@link FreeBusy} property. It defines whether the person is - * "free" or "busy" over the time periods that are specified in the property - * value. If this parameter is not set, the user should be considered "busy" - * during these times. - * @see RFC 5545 - * p.20 - */ - public static final String FBTYPE = "FBTYPE"; - - /** - * Defines a human-readable label for the property. - * @see - * draft-ietf-calext-extensions-01 p.16 - */ - public static final String LABEL = "LABEL"; - - /** - * Defines the language that the property value is written in (for example, - * "en" for English). - * @see RFC 5545 - * p.21 - */ - public static final String LANGUAGE = "LANGUAGE"; - - /** - * Used by the {@link Attendee} property. It defines the groups that the - * attendee is a member of in the form of URIs. Typically, these are email - * URIs (for example, "mailto:mailinglist@example.com"). - * @see RFC 5545 - * p.21-2 - */ - public static final String MEMBER = "MEMBER"; - - /** - * Used by the {@link Attendee} property. It defines the participation - * status of the attendee (for example, "ACCEPTED"). If none is defined, - * then the property should be treated as if this parameter was set to - * "NEEDS-ACTION". - * @see RFC 5545 - * p.22 - */ - public static final String PARTSTAT = "PARTSTAT"; - - /** - * Used by the {@link RecurrenceId} property. It defines the effective range - * of recurrence instances that the property references. - * @see RFC 5545 - * p.23-4 - */ - public static final String RANGE = "RANGE"; - - /** - * Used by the {@link Trigger} property. It defines the date-time field that - * the property's duration (if specified) is relative to (for example, the - * start date or the end date). - * @see RFC 5545 - * p.24 - */ - public static final String RELATED = "RELATED"; - - /** - * Used by the {@link RelatedTo} property. It defines the kind of - * relationship the property is describing (for example, a "child" - * relationship). - * @see RFC 5545 - * p.25 - */ - public static final String RELTYPE = "RELTYPE"; - - /** - * Used by the {@link Attendee} property. It defines the attendee's role - * and/or whether they must attend or not (for example, "OPT-PARTICIPANT" - * for "optional participant"). If none is defined, then the property should - * be treated as if this parameter was set to "REQ-PARTICIPANT" (required - * participant). - * @see RFC 5545 - * p.25 - * @see vCal 1.0 p.25 - */ - public static final String ROLE = "ROLE"; - - /** - * Used by the {@link Attendee} property. It defines whether the event - * organizer would like the attendee to reply with his or her intention of - * attending ("true" if the organizer would like a reply, "false" if not). - * If this parameter is not defined, then the property should be treated as - * if this parameter was set to "false". - * @see RFC 5545 - * p.26 - * @see vCal 1.0 p.25 - */ - public static final String RSVP = "RSVP"; - - /** - * Defines a URI which represents a person who is acting on behalf of the - * person that is defined in the property. Typically, the URI is an email - * URI (for example, "mailto:janedoe@example.com"). It is used by the - * {@link Attendee} and {@link Organizer} properties. - * @see RFC 5545 - * p.27 - */ - public static final String SENT_BY = "SENT-BY"; - - /** - * Used by the {@link Attendee} property. It defines the status of the - * person's event invitation (for example, "TENTATIVE" if the person may or - * may not attend). It is only used in the vCal 1.0 standard. - * @see vCal 1.0 p.25 - */ - public static final String STATUS = "STATUS"; - - /** - * Defines the content type of the property value (for example, "WAVE" for - * an audio file). It is only used in the vCal 1.0 standard. - * @see vCal 1.0 p.27 - */ - public static final String TYPE = "TYPE"; - - /** - * Used by properties that contain date-time values. It defines the timezone - * that the property value is formatted in. It either references a timezone - * defined in a VTIMEZONE component, or contains an Olson timezone ID. To - * use an Olson timezone ID, the parameter value must be prepended with a - * "/" (for example, "/America/New_York"). - * @see RFC 5545 - * p.27-8 - */ - public static final String TZID = "TZID"; - - /** - * Defines the data type of the property value (for example, "date" if the - * property value is a date without a time component). It is used if the - * property accepts multiple values that have different data types. - * @see RFC 5545 - * p.29-50 - */ - public static final String VALUE = "VALUE"; - - /** - * Creates a parameters list. - */ - public ICalParameters() { - /* - * Initialize map size to 0 because most properties don't use any - * parameters. - */ - super(0); - } - - /** - * Copies an existing parameters list. - * @param parameters the list to copy - */ - public ICalParameters(ICalParameters parameters) { - super(parameters); - } - - /** - *

- * Creates a parameter list that is backed by the given map. Any changes - * made to the given map will effect the parameter list and vice versa. - *

- *

- * Care must be taken to ensure that the given map's keys are all in - * uppercase. - *

- *

- * To avoid problems, it is highly recommended that the given map NOT be - * modified by anything other than this {@link ICalParameters} class after - * being passed into this constructor. - *

- * @param map the map - */ - public ICalParameters(Map> map) { - super(map); - } - - /** - *

- * Gets the ALTREP (alternate representation) parameter value. - *

- *

- * This parameter contains a URI that points to additional information about - * the entity represented by the property. - *

- * @return the URI or null if not set - * @see RFC 5545 - * p.14-5 - */ - public String getAltRepresentation() { - return first(ALTREP); - } - - /** - *

- * Sets the ALTREP (alternate representation) parameter value. - *

- *

- * This parameter contains a URI that points to additional information about - * the entity represented by the property. - *

- * @param uri the URI or null to remove - * @see RFC 5545 - * p.14-5 - */ - public void setAltRepresentation(String uri) { - replace(ALTREP, uri); - } - - /** - *

- * Gets the CHARSET parameter value. - *

- *

- * This parameter contains the character set that the property value is - * encoded in (for example, "UTF-8"). It is only used in the vCal 1.0 - * standard, and is typically used when a property value is encoded in - * quoted-printable encoding. - *

- * @return the character set or null if not set - * @see vCal 1.0 p.16 - */ - public String getCharset() { - return first(CHARSET); - } - - /** - *

- * Sets the CHARSET parameter value. - *

- *

- * This parameter contains the character set that the property value is - * encoded in (for example, "UTF-8"). It is only used in the vCal 1.0 - * standard, and is typically used when a property value is encoded in - * quoted-printable encoding. - *

- * @param charset the character set or null to remove - * @see vCal 1.0 p.16 - */ - public void setCharset(String charset) { - replace(CHARSET, charset); - } - - /** - *

- * Gets the CN (common name) parameter value. - *

- *

- * This parameter contains a human-readable, display name of the entity - * represented by this property (for example, "John Doe"). It is used by the - * {@link Attendee} and {@link Organizer} properties. - *

- * @return the common name or null if not set - * @see RFC 5545 - * p.15-6 - */ - public String getCommonName() { - return first(CN); - } - - /** - *

- * Sets the CN (common name) parameter value. - *

- *

- * This parameter contains a human-readable, display name of the entity - * represented by this property (for example, "John Doe"). It is used by the - * {@link Attendee} and {@link Organizer} properties. - *

- * @param cn the common name or null to remove - * @see RFC 5545 - * p.15-6 - */ - public void setCommonName(String cn) { - replace(CN, cn); - } - - /** - *

- * Gets the CUTYPE (calendar user type) parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * type of object that the attendee is (for example, an "individual" or a - * "room"). - *

- * @return the calendar user type or null if not set - * @see RFC 5545 - * p.16 - */ - public CalendarUserType getCalendarUserType() { - String value = first(CUTYPE); - return (value == null) ? null : CalendarUserType.get(value); - } - - /** - *

- * Sets the CUTYPE (calendar user type) parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * type of object that the attendee is (for example, an "individual" or a - * "room"). - *

- * @param calendarUserType the calendar user type or null to remove - * @see RFC 5545 - * p.16 - */ - public void setCalendarUserType(CalendarUserType calendarUserType) { - replace(CUTYPE, (calendarUserType == null) ? null : calendarUserType.getValue()); - } - - /** - *

- * Gets the DELEGATED-FROM parameter values. - *

- *

- * This parameter is used by the {@link Attendee} property. It stores a list - * of people who have delegated their responsibility to the attendee. The - * values must be URIs. They are typically email URIs (for example, - * "mailto:janedoe@example.com"). - *

- *

- * Changes to the returned list will update the {@link ICalParameters} - * object, and vice versa. - *

- * @return the URIs or an empty list if none are set - * @see RFC 5545 - * p.17 - */ - public List getDelegatedFrom() { - return get(DELEGATED_FROM); - } - - /** - *

- * Gets the DELEGATED-TO parameter values. - *

- *

- * This parameter is used by the {@link Attendee} property. It stores a list - * of people to which the attendee has delegated his or her responsibility. - * The values must be URIs. They are typically email URIs (for example, - * "mailto:janedoe@example.com"). - *

- *

- * Changes to the returned list will update the {@link ICalParameters} - * object, and vice versa. - *

- * @return the URIs or an empty list if none are set - * @see RFC 5545 - * p.17-8 - */ - public List getDelegatedTo() { - return get(DELEGATED_TO); - } - - /** - *

- * Gets the DIR (directory entry) parameter value. - *

- *

- * This parameter contains a URI (such as an LDAP URI) which points to - * additional information about the person that the property represents. It - * is used by the {@link Attendee} and {@link Organizer} properties. - *

- * @return the URI or null if not set - * @see RFC 5545 - * p.18 - */ - public String getDirectoryEntry() { - return first(DIR); - } - - /** - *

- * Sets the DIR (directory entry) parameter value. - *

- *

- * This parameter contains a URI (such as an LDAP URI) which points to - * additional information about the person that the property represents. It - * is used by the {@link Attendee} and {@link Organizer} properties. - *

- * @param uri the URI or null to remove - * @see RFC 5545 - * p.18 - */ - public void setDirectoryEntry(String uri) { - replace(DIR, uri); - } - - /** - *

- * Gets the DISPLAY parameter values. - *

- *

- * This parameter is used by the {@link Image} property. It defines the ways - * in which the client application should display the image (for example, as - * a thumbnail-sized image). - *

- *

- * Changes to the returned list will update the {@link ICalParameters} - * object, and vice versa. - *

- * @return the display suggestions or empty list if none are defined - * @see - * draft-ietf-calext-extensions p.13 - */ - public List getDisplays() { - return new EnumParameterList(DISPLAY) { - @Override - protected Display _asObject(String value) { - return Display.get(value); - } - }; - } - - /** - *

- * Gets the EMAIL parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. Normally, this - * property's value contains the email address of the attendee. But if the - * property value must hold something else, this parameter can be used to - * store the attendee's email address. - *

- * @return the email or null if not set - * @see - * draft-ietf-calext-extensions p.14 - */ - public String getEmail() { - return first(EMAIL); - } - - /** - *

- * Sets the EMAIL parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. Normally, this - * property's value contains the email address of the attendee. But if the - * property value must hold something else, this parameter can be used to - * store the attendee's email address. - *

- * @param email the email or null to remove - * @see - * draft-ietf-calext-extensions p.14 - */ - public void setEmail(String email) { - replace(EMAIL, email); - } - - /** - *

- * Gets the ENCODING parameter value. - *

- *

- * This parameter defines how the property value is encoded (for example, - * "base64" for a binary value). - *

- * @return the encoding or null if not set - * @see RFC 5545 - * p.18-9 - */ - public Encoding getEncoding() { - String value = first(ENCODING); - return (value == null) ? null : Encoding.get(value); - } - - /** - *

- * Sets the ENCODING parameter value. - *

- *

- * This parameter defines how the property value is encoded (for example, - * "base64" for a binary value). - *

- * @param encoding the encoding or null to remove - * @see RFC 5545 - * p.18-9 - */ - public void setEncoding(Encoding encoding) { - replace(ENCODING, (encoding == null) ? null : encoding.getValue()); - } - - /** - *

- * Gets the EXPECT parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines - * whether the event organizer expects the attendee to attend or not. It is - * only used in the vCal 1.0 standard. - *

- * @return the attendance expectation or null if not set - * @see vCal 1.0 p.25 - */ - public String getExpect() { - return first(EXPECT); - } - - /** - *

- * Sets the EXPECT parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines - * whether the event organizer expects the attendee to attend or not. It is - * only used in the vCal 1.0 standard. - *

- * @param expect the attendance expectation or null if not set - * @see vCal 1.0 p.25 - */ - public void setExpect(String expect) { - replace(EXPECT, expect); - } - - /** - *

- * Gets the FEATURE parameter values. - *

- *

- * This parameter is used by the {@link Conference} property. It defines the - * features that the conference supports (for example, audio and video). - *

- *

- * Changes to the returned list will update the {@link ICalParameters} - * object, and vice versa. - *

- * @return the features or empty list if none are set - * @see - * draft-ietf-calext-extensions p.15 - */ - public List getFeatures() { - return new EnumParameterList(FEATURE) { - @Override - protected Feature _asObject(String value) { - return Feature.get(value); - } - }; - } - - /** - *

- * Gets the FMTTYPE (format type) parameter value. - *

- *

- * This parameter defines the content type of the property value (for - * example, "image/jpg" if the property value is a JPEG image). - *

- * @return the format type or null if not set - * @see RFC 5545 - * p.19-20 - */ - public String getFormatType() { - return first(FMTTYPE); - } - - /** - *

- * Sets the FMTTYPE (format type) parameter value. - *

- *

- * This parameter defines the content type of the property value (for - * example, "image/jpg" if the property value is a JPEG image). - *

- * @param formatType the format type or null to remove - * @see RFC 5545 - * p.19-20 - */ - public void setFormatType(String formatType) { - replace(FMTTYPE, formatType); - } - - /** - *

- * Gets the FBTYPE (free busy type) parameter value. - *

- *

- * This parameter is used by the {@link FreeBusy} property. It defines - * whether the person is "free" or "busy" over the time periods that are - * specified in the property value. If this parameter is not set, the user - * should be considered "busy" during these times. - *

- * @return the free busy type or null if not set - * @see RFC 5545 - * p.20 - */ - public FreeBusyType getFreeBusyType() { - String value = first(FBTYPE); - return (value == null) ? null : FreeBusyType.get(value); - } - - /** - *

- * Sets the FBTYPE (free busy type) parameter value. - *

- *

- * This parameter is used by the {@link FreeBusy} property. It defines - * whether the person is "free" or "busy" over the time periods that are - * specified in the property value. If this parameter is not set, the user - * should be considered "busy" during these times. - *

- * @param freeBusyType the free busy type or null to remove - * @see RFC 5545 - * p.20 - */ - public void setFreeBusyType(FreeBusyType freeBusyType) { - replace(FBTYPE, (freeBusyType == null) ? null : freeBusyType.getValue()); - } - - /** - *

- * Gets the LABEL parameter value. - *

- *

- * This parameter defines a human-readable label for the property. - *

- * @return the label or null if not set - * @see - * draft-ietf-calext-extensions-01 p.16 - */ - public String getLabel() { - return first(LABEL); - } - - /** - *

- * Sets the LABEL parameter value. - *

- *

- * This parameter defines a human-readable label for the property. - *

- * @param label the label or null to remove - * @see - * draft-ietf-calext-extensions-01 p.16 - */ - public void setLabel(String label) { - replace(LABEL, label); - } - - /** - *

- * Gets the LANGUAGE parameter value. - *

- *

- * This parameter defines the language that the property value is written in - * (for example, "en" for English). - *

- * @return the language or null if not set - * @see RFC 5545 - * p.21 - */ - public String getLanguage() { - return first(LANGUAGE); - } - - /** - *

- * Sets the LANGUAGE parameter value. - *

- *

- * This parameter defines the language that the property value is written in - * (for example, "en" for English). - *

- * @param language the language or null to remove - * @see RFC 5545 - * p.21 - */ - public void setLanguage(String language) { - replace(LANGUAGE, language); - } - - /** - *

- * Gets the MEMBER property values. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * groups that the attendee is a member of in the form of URIs. Typically, - * these are email URIs (for example, "mailto:mailinglist@example.com"). - *

- *

- * Changes to the returned list will update the {@link ICalParameters} - * object, and vice versa. - *

- * @return the groups or empty list if none are set - * @see RFC 5545 - * p.21-2 - */ - public List getMembers() { - return get(MEMBER); - } - - /** - *

- * Gets the PARTSTAT (participation status) parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * participation status of the attendee (for example, "ACCEPTED"). If none - * is defined, then the property should be treated as if this parameter was - * set to "NEEDS-ACTION". - *

- * @return the participation status or null if not set - * @see RFC 5545 - * p.22 - */ - public String getParticipationStatus() { - return first(PARTSTAT); - } - - /** - *

- * Gets the PARTSTAT (participation status) parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * participation status of the attendee (for example, "ACCEPTED"). If none - * is defined, then the property should be treated as if this parameter was - * set to "NEEDS-ACTION". - *

- * @param participationStatus the participation status or null to remove - * @see RFC 5545 - * p.22 - */ - public void setParticipationStatus(String participationStatus) { - replace(PARTSTAT, participationStatus); - } - - /** - *

- * Gets the RANGE parameter value. - *

- *

- * This parameter is used by the {@link RecurrenceId} property. It defines - * the effective range of recurrence instances that the property references. - *

- * @return the range or null if not set - * @see RFC 5545 - * p.23-4 - */ - public Range getRange() { - String value = first(RANGE); - return (value == null) ? null : Range.get(value); - } - - /** - *

- * Sets the RANGE parameter value. - *

- *

- * This parameter is used by the {@link RecurrenceId} property. It defines - * the effective range of recurrence instances that the property references. - *

- * @param range the range or null to remove - * @see RFC 5545 - * p.23-4 - */ - public void setRange(Range range) { - replace(RANGE, (range == null) ? null : range.getValue()); - } - - /** - *

- * Gets the RELATED parameter value. - *

- *

- * This parameter is used by the {@link Trigger} property. It defines the - * date-time field that the property's duration (if specified) is relative - * to (for example, the start date or the end date). - *

- * @return the related field or null if not set - * @see RFC 5545 - * p.24 - */ - public Related getRelated() { - String value = first(RELATED); - return (value == null) ? null : Related.get(value); - } - - /** - *

- * Sets the RELATED parameter value. - *

- *

- * This parameter is used by the {@link Trigger} property. It defines the - * date-time field that the property's duration (if specified) is relative - * to (for example, the start date or the end date). - *

- * @param related the related field or null to remove - * @see RFC 5545 - * p.24 - */ - public void setRelated(Related related) { - replace(RELATED, (related == null) ? null : related.getValue()); - } - - /** - *

- * Gets the RELTYPE (relationship type) parameter value. - *

- *

- * This parameter is used by the {@link RelatedTo} property. It defines the - * kind of relationship the property is describing (for example, a "child" - * relationship). - *

- * @return the relationship type or null if not set - * @see RFC 5545 - * p.25 - */ - public RelationshipType getRelationshipType() { - String value = first(RELTYPE); - return (value == null) ? null : RelationshipType.get(value); - } - - /** - *

- * Sets the RELTYPE (relationship type) parameter value. - *

- *

- * This parameter is used by the {@link RelatedTo} property. It defines the - * kind of relationship the property is describing (for example, a "child" - * relationship). - *

- * @param relationshipType the relationship type or null to remove - * @see RFC 5545 - * p.25 - */ - public void setRelationshipType(RelationshipType relationshipType) { - replace(RELTYPE, (relationshipType == null) ? null : relationshipType.getValue()); - } - - /** - *

- * Gets the ROLE parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * attendee's role and/or whether they must attend or not (for example, - * "OPT-PARTICIPANT" for "optional participant"). If none is defined, then - * the property should be treated as if this parameter was set to - * "REQ-PARTICIPANT" (required participant). - *

- * @return the role or null if not set - * @see RFC 5545 - * p.25 - * @see vCal 1.0 p.25 - */ - public String getRole() { - /* - * Note: The acceptable values for this parameter differs in vCal 1.0, - * which is why this method does not return an enum. - */ - return first(ROLE); - } - - /** - *

- * Sets the ROLE parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * attendee's role and/or whether they must attend or not (for example, - * "OPT-PARTICIPANT" for "optional participant"). If none is defined, then - * the property should be treated as if this parameter was set to - * "REQ-PARTICIPANT" (required participant). - *

- * @param role the role or null to remove - * @see RFC 5545 - * p.25 - * @see vCal 1.0 p.25 - */ - public void setRole(String role) { - replace(ROLE, role); - } - - /** - *

- * Gets the RSVP parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines - * whether the event organizer would like the attendee to reply with his or - * her intention of attending ("true" if the organizer would like a reply, - * "false" if not). If this parameter is not defined, then the property - * should be treated as if this parameter was set to "false". - *

- * @return the value or null if not set - * @see RFC 5545 - * p.26 - * @see vCal 1.0 p.25 - */ - public String getRsvp() { - /* - * Note: The acceptable values for this parameter differs in vCal 1.0, - * which is why this method does not return a boolean. - */ - return first(RSVP); - } - - /** - *

- * Sets the RSVP parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines - * whether the event organizer would like the attendee to reply with his or - * her intention of attending ("true" if the organizer would like a reply, - * "false" if not). If this parameter is not defined, then the property - * should be treated as if this parameter was set to "false". - *

- * @param rsvp the value or null to remove - * @see RFC 5545 - * p.26 - * @see vCal 1.0 p.25 - */ - public void setRsvp(String rsvp) { - replace(RSVP, rsvp); - } - - /** - *

- * Gets the SENT-BY parameter value. - *

- *

- * This parameter defines a URI which represents a person who is acting on - * behalf of the person that is defined in the property. Typically, the URI - * is an email URI (for example, "mailto:janedoe@example.com"). It is used - * by the {@link Attendee} and {@link Organizer} properties. - *

- * @return the URI or null if not set - * @see RFC 5545 - * p.27 - */ - public String getSentBy() { - return first(SENT_BY); - } - - /** - *

- * Sets the SENT-BY parameter value. - *

- *

- * This parameter defines a URI which represents a person who is acting on - * behalf of the person that is defined in the property. Typically, the URI - * is an email URI (for example, "mailto:janedoe@example.com"). It is used - * by the {@link Attendee} and {@link Organizer} properties. - *

- * @param uri the URI or null to remove - * @see RFC 5545 - * p.27 - */ - public void setSentBy(String uri) { - replace(SENT_BY, uri); - } - - /** - *

- * Gets the STATUS parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * status of the person's event invitation (for example, "TENTATIVE" if the - * person may or may not attend). It is only used in the vCal 1.0 standard. - *

- * @return the status or null if not set - * @see vCal 1.0 p.25 - */ - public String getStatus() { - return first(STATUS); - } - - /** - *

- * Sets the STATUS parameter value. - *

- *

- * This parameter is used by the {@link Attendee} property. It defines the - * status of the person's event invitation (for example, "TENTATIVE" if the - * person may or may not attend). It is only used in the vCal 1.0 standard. - *

- * @param status the status or null to remove - * @see vCal 1.0 p.25 - */ - public void setStatus(String status) { - replace(STATUS, status); - } - - /** - *

- * Gets the TZID (timezone ID) parameter value. - *

- *

- * This parameter is used by properties that contain date-time values. It - * defines the timezone that the property value is formatted in. It either - * references a timezone defined in a VTIMEZONE component, or contains an - * Olson timezone ID. To use an Olson timezone ID, the parameter value must - * be prepended with a "/" (for example, "/America/New_York"). - *

- * @return the timezone ID or null if not set - * @see RFC 5545 - * p.27-8 - */ - public String getTimezoneId() { - return first(TZID); - } - - /** - *

- * Sets the TZID (timezone ID) parameter value. - *

- *

- * This parameter is used by properties that contain date-time values. It - * defines the timezone that the property value is formatted in. It either - * references a timezone defined in a VTIMEZONE component, or contains an - * Olson timezone ID. To use an Olson timezone ID, the parameter value must - * be prepended with a "/" (for example, "/America/New_York"). - *

- * @param timezoneId the timezone ID or null to remove - * @see RFC 5545 - * p.27-8 - */ - public void setTimezoneId(String timezoneId) { - replace(TZID, timezoneId); - } - - /** - *

- * Gets the TYPE parameter value. - *

- *

- * This parameter defines the content type of the property value (for - * example, "WAVE" for an audio file). It is only used in the vCal 1.0 - * standard. - *

- * @return the type or null if not set - * @see vCal 1.0 p.27 - */ - public String getType() { - return first(TYPE); - } - - /** - *

- * Sets the TYPE parameter value. - *

- *

- * This parameter defines the content type of the property value (for - * example, "WAVE" for an audio file). It is only used in the vCal 1.0 - * standard. - *

- * @param type the type or null to remove - * @see vCal 1.0 p.27 - */ - public void setType(String type) { - replace(TYPE, type); - } - - /** - *

- * Gets the VALUE parameter value. - *

- *

- * This parameter defines the data type of the property value (for example, - * "date" if the property value is a date without a time component). It is - * used if the property accepts multiple values that have different data - * types. - *

- * @return the data type or null if not set - * @see RFC 5545 - * p.29-50 - */ - public ICalDataType getValue() { - String value = first(VALUE); - return (value == null) ? null : ICalDataType.get(value); - } - - /** - *

- * Sets the VALUE parameter value. - *

- *

- * This parameter defines the data type of the property value (for example, - * "date" if the property value is a date without a time component). It is - * used if the property accepts multiple values that have different data - * types. - *

- * @param dataType the data type or null to remove - * @see RFC 5545 - * p.29-50 - */ - public void setValue(ICalDataType dataType) { - replace(VALUE, (dataType == null) ? null : dataType.getName()); - } - - /** - *

- * Checks the parameters for data consistency problems or deviations from - * the specification. - *

- *

- * These problems will not prevent the iCalendar object from being written - * to a data stream*, but may prevent it from being parsed correctly by the - * consuming application. - *

- *

- * *With a few exceptions: One thing this method does is check for illegal - * characters. There are certain characters that will break the iCalendar - * syntax if written (such as a newline character in a parameter name). If - * one of these characters is present, it WILL prevent the iCalendar object - * from being written. - *

- * @param version the version to validate against - * @return a list of warnings or an empty list if no problems were found - */ - public List validate(ICalVersion version) { - List warnings = new ArrayList(0); - - SyntaxStyle syntax; - switch (version) { - case V1_0: - syntax = SyntaxStyle.OLD; - break; - default: - syntax = SyntaxStyle.NEW; - break; - } - - /* - * Check for invalid characters in names and values. - */ - for (Map.Entry> entry : this) { - String name = entry.getKey(); - - //check the parameter name - if (!VObjectValidator.validateParameterName(name, syntax, true)) { - if (syntax == SyntaxStyle.OLD) { - AllowedCharacters notAllowed = VObjectValidator.allowedCharactersParameterName(syntax, true).flip(); - warnings.add(new ValidationWarning(57, name, notAllowed.toString(true))); - } else { - warnings.add(new ValidationWarning(54, name)); - } - } - - //check the parameter value(s) - List values = entry.getValue(); - for (String value : values) { - if (!VObjectValidator.validateParameterValue(value, syntax, false, true)) { - AllowedCharacters notAllowed = VObjectValidator.allowedCharactersParameterValue(syntax, false, true).flip(); - int code = (syntax == SyntaxStyle.OLD) ? 58 : 53; - warnings.add(new ValidationWarning(code, name, value, notAllowed.toString(true))); - } - } - } - - final int nonStandardCode = 1, deprecated = 47; - - String value = first(RSVP); - if (value != null) { - value = value.toLowerCase(); - List validValues = Arrays.asList("true", "false", "yes", "no"); - if (!validValues.contains(value)) { - warnings.add(new ValidationWarning(nonStandardCode, RSVP, value, validValues)); - } - } - - value = first(CUTYPE); - if (value != null && CalendarUserType.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, CUTYPE, value, CalendarUserType.all())); - } - - value = first(ENCODING); - if (value != null && Encoding.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, ENCODING, value, Encoding.all())); - } - - value = first(FBTYPE); - if (value != null && FreeBusyType.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, FBTYPE, value, FreeBusyType.all())); - } - - value = first(PARTSTAT); - if (value != null && ParticipationStatus.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, PARTSTAT, value, ParticipationStatus.all())); - } - - value = first(RANGE); - if (value != null) { - Range range = Range.find(value); - - if (range == null) { - warnings.add(new ValidationWarning(nonStandardCode, RANGE, value, Range.all())); - } - - if (range == Range.THIS_AND_PRIOR && version == ICalVersion.V2_0) { - warnings.add(new ValidationWarning(deprecated, RANGE, value)); - } - } - - value = first(RELATED); - if (value != null && Related.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, RELATED, value, Related.all())); - } - - value = first(RELTYPE); - if (value != null && RelationshipType.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, RELTYPE, value, RelationshipType.all())); - } - - value = first(ROLE); - if (value != null && Role.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, ROLE, value, Role.all())); - } - - value = first(VALUE); - if (value != null && ICalDataType.find(value) == null) { - warnings.add(new ValidationWarning(nonStandardCode, VALUE, value, ICalDataType.all())); - } - - return warnings; - } - - @Override - protected String sanitizeKey(String key) { - return (key == null) ? null : key.toUpperCase(); - } - - @Override - public int hashCode() { - /* - * Remember: Keys are case-insensitive, key order does not matter, and - * value order does not matter - */ - final int prime = 31; - int result = 1; - - for (Map.Entry> entry : this) { - String key = entry.getKey(); - List value = entry.getValue(); - - int valueHash = 1; - for (String v : value) { - valueHash += v.toLowerCase().hashCode(); - } - - int entryHash = 1; - entryHash += prime * entryHash + ((key == null) ? 0 : key.toLowerCase().hashCode()); - entryHash += prime * entryHash + valueHash; - - result += entryHash; - } - - return result; - } - - /** - *

- * Determines whether the given object is logically equivalent to this list - * of parameters. - *

- *

- * Note that iCalendar parameter names are case-insensitive. Also, note that - * the order in which they are defined does not matter. - *

- * @param obj the object to compare to - * @return true if the objects are equal, false if not - */ - @Override - public boolean equals(Object obj) { - /* - * Remember: Keys are case-insensitive, key order does not matter, and - * value order does not matter - */ - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - ICalParameters other = (ICalParameters) obj; - if (size() != other.size()) return false; - - for (Map.Entry> entry : this) { - String key = entry.getKey(); - List value = entry.getValue(); - List otherValue = other.get(key); - - if (value.size() != otherValue.size()) { - return false; - } - - List valueLower = new ArrayList(value.size()); - for (String v : value) { - valueLower.add(v.toLowerCase()); - } - Collections.sort(valueLower); - - List otherValueLower = new ArrayList(otherValue.size()); - for (String v : otherValue) { - otherValueLower.add(v.toLowerCase()); - } - Collections.sort(otherValueLower); - - if (!valueLower.equals(otherValueLower)) { - return false; - } - } - - return true; - } - - /** - *

- * A list that converts the raw string values of a parameter to the - * appropriate {@link EnumParameterValue} object that some parameters use. - *

- *

- * This list is backed by the {@link ICalParameters} object. Any changes - * made to the list will affect the {@link ICalParameters} object and vice - * versa. - *

- * @param the enum parameter class - */ - public abstract class EnumParameterList extends ICalParameterList { - public EnumParameterList(String parameterName) { - super(parameterName); - } - - @Override - protected String _asString(T value) { - return value.getValue(); - } - } - - /** - *

- * A list that converts the raw string values of a parameter to another kind - * of value (for example, Integers). - *

- *

- * This list is backed by the {@link ICalParameters} object. Any changes - * made to the list will affect the {@link ICalParameters} object and vice - * versa. - *

- *

- * If a String value cannot be converted to the appropriate data type, an - * {@link IllegalStateException} is thrown. - *

- */ - public abstract class ICalParameterList extends AbstractList { - protected final String parameterName; - protected final List parameterValues; - - /** - * @param parameterName the name of the parameter (case insensitive) - */ - public ICalParameterList(String parameterName) { - this.parameterName = parameterName; - parameterValues = ICalParameters.this.get(parameterName); - } - - @Override - public void add(int index, T value) { - String valueStr = _asString(value); - parameterValues.add(index, valueStr); - } - - @Override - public T remove(int index) { - String removed = parameterValues.remove(index); - return asObject(removed); - } - - @Override - public T get(int index) { - String value = parameterValues.get(index); - return asObject(value); - } - - @Override - public T set(int index, T value) { - String valueStr = _asString(value); - String replaced = parameterValues.set(index, valueStr); - return asObject(replaced); - } - - @Override - public int size() { - return parameterValues.size(); - } - - private T asObject(String value) { - try { - return _asObject(value); - } catch (Exception e) { - throw new IllegalStateException(Messages.INSTANCE.getExceptionMessage(26, parameterName), e); - } - } - - /** - * Converts the object to a String value for storing in the - * {@link ICalParameters} object. - * @param value the value - * @return the string value - */ - protected abstract String _asString(T value); - - /** - * Converts a String value to its object form. - * @param value the string value - * @return the object - * @throws Exception if there is a problem parsing the string - */ - protected abstract T _asObject(String value) throws Exception; - } -} diff --git a/app/src/main/java/biweekly/parameter/ParticipationLevel.java b/app/src/main/java/biweekly/parameter/ParticipationLevel.java deleted file mode 100644 index 664e20179b..0000000000 --- a/app/src/main/java/biweekly/parameter/ParticipationLevel.java +++ /dev/null @@ -1,156 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.util.CaseClasses; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines what level of participation is expected from a calendar user. Note - * that this class does not correspond to a particular parameter. The parameter - * varies depending on the iCalendar version. - * @author Michael Angstadt - * @see RFC 5545 p.25-6 - * @see vCal 1.0 p.26-7 - */ -public class ParticipationLevel { - private static final CaseClasses enums = new CaseClasses(ParticipationLevel.class) { - @Override - protected ParticipationLevel create(String value) { - return new ParticipationLevel(value); - } - - @Override - protected boolean matches(ParticipationLevel object, String value) { - for (String v : object.values.values()) { - if (v.equalsIgnoreCase(value)) { - return true; - } - } - return false; - } - }; - - /** - * Indicates that the user's participation is required. - */ - public static final ParticipationLevel REQUIRED; - static { - Map values = new HashMap(); - values.put(ICalVersion.V1_0, "REQUIRE"); - values.put(ICalVersion.V2_0_DEPRECATED, "REQ-PARTICIPANT"); - values.put(ICalVersion.V2_0, values.get(ICalVersion.V2_0_DEPRECATED)); - REQUIRED = new ParticipationLevel(values); - } - - /** - * Indicates that the user's participation is optional. - */ - public static final ParticipationLevel OPTIONAL; - static { - Map values = new HashMap(); - values.put(ICalVersion.V1_0, "REQUEST"); - values.put(ICalVersion.V2_0_DEPRECATED, "OPT-PARTICIPANT"); - values.put(ICalVersion.V2_0, values.get(ICalVersion.V2_0_DEPRECATED)); - OPTIONAL = new ParticipationLevel(values); - } - - /** - * Indicates that the user has been notified about the event for - * informational purposes only and does not need to attend. - */ - public static final ParticipationLevel FYI; - static { - Map values = new HashMap(); - values.put(ICalVersion.V1_0, "FYI"); - values.put(ICalVersion.V2_0_DEPRECATED, "NON-PARTICIPANT"); - values.put(ICalVersion.V2_0, values.get(ICalVersion.V2_0_DEPRECATED)); - FYI = new ParticipationLevel(values); - } - - private final Map values; - - private ParticipationLevel(Map values) { - this.values = Collections.unmodifiableMap(values); - } - - private ParticipationLevel(String value) { - Map values = new HashMap(); - for (ICalVersion version : ICalVersion.values()) { - values.put(version, value); - } - this.values = Collections.unmodifiableMap(values); - } - - /** - * Gets the value of the parameter - * @param version the version - * @return the parameter value - */ - public String getValue(ICalVersion version) { - return values.get(version); - } - - @Override - public String toString() { - return getValue(ICalVersion.V2_0); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static ParticipationLevel find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static ParticipationLevel get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/ParticipationStatus.java b/app/src/main/java/biweekly/parameter/ParticipationStatus.java deleted file mode 100644 index 1430ff12c4..0000000000 --- a/app/src/main/java/biweekly/parameter/ParticipationStatus.java +++ /dev/null @@ -1,139 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -import biweekly.ICalVersion; -import biweekly.component.VEvent; -import biweekly.component.VJournal; -import biweekly.component.VTodo; -import biweekly.property.Attendee; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines a calendar user's level of participation. Used with the - * {@link Attendee} property. - * @author Michael Angstadt - * @see RFC 5545 p.22-3 - * @see vCal 1.0 p.25-6 - */ -public class ParticipationStatus extends VersionedEnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(ParticipationStatus.class); - - /** - * Indicates that the user needs to make a decision about the item. Valid - * within the {@link VEvent}, {@link VTodo}, {@link VJournal} components. - */ - public static final ParticipationStatus NEEDS_ACTION = new ParticipationStatus("NEEDS-ACTION"); - - /** - * Indicates that the user has accepted the item. Valid within the - * {@link VEvent}, {@link VTodo}, {@link VJournal} components. - */ - public static final ParticipationStatus ACCEPTED = new ParticipationStatus("ACCEPTED"); - - /** - * Indicates that the user has declined the item. Valid within the - * {@link VEvent}, {@link VTodo}, {@link VJournal} components. - */ - public static final ParticipationStatus DECLINED = new ParticipationStatus("DECLINED"); - - /** - * Indicates that the user has tentatively accepted the item. Valid within - * the {@link VEvent} and {@link VJournal} components. - */ - public static final ParticipationStatus TENTATIVE = new ParticipationStatus("TENTATIVE"); - - /** - * Indicates that the user has delegated the item to someone else. Valid - * within the {@link VEvent} and {@link VTodo} components. - */ - public static final ParticipationStatus DELEGATED = new ParticipationStatus("DELEGATED"); - - /** - * Indicates that the user has completed the item. Only valid within the - * {@link VTodo} component. - */ - public static final ParticipationStatus COMPLETED = new ParticipationStatus("COMPLETED"); - - /** - * Indicates that the user is in the process of completing the item. Only - * valid within the {@link VTodo} component. - */ - public static final ParticipationStatus IN_PROCESS = new ParticipationStatus("IN_PROCESS", ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - - /** - * Indicates that the user confirmed attendance. Only valid within the - * {@link VEvent} component of vCalendar version 1.0. - */ - public static final ParticipationStatus CONFIRMED = new ParticipationStatus("CONFIRMED", ICalVersion.V1_0); - - /** - * Indicates that the item was sent out to the user. Valid within - * {@link VEvent} and {@link VTodo} components of vCalendar version 1.0. - */ - public static final ParticipationStatus SENT = new ParticipationStatus("SENT", ICalVersion.V1_0); - - private ParticipationStatus(String value, ICalVersion... supportedVersions) { - super(value, supportedVersions); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static ParticipationStatus find(String value) { - if ("NEEDS ACTION".equalsIgnoreCase(value)) { //vCal - return NEEDS_ACTION; - } - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static ParticipationStatus get(String value) { - if ("NEEDS ACTION".equalsIgnoreCase(value)) { //vCal - return NEEDS_ACTION; - } - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/Range.java b/app/src/main/java/biweekly/parameter/Range.java deleted file mode 100644 index c479fb51fe..0000000000 --- a/app/src/main/java/biweekly/parameter/Range.java +++ /dev/null @@ -1,81 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -import biweekly.property.RecurrenceId; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the effective range of recurrence instances specified by the - * {@link RecurrenceId} property. This parameter is essentially deprecated. - * @author Michael Angstadt - * @see RFC 5545 p.23-4 - */ -public class Range extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(Range.class); - - public static final Range THIS_AND_FUTURE = new Range("THISANDFUTURE"); - - /** - * Deprecated in the latest iCal specification. - */ - public static final Range THIS_AND_PRIOR = new Range("THISANDPRIOR"); - - private Range(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static Range find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static Range get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/Related.java b/app/src/main/java/biweekly/parameter/Related.java deleted file mode 100644 index 9f72aecd89..0000000000 --- a/app/src/main/java/biweekly/parameter/Related.java +++ /dev/null @@ -1,75 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the date that an alarm trigger is relative to. - * @author Michael Angstadt - * @see RFC 5545 p.24 - */ -public class Related extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(Related.class); - - public static final Related START = new Related("START"); - - public static final Related END = new Related("END"); - - private Related(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static Related find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static Related get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/RelationshipType.java b/app/src/main/java/biweekly/parameter/RelationshipType.java deleted file mode 100644 index 4681729ac0..0000000000 --- a/app/src/main/java/biweekly/parameter/RelationshipType.java +++ /dev/null @@ -1,78 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the hierarchical relationship that a component has with another - * component. - * @author Michael Angstadt - * @see RFC 5545 p.25 - */ -public class RelationshipType extends EnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(RelationshipType.class); - - public static final RelationshipType PARENT = new RelationshipType("PARENT"); - - public static final RelationshipType CHILD = new RelationshipType("CHILD"); - - public static final RelationshipType SIBLING = new RelationshipType("SIBLING"); - - private RelationshipType(String value) { - super(value); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static RelationshipType find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static RelationshipType get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/Role.java b/app/src/main/java/biweekly/parameter/Role.java deleted file mode 100644 index 01b8d2aac8..0000000000 --- a/app/src/main/java/biweekly/parameter/Role.java +++ /dev/null @@ -1,124 +0,0 @@ -package biweekly.parameter; - -import java.util.Collection; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines the role that a calendar user holds. - * @author Michael Angstadt - * @see RFC 5545 p.25-6 - * @see vCal 1.0 p.25 - */ -public class Role extends VersionedEnumParameterValue { - private static final ICalParameterCaseClasses enums = new ICalParameterCaseClasses(Role.class); - - /** - *

- * Indicates that the user is the chair of the calendar entity. - *

- *

- * Supported versions: {@code 2.0} - *

- */ - public static final Role CHAIR = new Role("CHAIR", ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - - /** - *

- * Indicates that the user is an attendee of the calendar entity. - *

- *

- * Supported versions: {@code 1.0} - *

- */ - public static final Role ATTENDEE = new Role("ATTENDEE", ICalVersion.V1_0); - - /** - *

- * Indicates that the user is the organizer of the calendar entity. - *

- *

- * Supported versions: {@code 1.0} - *

- */ - public static final Role ORGANIZER = new Role("ORGANIZER", ICalVersion.V1_0); - - /** - *

- * Indicates that the user is the owner of the calendar entity. - *

- *

- * Supported versions: {@code 1.0} - *

- */ - public static final Role OWNER = new Role("OWNER", ICalVersion.V1_0); - - /** - *

- * Indicates that the user is a delegate of another attendee. - *

- *

- * Supported versions: {@code 1.0} - *

- */ - public static final Role DELEGATE = new Role("DELEGATE", ICalVersion.V1_0); - - private Role(String value, ICalVersion... versions) { - super(value, versions); - } - - /** - * Searches for a parameter value that is defined as a static constant in - * this class. - * @param value the parameter value - * @return the object or null if not found - */ - public static Role find(String value) { - return enums.find(value); - } - - /** - * Searches for a parameter value and creates one if it cannot be found. All - * objects are guaranteed to be unique, so they can be compared with - * {@code ==} equality. - * @param value the parameter value - * @return the object - */ - public static Role get(String value) { - return enums.get(value); - } - - /** - * Gets all of the parameter values that are defined as static constants in - * this class. - * @return the parameter values - */ - public static Collection all() { - return enums.all(); - } -} diff --git a/app/src/main/java/biweekly/parameter/VersionedEnumParameterValue.java b/app/src/main/java/biweekly/parameter/VersionedEnumParameterValue.java deleted file mode 100644 index e8a51bf058..0000000000 --- a/app/src/main/java/biweekly/parameter/VersionedEnumParameterValue.java +++ /dev/null @@ -1,62 +0,0 @@ -package biweekly.parameter; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - */ - -/** - * Represents a parameter whose values are supported by a variety of different - * iCalendar versions. - * @author Michael Angstadt - */ -public class VersionedEnumParameterValue extends EnumParameterValue { - private static final ICalVersion[] allVersions = ICalVersion.values(); - protected final ICalVersion[] supportedVersions; - - public VersionedEnumParameterValue(String value, ICalVersion... supportedVersions) { - super(value); - this.supportedVersions = (supportedVersions.length == 0) ? allVersions : supportedVersions; - } - - /** - * Determines if the parameter value is supported by the given iCalendar - * version. - * @param version the iCalendar version - * @return true if it is supported, false if not - */ - public boolean isSupported(ICalVersion version) { - for (ICalVersion supportedVersion : supportedVersions) { - if (supportedVersion == version) { - return true; - } - } - return false; - } -} diff --git a/app/src/main/java/biweekly/parameter/package-info.java b/app/src/main/java/biweekly/parameter/package-info.java deleted file mode 100644 index 66e11d67cb..0000000000 --- a/app/src/main/java/biweekly/parameter/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains classes related to property parameters. - */ -package biweekly.parameter; \ No newline at end of file diff --git a/app/src/main/java/biweekly/property/Action.java b/app/src/main/java/biweekly/property/Action.java deleted file mode 100644 index 1bd3fc769b..0000000000 --- a/app/src/main/java/biweekly/property/Action.java +++ /dev/null @@ -1,191 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the type of action to invoke when an alarm is triggered. - *

- * - *

- * Code sample (creating): - *

- * - *
- * Action action = Action.audio();
- * 
- * - *

- * Code sample (retrieving): - *

- * - *
- * ICalendar ical = ...
- * for (VAlarm alarm : ical.getAlarms()) {
- *   Action action = alarm.getAction();
- *   if (action.isAudio()) {
- *     //...
- *   } else if (action.isEmail()) {
- *     //...
- *   } else if (action.isDisplay()) {
- *     //...
- *   }
- * }
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.132-3 - * @see RFC 2445 p.126 - */ -public class Action extends EnumProperty { - public static final String AUDIO = "AUDIO"; - public static final String DISPLAY = "DISPLAY"; - public static final String EMAIL = "EMAIL"; - public static final String PROCEDURE = "PROCEDURE"; - - /** - * Creates an action property. Use of this constructor is discouraged and - * may put the property in an invalid state. Use one of the static factory - * methods instead. - * @param value the value (e.g. "AUDIO") - */ - public Action(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Action(Action original) { - super(original); - } - - /** - * Creates an "audio" action property. - * @return the property - */ - public static Action audio() { - return create(AUDIO); - } - - /** - * Determines if this property is an "audio" action. - * @return true if it's an "audio" action, false if not - */ - public boolean isAudio() { - return is(AUDIO); - } - - /** - * Creates an "display" action property. - * @return the property - */ - public static Action display() { - return create(DISPLAY); - } - - /** - * Determines if this property is an "display" action. - * @return true if it's an "display" action, false if not - */ - public boolean isDisplay() { - return is(DISPLAY); - } - - /** - * Creates an "email" action property. - * @return the property - */ - public static Action email() { - return create(EMAIL); - } - - /** - * Determines if this property is an "email" action. - * @return true if it's an "email" action, false if not - */ - public boolean isEmail() { - return is(EMAIL); - } - - /** - * Creates a "procedure" action property (vCal 1.0 only). - * @return the property - */ - public static Action procedure() { - return create(PROCEDURE); - } - - /** - * Determines if this property is a "procedure" action (vCal 1.0 only). - * @return true if it's a "procedure" action, false if not - */ - public boolean isProcedure() { - return is(PROCEDURE); - } - - private static Action create(String value) { - return new Action(value); - } - - @Override - protected Collection getStandardValues(ICalVersion version) { - switch (version) { - case V1_0: - return Arrays.asList(AUDIO, DISPLAY, EMAIL, PROCEDURE); - default: - return Arrays.asList(AUDIO, DISPLAY, EMAIL); - } - } - - @Override - protected Collection getValueSupportedVersions() { - if (value == null) { - return Collections.emptyList(); - } - - if (isAudio() || isDisplay() || isEmail()) { - return Arrays.asList(ICalVersion.values()); - } - if (isProcedure()) { - return Collections.singletonList(ICalVersion.V1_0); - } - - return Collections.emptyList(); - } - - @Override - public Action copy() { - return new Action(this); - } -} diff --git a/app/src/main/java/biweekly/property/Attachment.java b/app/src/main/java/biweekly/property/Attachment.java deleted file mode 100644 index 6fd106a56f..0000000000 --- a/app/src/main/java/biweekly/property/Attachment.java +++ /dev/null @@ -1,180 +0,0 @@ -package biweekly.property; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines an file attachment (such as an image or document) that is associated - * with the component to which it belongs. - *

- * - *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //from a byte array
- * byte[] data = ...
- * Attachment attach = new Attachment("image/png", data);
- * event.addAttachment(attach);
- * 
- * //from a file 
- * File file = new File("image.png");
- * attach = new Attachment("image/png", file);
- * event.addAttachment(attach);
- * 
- * //referencing a URL
- * attach = new Attachment("image/png", "http://example.com/image.png");
- * event.addAttachment(attach);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.80-1 - * @see RFC 2445 p.77-8 - * @see vCal 1.0 p.25 - */ -public class Attachment extends BinaryProperty { - private String contentId; - - /** - * Creates a new attachment. - * @param formatType the content-type of the data (e.g. "image/png") - * @param file the file to attach - * @throws IOException if there's a problem reading from the file - */ - public Attachment(String formatType, File file) throws IOException { - super(file); - setFormatType(formatType); - } - - /** - * Creates a new attachment. - * @param formatType the content-type of the data (e.g. "image/png") - * @param data the binary data - */ - public Attachment(String formatType, byte[] data) { - super(data); - setFormatType(formatType); - } - - /** - * Creates a new attachment. - * @param formatType the content-type of the data (e.g. "image/png") - * @param uri a URL pointing to the resource (e.g. - * "http://example.com/image.png") - */ - public Attachment(String formatType, String uri) { - super(uri); - setFormatType(formatType); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Attachment(Attachment original) { - super(original); - contentId = original.contentId; - } - - @Override - public void setData(byte[] data) { - super.setData(data); - contentId = null; - } - - @Override - public void setUri(String uri) { - super.setUri(uri); - contentId = null; - } - - /** - * Sets the content ID. - * @return the content ID or null if not set - */ - public String getContentId() { - return contentId; - } - - /** - * Sets the content ID. - * @param contentId the content ID - */ - public void setContentId(String contentId) { - this.contentId = contentId; - uri = null; - data = null; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (uri == null && data == null && contentId == null) { - warnings.add(new ValidationWarning(26)); - } - } - - @Override - protected Map toStringValues() { - Map values = super.toStringValues(); - values.put("contentId", contentId); - return values; - } - - @Override - public Attachment copy() { - return new Attachment(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((contentId == null) ? 0 : contentId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Attachment other = (Attachment) obj; - if (contentId == null) { - if (other.contentId != null) return false; - } else if (!contentId.equals(other.contentId)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Attendee.java b/app/src/main/java/biweekly/property/Attendee.java deleted file mode 100644 index 6459052c2f..0000000000 --- a/app/src/main/java/biweekly/property/Attendee.java +++ /dev/null @@ -1,422 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.component.VAlarm; -import biweekly.parameter.CalendarUserType; -import biweekly.parameter.ParticipationLevel; -import biweekly.parameter.ParticipationStatus; -import biweekly.parameter.Role; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines an attendee (such as a person attending an event). This property has - * different meanings depending on the component that it belongs to: - *

- *
    - *
  • {@link VAlarm} (with "EMAIL" action) - An email address that is to - * receive the alarm.
  • - *
  • All others - An attendee of the calendar entity.
  • - *
- * - *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Attendee attendee = Attendee.email("johndoe@example.com")
- * attendee.setCommonName("John Doe");
- * attendee.setRsvp(true);
- * attendee.setRole(Role.CHAIR);
- * attendee.setParticipationStatus(ParticipationStatus.ACCEPTED);
- * event.addAttendee(attendee);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.107-9 - * @see RFC 2445 - * p.102-4 - * @see vCal 1.0 p.25-7 - */ -public class Attendee extends ICalProperty { - private String name, email, uri; - private Role role; - private ParticipationLevel participationLevel; - private ParticipationStatus status; - private Boolean rsvp; - - /** - * Creates an attendee property. - * @param name the attendee's name (e.g. "John Doe") - * @param email the attendee's email (e.g. "jdoe@example.com") - */ - public Attendee(String name, String email) { - this(name, email, null); - } - - /** - * Creates an attendee property. - * @param name the attendee's name (e.g. "John Doe") - * @param email the attendee's email (e.g. "jdoe@example.com") - * @param uri a URI representing the attendee - */ - public Attendee(String name, String email, String uri) { - this.name = name; - this.email = email; - this.uri = uri; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Attendee(Attendee original) { - super(original); - name = original.name; - email = original.email; - uri = original.uri; - role = original.role; - participationLevel = original.participationLevel; - status = original.status; - rsvp = original.rsvp; - } - - /** - * Gets the attendee's email - * @return the email (e.g. "jdoe@company.com") - */ - public String getEmail() { - return email; - } - - /** - * Sets the attendee's email - * @param email the email (e.g. "jdoe@company.com") - */ - public void setEmail(String email) { - this.email = email; - } - - /** - * Gets a URI representing the attendee. - * @return the URI (e.g. "mailto:jdoe@company.com") - */ - public String getUri() { - return uri; - } - - /** - * Sets a URI representing the attendee. - * @param uri the URI (e.g. "mailto:jdoe@company.com") - */ - public void setUri(String uri) { - this.uri = uri; - } - - /** - *

- * Gets the type of user the attendee is (for example, an "individual" or a - * "room"). - *

- *

- * Supported versions: {@code 2.0} - *

- * @return the calendar user type or null if not set - * @see RFC 5545 - * p.16 - */ - public CalendarUserType getCalendarUserType() { - return parameters.getCalendarUserType(); - } - - /** - *

- * Sets the type of user the attendee is (for example, an "individual" or a - * "room"). - *

- *

- * Supported versions: {@code 2.0} - *

- * @param cutype the calendar user type or null to remove - * @see RFC 5545 - * p.16 - */ - public void setCalendarUserType(CalendarUserType cutype) { - parameters.setCalendarUserType(cutype); - } - - /** - *

- * Gets the list that holds the groups that the attendee is a member of. - *

- *

- * Supported versions: {@code 2.0} - *

- * @return the groups (this list is mutable). Typically, these are email - * address URIs (e.g. "mailto:mailinglist@example.com") - * @see RFC 5545 - * p.21-2 - */ - public List getMemberOf() { - return parameters.getMembers(); - } - - /** - * Gets an attendee's role (for example, "chair" or "attendee"). - * @return the role or null if not set - * @see RFC 5545 - * p.25-6 - * @see vCal 1.0 p.25 - */ - public Role getRole() { - return role; - } - - /** - * Sets an attendee's role (for example, "chair" or "attendee"). - * @param role the role or null to remove - * @see RFC 5545 - * p.25-6 - * @see vCal 1.0 p.25 - */ - public void setRole(Role role) { - this.role = role; - } - - /** - * Gets an attendee's level of participation. - * @return the participation level or null if not set - * @see RFC 5545 - * p.25-6 - * @see vCal 1.0 p.26-7 - */ - public ParticipationLevel getParticipationLevel() { - return participationLevel; - } - - /** - * Sets an attendee's level of participation. - * @param level the participation level or null to remove - * @see RFC 5545 - * p.25-6 - * @see vCal 1.0 p.26-7 - */ - public void setParticipationLevel(ParticipationLevel level) { - this.participationLevel = level; - } - - /** - * Gets an attendee's participation status - * @return the participation status or null if not set - * @see RFC 5545 - * p.22-3 - * @see vCal 1.0 p.25-6 - */ - public ParticipationStatus getParticipationStatus() { - return status; - } - - /** - * Sets an attendee's participation status. - * @param status the participation status or null to remove - * @see RFC 5545 - * p.22-3 - * @see vCal 1.0 p.25-6 - */ - public void setParticipationStatus(ParticipationStatus status) { - this.status = status; - } - - /** - * Gets whether the organizer requests a response from the attendee. - * @return true if an RSVP is requested, false if not, null if not set - * @see RFC 5545 - * p.26-7 - */ - public Boolean getRsvp() { - return rsvp; - } - - /** - * Sets whether the organizer requests a response from the attendee. - * @param rsvp true if an RSVP has been requested, false if not, null to - * remove - * @see RFC 5545 - * p.26-7 - */ - public void setRsvp(Boolean rsvp) { - this.rsvp = rsvp; - } - - /** - *

- * Gets the list containing the people who have delegated their - * responsibility to the attendee. - *

- *

- * Supported versions: {@code 2.0} - *

- * @return the delegators (this list is mutable). Typically, these are email - * URIs (e.g. "mailto:janedoe@example.com"). - * @see RFC 5545 - * p.17 - */ - public List getDelegatedFrom() { - return parameters.getDelegatedFrom(); - } - - /** - *

- * Gets the list containing the people to which the attendee has delegated - * his or her responsibility. - *

- *

- * Supported versions: {@code 2.0} - *

- * @return the delegatees (this list is mutable). Typically, these are email - * URIs (e.g. "mailto:janedoe@example.com"). - * @see RFC 5545 - * p.17-8 - */ - public List getDelegatedTo() { - return parameters.getDelegatedTo(); - } - - @Override - public String getSentBy() { - return super.getSentBy(); - } - - @Override - public void setSentBy(String uri) { - super.setSentBy(uri); - } - - @Override - public String getCommonName() { - return name; - } - - @Override - public void setCommonName(String commonName) { - this.name = commonName; - } - - @Override - public String getDirectoryEntry() { - return super.getDirectoryEntry(); - } - - @Override - public void setDirectoryEntry(String uri) { - super.setDirectoryEntry(uri); - } - - /** - * Gets the language that the common name is written in. - */ - @Override - public String getLanguage() { - return super.getLanguage(); - } - - /** - * Sets the language that the common name is written in. - */ - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - //TODO - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("name", name); - values.put("email", email); - values.put("uri", uri); - values.put("role", role); - values.put("participationLevel", participationLevel); - values.put("status", status); - values.put("rsvp", rsvp); - return values; - } - - @Override - public Attendee copy() { - return new Attendee(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((participationLevel == null) ? 0 : participationLevel.hashCode()); - result = prime * result + ((role == null) ? 0 : role.hashCode()); - result = prime * result + ((rsvp == null) ? 0 : rsvp.hashCode()); - result = prime * result + ((status == null) ? 0 : status.hashCode()); - result = prime * result + ((uri == null) ? 0 : uri.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Attendee other = (Attendee) obj; - if (email == null) { - if (other.email != null) return false; - } else if (!email.equals(other.email)) return false; - if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - if (participationLevel != other.participationLevel) return false; - if (role != other.role) return false; - if (rsvp == null) { - if (other.rsvp != null) return false; - } else if (!rsvp.equals(other.rsvp)) return false; - if (status != other.status) return false; - if (uri == null) { - if (other.uri != null) return false; - } else if (!uri.equals(other.uri)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/AudioAlarm.java b/app/src/main/java/biweekly/property/AudioAlarm.java deleted file mode 100644 index ec062665ab..0000000000 --- a/app/src/main/java/biweekly/property/AudioAlarm.java +++ /dev/null @@ -1,135 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Map; - -import biweekly.component.VAlarm; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines an alarm that will play an audio file when triggered. It is - * recommended that the {@link VAlarm} component be used to create alarms. - * @author Michael Angstadt - * @see vCal 1.0 p.27-8 - * @see VAlarm#audio - */ -public class AudioAlarm extends VCalAlarmProperty { - private String contentId, uri; - private byte[] data; - - public AudioAlarm() { - //empty - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public AudioAlarm(AudioAlarm original) { - super(original); - data = (original.data == null) ? null : original.data.clone(); - uri = original.uri; - contentId = original.contentId; - } - - public String getContentId() { - return contentId; - } - - public void setContentId(String contentId) { - this.contentId = contentId; - this.uri = null; - this.data = null; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - this.contentId = null; - this.data = null; - } - - public byte[] getData() { - return data; - } - - public void setData(byte[] data) { - this.data = data; - this.uri = null; - this.contentId = null; - } - - public String getType() { - return parameters.getType(); - } - - public void setType(String type) { - parameters.setType(type); - } - - @Override - protected Map toStringValues() { - Map values = super.toStringValues(); - values.put("data", (data == null) ? "null" : "length: " + data.length); - values.put("uri", uri); - values.put("contentId", contentId); - return values; - } - - @Override - public AudioAlarm copy() { - return new AudioAlarm(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((contentId == null) ? 0 : contentId.hashCode()); - result = prime * result + Arrays.hashCode(data); - result = prime * result + ((uri == null) ? 0 : uri.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - AudioAlarm other = (AudioAlarm) obj; - if (contentId == null) { - if (other.contentId != null) return false; - } else if (!contentId.equals(other.contentId)) return false; - if (uri == null) { - if (other.uri != null) return false; - } else if (!uri.equals(other.uri)) return false; - if (!Arrays.equals(data, other.data)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/BinaryProperty.java b/app/src/main/java/biweekly/property/BinaryProperty.java deleted file mode 100644 index 07ed72635b..0000000000 --- a/app/src/main/java/biweekly/property/BinaryProperty.java +++ /dev/null @@ -1,163 +0,0 @@ -package biweekly.property; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.Gobble; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * A property whose value is a binary resource (such as an image or document). - * @author Michael Angstadt - */ -public class BinaryProperty extends ICalProperty { - protected byte[] data; - protected String uri; - - /** - * Creates a new binary property. - * @param file a file containing the binary data - * @throws IOException if there's a problem reading from the file - */ - public BinaryProperty(File file) throws IOException { - this.data = new Gobble(file).asByteArray(); - } - - /** - * Creates a new binary property. - * @param data the binary data - */ - public BinaryProperty(byte[] data) { - this.data = data; - } - - /** - * Creates a new binary property. - * @param uri a URL pointing to the resource (e.g. - * "http://example.com/image.png") - */ - public BinaryProperty(String uri) { - this.uri = uri; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public BinaryProperty(BinaryProperty original) { - super(original); - data = (original.data == null) ? null : original.data.clone(); - uri = original.uri; - } - - /** - * Gets the property's binary data. - * @return the binary data or null if not set - */ - public byte[] getData() { - return data; - } - - /** - * Sets the property's binary data. - * @param data the binary data - */ - public void setData(byte[] data) { - this.data = data; - uri = null; - } - - /** - * Gets the property's URI. - * @return the URI (e.g. "http://example.com/image.png") or null if not set - */ - public String getUri() { - return uri; - } - - /** - * Sets the property's URI. - * @param uri the URI (e.g. "http://example.com/image.png") - */ - public void setUri(String uri) { - this.uri = uri; - data = null; - } - - @Override - public String getFormatType() { - return super.getFormatType(); - } - - @Override - public void setFormatType(String formatType) { - super.setFormatType(formatType); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (uri == null && data == null) { - warnings.add(new ValidationWarning(26)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("data", (data == null) ? "null" : "length: " + data.length); - values.put("uri", uri); - return values; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + Arrays.hashCode(data); - result = prime * result + ((uri == null) ? 0 : uri.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - BinaryProperty other = (BinaryProperty) obj; - if (uri == null) { - if (other.uri != null) return false; - } else if (!uri.equals(other.uri)) return false; - if (!Arrays.equals(data, other.data)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/CalendarScale.java b/app/src/main/java/biweekly/property/CalendarScale.java deleted file mode 100644 index e738915214..0000000000 --- a/app/src/main/java/biweekly/property/CalendarScale.java +++ /dev/null @@ -1,126 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the calendar system that this iCalendar object uses for all its date - * values. If none is specified, then the calendar is assumed to be in - * "gregorian" format. - *

- * - *

- * Code sample (creating): - *

- * - *
- * ICalendar ical = new ICalendar();
- * ical.setCalendarScale(CalendarScale.gregorian());
- * 
- * ical = new ICalendar();
- * ical.setCalendarScale(new CalendarScale("another-calendar-system"));
- * 
- * - *

- * Code sample (retrieving): - *

- * - *
- * ICalendar ical = ...
- * CalendarScale calscale = ical.getCalendarscale();
- * 
- * if (calscale.isGregorian()) {
- *   //...
- * } else {
- *   String value = calscale.getValue();
- *   //...
- * }
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.76-7 - * @see RFC 2445 p.73-4 - */ -public class CalendarScale extends EnumProperty { - public static final String GREGORIAN = "GREGORIAN"; - - /** - * Creates a new calendar scale property. Use of this constructor is - * discouraged and may put the property in an invalid state. Use one of the - * static factory methods instead. - * @param value the value of the property (e.g. "gregorian") - */ - public CalendarScale(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public CalendarScale(CalendarScale original) { - super(original); - } - - /** - * Creates a new property whose value is set to "gregorian". - * @return the new property - */ - public static CalendarScale gregorian() { - return new CalendarScale(GREGORIAN); - } - - /** - * Determines whether the property is set to "gregorian". - * @return true if it's set to "gregorian", false if not - */ - public boolean isGregorian() { - return is(GREGORIAN); - } - - @Override - protected Collection getStandardValues(ICalVersion version) { - return Collections.singletonList(GREGORIAN); - } - - @Override - protected Collection getValueSupportedVersions() { - if (value == null) { - return Collections.emptyList(); - } - return Arrays.asList(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } - - @Override - public CalendarScale copy() { - return new CalendarScale(this); - } -} diff --git a/app/src/main/java/biweekly/property/Categories.java b/app/src/main/java/biweekly/property/Categories.java deleted file mode 100644 index 17ff25845a..0000000000 --- a/app/src/main/java/biweekly/property/Categories.java +++ /dev/null @@ -1,98 +0,0 @@ -package biweekly.property; - -import java.util.List; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a list of keywords that describe the component to which it belongs. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Categories categories = new Categories("conference", "meeting");
- * event.addCategories(categories);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.81-2 - * @see RFC 2445 p.78-9 - * @see vCal 1.0 p.28 - * @see draft-ietf-calext-extensions-01 - * p.7 - */ -public class Categories extends ListProperty { - /** - * Creates a new categories property. - */ - public Categories() { - super(); - } - - /** - * Creates a new categories property. - * @param categories the categories to initialize the property with - */ - public Categories(String... categories) { - super(categories); - } - - /** - * Creates a new categories property. - * @param categories the categories to initialize the property with - */ - public Categories(List categories) { - super(categories); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Categories(Categories original) { - super(original); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Categories copy() { - return new Categories(this); - } -} diff --git a/app/src/main/java/biweekly/property/Classification.java b/app/src/main/java/biweekly/property/Classification.java deleted file mode 100644 index 1ba73b061f..0000000000 --- a/app/src/main/java/biweekly/property/Classification.java +++ /dev/null @@ -1,153 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the level of sensitivity of the iCalendar data. If not specified, the - * data should be considered "public". - *

- *

- * Code sample (creating): - *

- * - *
- * VEvent event = new VEvent();
- * event.setClassification(Classification.public_());
- * 
- * - *

- * Code sample (retrieving): - *

- * - *
- * ICalendar ical = ...
- * VEvent event = ical.getEvents().get(0);
- * 
- * Classification classification = event.getClassification();
- * if (classification.isPublic()) {
- *   //...
- * } else if (classification.isPrivate()) {
- *   //...
- * } else if (classification.isConfidential()) {
- *   //...
- * }
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.82-3 - * @see RFC 2445 - * p.79-80 - * @see vCal 1.0 p.28-9 - */ -public class Classification extends EnumProperty { - public static final String PUBLIC = "PUBLIC"; - public static final String PRIVATE = "PRIVATE"; - public static final String CONFIDENTIAL = "CONFIDENTIAL"; - - /** - * Creates a new classification property. Use the static factory methods to - * create a property with a standard classification level. - * @param classification the classification level (e.g. "PUBLIC") - */ - public Classification(String classification) { - super(classification); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Classification(Classification original) { - super(original); - } - - /** - * Creates a "public" classification property. - * @return the property - */ - public static Classification public_() { - return create(PUBLIC); - } - - /** - * Determines if the classification level is "public". - * @return true if it's "public", false if not - */ - public boolean isPublic() { - return is(PUBLIC); - } - - /** - * Creates a "private" classification property. - * @return the property - */ - public static Classification private_() { - return create(PRIVATE); - } - - /** - * Determines if the classification level is "private". - * @return true if it's "private", false if not - */ - public boolean isPrivate() { - return is(PRIVATE); - } - - /** - * Creates a "confidential" classification property. - * @return the property - */ - public static Classification confidential() { - return create(CONFIDENTIAL); - } - - /** - * Determines if the classification level is "confidential". - * @return true if it's "confidential", false if not - */ - public boolean isConfidential() { - return is(CONFIDENTIAL); - } - - private static Classification create(String classification) { - return new Classification(classification); - } - - @Override - protected Collection getStandardValues(ICalVersion version) { - return Arrays.asList(PUBLIC, PRIVATE, CONFIDENTIAL); - } - - @Override - public Classification copy() { - return new Classification(this); - } -} diff --git a/app/src/main/java/biweekly/property/Color.java b/app/src/main/java/biweekly/property/Color.java deleted file mode 100644 index cdd1c8f3ce..0000000000 --- a/app/src/main/java/biweekly/property/Color.java +++ /dev/null @@ -1,115 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a color that clients may use when displaying the component data. - * Clients may use this color in any way they wish. For example, they can use it - * as a background color. - *

- *

- * Acceptable values are defined in Section - * 4.3 of the CSS Color Module Level 3 Recommendation. For example, - * "aliceblue", "green", "navy". - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Color color = new Color("mistyrose");
- * event.setColor(color);
- * 
- * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.9 - */ -public class Color extends TextProperty { - /** - * Creates a color property. - * @param color the color name (case insensitive). Acceptable values are - * defined in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - */ - public Color(String color) { - super(color); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Color(Color original) { - super(original); - } - - /** - * Gets the value of this property. - * @return the value (case insensitive). Acceptable values are defined in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - */ - @Override - public String getValue() { - return super.getValue(); - } - - /** - * Sets the value of this property. - * @param value the value (case insensitive). Acceptable values are defined - * in Section 4.3 of the CSS Color Module Level 3 Recommendation. For - * example, "aliceblue", "green", "navy". - */ - @Override - public void setValue(String value) { - super.setValue(value); - } - - @Override - public Color copy() { - return new Color(this); - } - - @Override - protected int valueHashCode() { - return value.toLowerCase().hashCode(); - } - - @Override - protected boolean valueEquals(String otherValue) { - return value.equalsIgnoreCase(otherValue); - } -} diff --git a/app/src/main/java/biweekly/property/Comment.java b/app/src/main/java/biweekly/property/Comment.java deleted file mode 100644 index b0c70919b3..0000000000 --- a/app/src/main/java/biweekly/property/Comment.java +++ /dev/null @@ -1,87 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a free-text comment. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Comment comment = new Comment("Free text");
- * event.addComment(comment);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.83-4 - * @see RFC 2445 p.80-1 - */ -public class Comment extends TextProperty { - /** - * Creates a comment property. - * @param comment the comment - */ - public Comment(String comment) { - super(comment); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Comment(Comment original) { - super(original); - } - - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Comment copy() { - return new Comment(this); - } -} diff --git a/app/src/main/java/biweekly/property/Completed.java b/app/src/main/java/biweekly/property/Completed.java deleted file mode 100644 index c6033227ed..0000000000 --- a/app/src/main/java/biweekly/property/Completed.java +++ /dev/null @@ -1,71 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the date and time that a to-do task was completed. - *

- *

- * Code sample: - *

- * - *
- * VTodo todo = new VTodo();
- * 
- * Date datetime = ...
- * Completed completed = new Completed(datetime);
- * todo.setCompleted(completed);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.94-5 - * @see RFC 2445 p.90-1 - * @see vCal 1.0 p.29 - */ -public class Completed extends DateTimeProperty { - /** - * Creates a completed property. - * @param completed the completion date - */ - public Completed(Date completed) { - super(completed); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Completed(Completed original) { - super(original); - } - - @Override - public Completed copy() { - return new Completed(this); - } -} diff --git a/app/src/main/java/biweekly/property/Conference.java b/app/src/main/java/biweekly/property/Conference.java deleted file mode 100644 index ef833939eb..0000000000 --- a/app/src/main/java/biweekly/property/Conference.java +++ /dev/null @@ -1,132 +0,0 @@ -package biweekly.property; - -import java.util.List; - -import biweekly.parameter.Feature; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Contains information used for accessing a conference system. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Conference conference = new Conference("tel:+1-412-555-0123,,,654321");
- * conference.setLabel("Audio conference, access code=77869");
- * conference.getFeatures().add(Feature.AUDIO);
- * conference.getFeatures().add(Feature.PHONE);
- * event.addConference(conference);
- * 
- * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.11 - */ -public class Conference extends ICalProperty { - private String uri, text; - - /** - * Creates a conference property. - * @param uri the uri - */ - public Conference(String uri) { - this.uri = uri; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Conference(Conference original) { - super(original); - uri = original.uri; - text = original.text; - } - - /** - * Gets the URI value of this property. - * @return the URI value or null if not set - */ - public String getUri() { - return uri; - } - - /** - * Sets the value of this property to a URI. - * @param uri the URI - */ - public void setUri(String uri) { - this.uri = uri; - text = null; - } - - /** - * Gets the plain text value of this property. - * @return the plain text value or null if not set - */ - public String getText() { - return text; - } - - /** - * Sets the value of this property to a plain text value. - * @param text the plain text value - */ - public void setText(String text) { - this.text = text; - uri = null; - } - - /** - * Gets the list that holds the features that this conference supports (for - * example, audio and video). - * @return the features (this list is mutable) - */ - public List getFeatures() { - return parameters.getFeatures(); - } - - @Override - public String getLabel() { - return super.getLabel(); - } - - @Override - public void setLabel(String label) { - super.setLabel(label); - } - - @Override - public Conference copy() { - return new Conference(this); - } -} diff --git a/app/src/main/java/biweekly/property/Contact.java b/app/src/main/java/biweekly/property/Contact.java deleted file mode 100644 index 5b09611455..0000000000 --- a/app/src/main/java/biweekly/property/Contact.java +++ /dev/null @@ -1,96 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the contact information for a person or other entity (for example, - * the name of a business and its phone number). - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Contact contact = new Contact("Acme Co: (212) 555-1234");
- * event.addContact(contact);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.109-11 - * @see RFC 2445 - * p.104-6 - */ -public class Contact extends TextProperty { - /** - * Creates a contact property. - * @param contact the contact information (e.g. "Acme Co: (212) 555-1234") - */ - public Contact(String contact) { - super(contact); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Contact(Contact original) { - super(original); - } - - /** - * @return the URI (such as a URL to a vCard) or null if not set - */ - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - /** - * @param uri the URI (such as a URL to a vCard) or null to remove - */ - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Contact copy() { - return new Contact(this); - } -} diff --git a/app/src/main/java/biweekly/property/Created.java b/app/src/main/java/biweekly/property/Created.java deleted file mode 100644 index 72b9029e4f..0000000000 --- a/app/src/main/java/biweekly/property/Created.java +++ /dev/null @@ -1,72 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the time that the calendar information was initially created. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Date datetime = ...
- * Created created = new Created(datetime);
- * event.setCreated(created);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.136 - * @see RFC 2445 - * p.129-30 - * @see vCal 1.0 p.29 - */ -public class Created extends DateTimeProperty { - /** - * Creates a created property. - * @param date the creation date - */ - public Created(Date date) { - super(date); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Created(Created original) { - super(original); - } - - @Override - public Created copy() { - return new Created(this); - } -} diff --git a/app/src/main/java/biweekly/property/DateDue.java b/app/src/main/java/biweekly/property/DateDue.java deleted file mode 100644 index 587d2694e4..0000000000 --- a/app/src/main/java/biweekly/property/DateDue.java +++ /dev/null @@ -1,149 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the due date of a to-do task. - *

- *

- * Code sample (creating): - *

- * - *
- * VTodo todo = new VTodo();
- * 
- * //date and time
- * Date datetime = ...
- * DateDue due = new DateDue(datetime);
- * todo.setDateDue(due);
- * 
- * //date (without time component)
- * Date date = ...
- * due = new DateDue(date, false);
- * todo.setDateDue(due);
- * 
- * - *

- * Code sample (reading): - *

- * - *
- * ICalendar ical = ...
- * TimezoneInfo tzinfo = ical.getTimezoneInfo();
- * 
- * for (VTodo todo : ical.getTodos()) {
- *   DateDue due = todo.getDateDue();
- *   
- *   //get property value (ICalDate extends java.util.Date)
- *   ICalDate value = due.getValue();
- *   
- *   if (value.hasTime()) {
- *     //the value includes a time component
- *   } else {
- *     //the value is just a date
- *     //date object's time is set to "00:00:00" under local computer's default timezone
- *   }
- *   
- *   //gets the timezone that the property value was parsed under if you are curious about that
- *   TimeZone tz = tzinfo.getTimeZone(due);
- * }
- * 
- * - *

- * Code sample (using timezones): - *

- * - *
- * ICalendar ical = new ICalendar();
- * VTodo todo = new VTodo();
- * Date datetime = ...
- * DateDue due = new DateDue(datetime);
- * todo.setDateDue(due);
- * ical.addTodo(todo);
- * 
- * TimezoneAssignment tz = ...
- * 
- * //set the timezone of all date-time property values
- * //date-time property values are written in UTC by default
- * ical.getTimezoneInfo().setDefaultTimezone(tz);
- * 
- * //or set the timezone just for this property
- * ical.getTimezoneInfo().setTimezone(due, tz);
- * 
- * //finally, write the iCalendar object
- * ICalWriter writer = ...
- * writer.write(ical);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.96-7 - * @see RFC 2445 p.92-3 - * @see vCal 1.0 p.30 - */ -public class DateDue extends DateOrDateTimeProperty { - /** - * Creates a due date property. - * @param dueDate the due date - */ - public DateDue(Date dueDate) { - super(dueDate); - } - - /** - * Creates a due date property. - * @param dueDate the due date - * @param hasTime true if the value has a time component, false if it is - * strictly a date - */ - public DateDue(Date dueDate, boolean hasTime) { - super(dueDate, hasTime); - } - - /** - * Creates a due date property. - * @param dueDate the due date - */ - public DateDue(ICalDate dueDate) { - super(dueDate); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DateDue(DateDue original) { - super(original); - } - - @Override - public DateDue copy() { - return new DateDue(this); - } -} diff --git a/app/src/main/java/biweekly/property/DateEnd.java b/app/src/main/java/biweekly/property/DateEnd.java deleted file mode 100644 index 01f0ff41e0..0000000000 --- a/app/src/main/java/biweekly/property/DateEnd.java +++ /dev/null @@ -1,147 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the end date of an event or free/busy component. - *

- *

- * Code sample (creating): - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //date and time
- * Date datetime = ...
- * DateEnd dtend = new DateEnd(datetime);
- * event.setDateEnd(dtend);
- * 
- * //date (without time component)
- * Date date = ...
- * dtend = new DateEnd(date, false);
- * event.setDateEnd(dtend);
- * 
- * - *

- * Code sample (reading): - *

- * - *
- * ICalendar ical = ...
- * for (VEvent event : ical.getEvents()) {
- *   DateEnd dtend = event.getDateEnd();
- *   
- *   //get property value (ICalDate extends java.util.Date)
- *   ICalDate value = dtend.getValue();
- *   
- *   if (value.hasTime()) {
- *     //the value includes a time component
- *   } else {
- *     //the value is just a date
- *     //date object's time is set to "00:00:00" under local computer's default timezone
- *   }
- *   
- *   //gets the timezone that the property value was parsed under if you are curious about that
- *   TimeZone tz = tzinfo.getTimeZone(dtend);
- * }
- * 
- * - *

- * Code sample (using timezones): - *

- * - *
- * ICalendar ical = new ICalendar();
- * VEvent event = new VEvent();
- * Date datetime = ...
- * DateEnd dtend = new DateEnd(datetime);
- * event.setDateEnd(dtend);
- * ical.addEvent(event);
- * 
- * TimezoneAssignment tz = ...
- * 
- * //set the timezone of all date-time property values
- * //date-time property values are written in UTC by default
- * ical.getTimezoneInfo().setDefaultTimezone(tz);
- * 
- * //or set the timezone just for this property
- * ical.getTimezoneInfo().setTimezone(dtend, tz);
- * 
- * //finally, write the iCalendar object
- * ICalWriter writer = ...
- * writer.write(ical);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.95-6 - * @see RFC 2445 p.91-2 - * @see vCal 1.0 p.31 - */ -public class DateEnd extends DateOrDateTimeProperty { - /** - * Creates an end date property. - * @param endDate the end date - */ - public DateEnd(Date endDate) { - super(endDate); - } - - /** - * Creates an end date property. - * @param endDate the end date - * @param hasTime true if the value has a time component, false if it is - * strictly a date - */ - public DateEnd(Date endDate, boolean hasTime) { - super(endDate, hasTime); - } - - /** - * Creates an end date property. - * @param dateEnd the end date - */ - public DateEnd(ICalDate dateEnd) { - super(dateEnd); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DateEnd(DateEnd original) { - super(original); - } - - @Override - public DateEnd copy() { - return new DateEnd(this); - } -} diff --git a/app/src/main/java/biweekly/property/DateOrDateTimeProperty.java b/app/src/main/java/biweekly/property/DateOrDateTimeProperty.java deleted file mode 100644 index 87fdc04949..0000000000 --- a/app/src/main/java/biweekly/property/DateOrDateTimeProperty.java +++ /dev/null @@ -1,88 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is a date or a date-time. - * @author Michael Angstadt - */ -public class DateOrDateTimeProperty extends ValuedProperty { - /** - * Creates a new property. - * @param value the date-time value - */ - public DateOrDateTimeProperty(ICalDate value) { - super(value); - } - - /** - * Creates a new property. - * @param value the date-time value - */ - public DateOrDateTimeProperty(Date value) { - this(value, true); - } - - /** - * Creates a new property. - * @param value the date-time value - * @param hasTime true if the value has a time component, false if it is - * strictly a date - */ - public DateOrDateTimeProperty(Date value, boolean hasTime) { - this(createICalDate(value, hasTime)); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DateOrDateTimeProperty(DateOrDateTimeProperty original) { - super(original); - value = (original.value == null) ? null : new ICalDate(original.value); - } - - /** - * Sets the date-time value. - * @param value the date-time value - * @param hasTime true if the value has a time component, false if it is - * strictly a date - */ - public void setValue(Date value, boolean hasTime) { - setValue((value == null) ? null : new ICalDate(value, hasTime)); - } - - private static ICalDate createICalDate(Date value, boolean hasTime) { - if (value == null) { - return null; - } - return (value instanceof ICalDate) ? (ICalDate) value : new ICalDate(value, hasTime); - } -} diff --git a/app/src/main/java/biweekly/property/DateStart.java b/app/src/main/java/biweekly/property/DateStart.java deleted file mode 100644 index 31307f1a02..0000000000 --- a/app/src/main/java/biweekly/property/DateStart.java +++ /dev/null @@ -1,148 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the start date of an event, free/busy component, or timezone - * component. - *

- *

- * Code sample (creating): - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //date and time
- * Date datetime = ...
- * DateStart dtstart = new DateStart(datetime);
- * event.setDateStart(dtstart);
- * 
- * //date (without time component)
- * Date date = ...
- * dtstart = new DateStart(date, false);
- * event.setDateStart(dtstart);
- * 
- * - *

- * Code sample (reading): - *

- * - *
- * ICalendar ical = ...
- * for (VEvent event : ical.getEvents()) {
- *   DateStart dtstart = event.getDateStart();
- *   
- *   //get property value (ICalDate extends java.util.Date)
- *   ICalDate value = dtstart.getValue();
- *   
- *   if (value.hasTime()) {
- *     //the value includes a time component
- *   } else {
- *     //the value is just a date
- *     //date object's time is set to "00:00:00" under local computer's default timezone
- *   }
- *   
- *   //gets the timezone that the property value was parsed under if you are curious about that
- *   TimeZone tz = tzinfo.getTimeZone(dtstart);
- * }
- * 
- * - *

- * Code sample (using timezones): - *

- * - *
- * ICalendar ical = new ICalendar();
- * VEvent event = new VEvent();
- * Date datetime = ...
- * DateStart dtstart = new DateStart(datetime);
- * event.setDateStart(dtstart);
- * ical.addEvent(event);
- * 
- * TimezoneAssignment tz = ...
- * 
- * //set the timezone of all date-time property values
- * //date-time property values are written in UTC by default
- * ical.getTimezoneInfo().setDefaultTimezone(tz);
- * 
- * //or set the timezone just for this property
- * ical.getTimezoneInfo().setTimezone(dtstart, tz);
- * 
- * //finally, write the iCalendar object
- * ICalWriter writer = ...
- * writer.write(ical);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.97-8 - * @see RFC 2445 p.93-4 - * @see vCal 1.0 p.35 - */ -public class DateStart extends DateOrDateTimeProperty { - /** - * Creates a start date property. - * @param startDate the start date - */ - public DateStart(Date startDate) { - super(startDate); - } - - /** - * Creates a start date property. - * @param startDate the start date - * @param hasTime true if the value has a time component, false if it is - * strictly a date - */ - public DateStart(Date startDate, boolean hasTime) { - super(startDate, hasTime); - } - - /** - * Creates a start date property. - * @param startDate the start date - */ - public DateStart(ICalDate startDate) { - super(startDate); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DateStart(DateStart original) { - super(original); - } - - @Override - public DateStart copy() { - return new DateStart(this); - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/property/DateTimeProperty.java b/app/src/main/java/biweekly/property/DateTimeProperty.java deleted file mode 100644 index 22d4fe6e60..0000000000 --- a/app/src/main/java/biweekly/property/DateTimeProperty.java +++ /dev/null @@ -1,52 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is a date-time value. These properties are - * always written in UTC time. - * @author Michael Angstadt - */ -public class DateTimeProperty extends ValuedProperty { - /** - * Creates a new property. - * @param value the date-time value - */ - public DateTimeProperty(Date value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DateTimeProperty(DateTimeProperty original) { - super(original); - value = new Date(original.value.getTime()); - } -} diff --git a/app/src/main/java/biweekly/property/DateTimeStamp.java b/app/src/main/java/biweekly/property/DateTimeStamp.java deleted file mode 100644 index 341898f1e9..0000000000 --- a/app/src/main/java/biweekly/property/DateTimeStamp.java +++ /dev/null @@ -1,82 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * The meaning of this property varies depending on whether the iCalendar object - * has a {@link Method} property. - *

- *
    - *
  • Has a {@link Method} property: Defines the creation date of the - * iCalendar object itself (not the creation date of the actual calendar - * data from the originating data store). Use the {@link Created} property to - * define the creation date of the actual calendar data.
  • - *
  • Does not have a {@link Method} property: Defines the date that the - * calendar data was last updated (the {@link LastModified} property also holds - * this information).
  • - *
- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Date datetime = ... 
- * DateTimeStamp dtstamp = new DateTimeStamp(datetime);
- * event.setDateTimeStamp(dtstamp);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.137-8 - * @see RFC 2445 - * p.130-1 - */ -public class DateTimeStamp extends DateTimeProperty { - /** - * Creates a date time stamp property. - * @param date the date - */ - public DateTimeStamp(Date date) { - super(date); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DateTimeStamp(DateTimeStamp original) { - super(original); - } - - @Override - public DateTimeStamp copy() { - return new DateTimeStamp(this); - } -} diff --git a/app/src/main/java/biweekly/property/Daylight.java b/app/src/main/java/biweekly/property/Daylight.java deleted file mode 100644 index 2bd9314db4..0000000000 --- a/app/src/main/java/biweekly/property/Daylight.java +++ /dev/null @@ -1,247 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.ICalDate; -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents daylight savings time information. - * @author Michael Angstadt - * @see vCal 1.0 p.23 - */ -public class Daylight extends ICalProperty { - private boolean daylight; - private UtcOffset offset; - private ICalDate start, end; - private String standardName, daylightName; - - /** - * Creates a daylight savings property which states that the timezone does - * not observe daylight savings time. - */ - public Daylight() { - this.daylight = false; - } - - /** - * Creates a daylight savings property. - * @param daylight true if the timezone observes daylight savings time, - * false if not - * @param offset the UTC offset of daylight savings time - * @param start the start date of daylight savings time - * @param end the end date of daylight savings time - * @param standardName the timezone's name for standard time (e.g. "EST") - * @param daylightName the timezone's name for daylight savings time (e.g. - * "EDT") - */ - public Daylight(boolean daylight, UtcOffset offset, ICalDate start, ICalDate end, String standardName, String daylightName) { - this.daylight = daylight; - this.offset = offset; - this.start = start; - this.end = end; - this.standardName = standardName; - this.daylightName = daylightName; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Daylight(Daylight original) { - super(original); - daylight = original.daylight; - offset = original.offset; - start = (original.start == null) ? null : new ICalDate(original.start); - end = (original.end == null) ? null : new ICalDate(original.end); - standardName = original.standardName; - daylightName = original.daylightName; - } - - /** - * Gets whether this timezone observes daylight savings time. - * @return true if it observes daylight savings time, false if not - */ - public boolean isDaylight() { - return daylight; - } - - /** - * Sets whether this timezone observes daylight savings time. - * @param daylight true if it observes daylight savings time, false if not - */ - public void setDaylight(boolean daylight) { - this.daylight = daylight; - } - - /** - * Gets the UTC offset of daylight savings time. - * @return the UTC offset - */ - public UtcOffset getOffset() { - return offset; - } - - /** - * Sets the UTC offset of daylight savings time. - * @param offset the UTC offset - */ - public void setOffset(UtcOffset offset) { - this.offset = offset; - } - - /** - * Gets the start date of dayight savings time. - * @return the start date - */ - public ICalDate getStart() { - return start; - } - - /** - * Sets the start date of dayight savings time. - * @param start the start date - */ - public void setStart(ICalDate start) { - this.start = start; - } - - /** - * Gets the end date of daylight savings time. - * @return the end date - */ - public ICalDate getEnd() { - return end; - } - - /** - * Sets the end date of daylight savings time. - * @param end the end date - */ - public void setEnd(ICalDate end) { - this.end = end; - } - - /** - * Gets the name for standard time. - * @return the name (e.g. "EST") - */ - public String getStandardName() { - return standardName; - } - - /** - * Sets the name for standard time. - * @param name the name (e.g. "EST") - */ - public void setStandardName(String name) { - this.standardName = name; - } - - /** - * Gets the name of daylight savings time. - * @return the name (e.g. "EDT") - */ - public String getDaylightName() { - return daylightName; - } - - /** - * Sets the name of daylight savings time. - * @param name the name (e.g. "EDT") - */ - public void setDaylightName(String name) { - this.daylightName = name; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (daylight && (offset == null || start == null || end == null || standardName == null || daylightName == null)) { - warnings.add(new ValidationWarning(43)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("daylight", daylight); - values.put("offset", offset); - values.put("start", start); - values.put("end", end); - values.put("standardName", standardName); - values.put("daylightName", daylightName); - return values; - } - - @Override - public Daylight copy() { - return new Daylight(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + (daylight ? 1231 : 1237); - result = prime * result + ((daylightName == null) ? 0 : daylightName.hashCode()); - result = prime * result + ((end == null) ? 0 : end.hashCode()); - result = prime * result + ((offset == null) ? 0 : offset.hashCode()); - result = prime * result + ((standardName == null) ? 0 : standardName.hashCode()); - result = prime * result + ((start == null) ? 0 : start.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Daylight other = (Daylight) obj; - if (daylight != other.daylight) return false; - if (daylightName == null) { - if (other.daylightName != null) return false; - } else if (!daylightName.equals(other.daylightName)) return false; - if (end == null) { - if (other.end != null) return false; - } else if (!end.equals(other.end)) return false; - if (offset == null) { - if (other.offset != null) return false; - } else if (!offset.equals(other.offset)) return false; - if (standardName == null) { - if (other.standardName != null) return false; - } else if (!standardName.equals(other.standardName)) return false; - if (start == null) { - if (other.start != null) return false; - } else if (!start.equals(other.start)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Description.java b/app/src/main/java/biweekly/property/Description.java deleted file mode 100644 index 8ca952c1f5..0000000000 --- a/app/src/main/java/biweekly/property/Description.java +++ /dev/null @@ -1,102 +0,0 @@ -package biweekly.property; - -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a detailed description of the component that this property belongs - * to. The description should be a more detailed version of the text provided by - * the {@link Summary} property. - *

- *

- * If defined in the top-level {@link ICalendar} component, it contains a - * detailed description of the calendar as a whole. An iCalendar object can only - * have one description, but multiple Description properties can exist in order - * to specify the description in multiple languages. In this case, each property - * instance must be assigned a LANGUAGE parameter. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Description description = new Description("During this meeting, we will discuss...");
- * event.setDescription(description);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.84-5 - * @see RFC 2445 p.81-2 - * @see vCal 1.0 p.30 - * @see draft-ietf-calext-extensions-01 - * p.6 - */ -public class Description extends TextProperty { - /** - * Creates a description property. - * @param description the description - */ - public Description(String description) { - super(description); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Description(Description original) { - super(original); - } - - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Description copy() { - return new Description(this); - } -} diff --git a/app/src/main/java/biweekly/property/DisplayAlarm.java b/app/src/main/java/biweekly/property/DisplayAlarm.java deleted file mode 100644 index 07ee706e4d..0000000000 --- a/app/src/main/java/biweekly/property/DisplayAlarm.java +++ /dev/null @@ -1,101 +0,0 @@ -package biweekly.property; - -import java.util.Map; - -import biweekly.component.VAlarm; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines an alarm that displays a message when triggered. It is recommended - * that the {@link VAlarm} component be used to created alarms. - * @author Michael Angstadt - * @see vCal 1.0 p.30 - * @see VAlarm#display - */ -public class DisplayAlarm extends VCalAlarmProperty { - private String text; - - public DisplayAlarm(String text) { - this.text = text; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DisplayAlarm(DisplayAlarm original) { - super(original); - text = original.text; - } - - /** - * Gets the text to display when the alarm is triggered. - * @return the display text - */ - public String getText() { - return text; - } - - /** - * Sets the text to display when the alarm is triggered. - * @param text the display text - */ - public void setText(String text) { - this.text = text; - } - - @Override - protected Map toStringValues() { - Map values = super.toStringValues(); - values.put("text", text); - return values; - } - - @Override - public DisplayAlarm copy() { - return new DisplayAlarm(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((text == null) ? 0 : text.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - DisplayAlarm other = (DisplayAlarm) obj; - if (text == null) { - if (other.text != null) return false; - } else if (!text.equals(other.text)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/DurationProperty.java b/app/src/main/java/biweekly/property/DurationProperty.java deleted file mode 100644 index cbe7fd57ea..0000000000 --- a/app/src/main/java/biweekly/property/DurationProperty.java +++ /dev/null @@ -1,81 +0,0 @@ -package biweekly.property; - -import biweekly.component.VAlarm; -import biweekly.component.VEvent; -import biweekly.component.VTodo; -import biweekly.util.Duration; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a duration of time (for example, "2 hours and 30 minutes"). This - * property has different meanings depending on the component it belongs to: - *

- *
    - *
  • {@link VEvent} - The duration of the event (used in place of a - * {@link DateEnd} property).
  • - *
  • {@link VTodo} - The duration of the to-do task (used in place of a - * {@link DateEnd} property).
  • - *
  • {@link VAlarm} - The pause between alarm repetitions.
  • - *
- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Duration duration = Duration.builder().hours(2).minutes(30).build();
- * DurationProperty prop = new DurationProperty(duration);
- * event.setDuration(prop);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.99 - * @see RFC 2445 p.94-5 - */ -public class DurationProperty extends ValuedProperty { - /** - * Creates a duration property. - * @param duration the duration value (e.g. "2 hours and 30 minutes") - */ - public DurationProperty(Duration duration) { - super(duration); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public DurationProperty(DurationProperty original) { - super(original); - } - - @Override - public DurationProperty copy() { - return new DurationProperty(this); - } -} diff --git a/app/src/main/java/biweekly/property/EmailAlarm.java b/app/src/main/java/biweekly/property/EmailAlarm.java deleted file mode 100644 index a790521384..0000000000 --- a/app/src/main/java/biweekly/property/EmailAlarm.java +++ /dev/null @@ -1,123 +0,0 @@ -package biweekly.property; - -import java.util.Map; - -import biweekly.component.VAlarm; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines an alarm that sends an email when triggered. It is recommended that - * the {@link VAlarm} component be used to create alarms. - * @author Michael Angstadt - * @see vCal 1.0 p.32 - * @see VAlarm#email - */ -public class EmailAlarm extends VCalAlarmProperty { - private String email, note; - - public EmailAlarm(String email) { - this.email = email; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public EmailAlarm(EmailAlarm original) { - super(original); - email = original.email; - note = original.note; - } - - /** - * Gets the email address. - * @return the email address - */ - public String getEmail() { - return email; - } - - /** - * Sets the email address. - * @param email the email address - */ - public void setEmail(String email) { - this.email = email; - } - - /** - * Gets the note to send. - * @return the note - */ - public String getNote() { - return note; - } - - /** - * Sets the note to send - * @param note the note - */ - public void setNote(String note) { - this.note = note; - } - - @Override - protected Map toStringValues() { - Map values = super.toStringValues(); - values.put("email", email); - values.put("note", note); - return values; - } - - @Override - public EmailAlarm copy() { - return new EmailAlarm(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((note == null) ? 0 : note.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - EmailAlarm other = (EmailAlarm) obj; - if (email == null) { - if (other.email != null) return false; - } else if (!email.equals(other.email)) return false; - if (note == null) { - if (other.note != null) return false; - } else if (!note.equals(other.note)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/EnumProperty.java b/app/src/main/java/biweekly/property/EnumProperty.java deleted file mode 100644 index 81b377e000..0000000000 --- a/app/src/main/java/biweekly/property/EnumProperty.java +++ /dev/null @@ -1,125 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property that has a defined set of acceptable values (for - * example, the {@link Action} property). - * @author Michael Angstadt - */ -public abstract class EnumProperty extends TextProperty { - /** - * Creates an enum property. - * @param value the property value - */ - public EnumProperty(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public EnumProperty(EnumProperty original) { - super(original); - } - - /** - * Compares the property's value with a given string (case-insensitive). - * @param value the string - * @return true if it's equal, false if not - */ - protected boolean is(String value) { - return value.equalsIgnoreCase(this.value); - } - - /** - * Gets the list of acceptable values for this property. - * @param version the version - * @return the list of acceptable values - */ - protected abstract Collection getStandardValues(ICalVersion version); - - /** - * Gets the iCalendar versions that this property's value is supported in. - * Meant to be overridden by the child class. - * @return the supported versions - */ - protected Collection getValueSupportedVersions() { - return (value == null) ? Collections. emptyList() : Arrays.asList(ICalVersion.values()); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - if (value == null) { - return; - } - - Collection supportedVersions = getValueSupportedVersions(); - if (supportedVersions.isEmpty()) { - //it's a non-standard value - warnings.add(new ValidationWarning(28, value, getStandardValues(version))); - return; - } - - boolean supported = supportedVersions.contains(version); - if (!supported) { - warnings.add(new ValidationWarning(46, value, supportedVersions)); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + parameters.hashCode(); - result = prime * result + ((value == null) ? 0 : value.toLowerCase().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - EnumProperty other = (EnumProperty) obj; - if (!parameters.equals(other.parameters)) return false; - if (value == null) { - if (other.value != null) return false; - } else if (!value.equalsIgnoreCase(other.value)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/ExceptionDates.java b/app/src/main/java/biweekly/property/ExceptionDates.java deleted file mode 100644 index 13c63b44f5..0000000000 --- a/app/src/main/java/biweekly/property/ExceptionDates.java +++ /dev/null @@ -1,106 +0,0 @@ -package biweekly.property; - -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a list of exceptions to the dates specified in the - * {@link RecurrenceRule} property. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //dates with time components
- * ExceptionDates exdate = new ExceptionDates();
- * Date datetime = ...
- * exdate.getValues().add(new ICalDate(datetime, true));
- * event.addExceptionDates(exdate);
- * 
- * //dates without time components
- * exdate = new ExceptionDates();
- * Date date = ...
- * exdate.getValues().add(new ICalDate(date, false));
- * event.addExceptionDates(exdate);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.118-20 - * @see RFC 2445 - * p.112-4 - * @see vCal 1.0 p.31 - */ -public class ExceptionDates extends ListProperty { - public ExceptionDates() { - //empty - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public ExceptionDates(ExceptionDates original) { - super(original); - values.clear(); - for (ICalDate date : original.getValues()) { - values.add(new ICalDate(date)); - } - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - - List dates = getValues(); - if (dates.isEmpty()) { - return; - } - - //can't mix date and date-time values - boolean hasTime = dates.get(0).hasTime(); - for (ICalDate date : dates.subList(1, dates.size())) { - if (date.hasTime() != hasTime) { - warnings.add(new ValidationWarning(50)); - break; - } - } - } - - @Override - public ExceptionDates copy() { - return new ExceptionDates(this); - } -} diff --git a/app/src/main/java/biweekly/property/ExceptionRule.java b/app/src/main/java/biweekly/property/ExceptionRule.java deleted file mode 100644 index b94bbdea38..0000000000 --- a/app/src/main/java/biweekly/property/ExceptionRule.java +++ /dev/null @@ -1,91 +0,0 @@ -package biweekly.property; - -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.Recurrence; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a list of exceptions to the dates specified in the - * {@link RecurrenceRule} property. - *

- *

- * Note that this property has been removed from the latest version of the iCal - * specification. Its use should be avoided. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //"bi-weekly"
- * Recurrence recur = new Recurrence.Builder(Frequency.WEEKLY).interval(2).build();
- * ExceptionRule exrule = new ExceptionRule(recur);
- * event.addExceptionRule(exrule);
- * 
- * @author Michael Angstadt - * @see RFC 2445 - * p.114-15 - * @see vCal 1.0 p.31 - */ -public class ExceptionRule extends RecurrenceProperty { - /** - * Creates a new exception rule property. - * @param recur the recurrence rule - */ - public ExceptionRule(Recurrence recur) { - super(recur); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public ExceptionRule(ExceptionRule original) { - super(original); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - - if (version == ICalVersion.V2_0) { - warnings.add(new ValidationWarning(37)); - } - } - - @Override - public ExceptionRule copy() { - return new ExceptionRule(this); - } -} diff --git a/app/src/main/java/biweekly/property/FreeBusy.java b/app/src/main/java/biweekly/property/FreeBusy.java deleted file mode 100644 index 6bcc77b5d2..0000000000 --- a/app/src/main/java/biweekly/property/FreeBusy.java +++ /dev/null @@ -1,131 +0,0 @@ -package biweekly.property; - -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.parameter.FreeBusyType; -import biweekly.util.Period; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a person's availability over certain time periods (for example, - * "busy" between 1pm-3pm and 4pm-5pm). Note that this property can contain - * multiple time periods, but only one availability type may be defined (e.g. - * "busy" or "free"). - *

- *

- * Code sample: - *

- * - *
- * VFreeBusy fb = new VFreeBusy();
- * 
- * FreeBusy freebusy = new FreeBusy();
- * freebusy.setType(FreeBusyType.BUSY);
- * 
- * Date onePM = ...
- * Date threePM = ...
- * freebusy.getValues().add(new Period(onePM, threePM));
- * 
- * fb.addFreeBusy(freebusy);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.100-1 - * @see RFC 2445 p.95-6 - */ -public class FreeBusy extends ListProperty { - public FreeBusy() { - //empty - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public FreeBusy(FreeBusy original) { - super(original); - values.clear(); - for (Period period : original.values) { - values.add(new Period(period)); - } - } - - /** - * Gets the person's status over the time periods that are specified in this - * property (for example, "free" or "busy"). If not set, the user should be - * considered "busy". - * @return the type or null if not set - * @see RFC 5545 - * p.20 - */ - public FreeBusyType getType() { - return parameters.getFreeBusyType(); - } - - /** - * Sets the person's status over the time periods that are specified in this - * property (for example, "free" or "busy"). If not set, the user should be - * considered "busy". - * @param fbType the type or null to remove - * @see RFC 5545 - * p.20 - */ - public void setType(FreeBusyType fbType) { - parameters.setFreeBusyType(fbType); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - if (values.isEmpty()) { - return; - } - - for (Period timePeriod : values) { - if (timePeriod.getStartDate() == null) { - warnings.add(new ValidationWarning(39)); - break; - } - } - - for (Period timePeriod : values) { - if (timePeriod.getEndDate() == null && timePeriod.getDuration() == null) { - warnings.add(new ValidationWarning(40)); - break; - } - } - } - - @Override - public FreeBusy copy() { - return new FreeBusy(this); - } -} diff --git a/app/src/main/java/biweekly/property/Geo.java b/app/src/main/java/biweekly/property/Geo.java deleted file mode 100644 index d370046af6..0000000000 --- a/app/src/main/java/biweekly/property/Geo.java +++ /dev/null @@ -1,168 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a set of geographical coordinates. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Geo geo = new Geo(40.714623, -74.006605);
- * event.setGeo(geo);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.85-7 - * @see RFC 2445 p.82-3 - * @see vCal 1.0 p.23 - */ -public class Geo extends ICalProperty { - private Double latitude; - private Double longitude; - - /** - * Creates a new geo property. - * @param latitude the latitude - * @param longitude the longitude - */ - public Geo(Double latitude, Double longitude) { - this.latitude = latitude; - this.longitude = longitude; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Geo(Geo original) { - super(original); - latitude = original.latitude; - longitude = original.longitude; - } - - /** - * Gets the latitude. - * @return the latitude - */ - public Double getLatitude() { - return latitude; - } - - /** - * Sets the latitude. - * @param latitude the latitude - */ - public void setLatitude(Double latitude) { - this.latitude = latitude; - } - - /** - * Gets the longitude. - * @return the longitude - */ - public Double getLongitude() { - return longitude; - } - - /** - * Sets the longitude. - * @param longitude the longitude - */ - public void setLongitude(Double longitude) { - this.longitude = longitude; - } - - /** - * Converts a coordinate in the degrees-minutes-seconds format into its - * decimal equivalent. - * @param degrees the degrees - * @param minutes the minutes - * @param seconds the seconds - * @return the decimal value - */ - public static double toDecimal(int degrees, int minutes, int seconds) { - return degrees + (minutes / 60.0) + (seconds / 3600.0); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (latitude == null) { - warnings.add(new ValidationWarning(41)); - } - if (longitude == null) { - warnings.add(new ValidationWarning(42)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("latitude", latitude); - values.put("longitude", longitude); - return values; - } - - @Override - public Geo copy() { - return new Geo(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((latitude == null) ? 0 : latitude.hashCode()); - result = prime * result + ((longitude == null) ? 0 : longitude.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Geo other = (Geo) obj; - if (latitude == null) { - if (other.latitude != null) return false; - } else if (!latitude.equals(other.latitude)) return false; - if (longitude == null) { - if (other.longitude != null) return false; - } else if (!longitude.equals(other.longitude)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/ICalProperty.java b/app/src/main/java/biweekly/property/ICalProperty.java deleted file mode 100644 index 919dd98619..0000000000 --- a/app/src/main/java/biweekly/property/ICalProperty.java +++ /dev/null @@ -1,458 +0,0 @@ -package biweekly.property; - -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ICalendar; -import biweekly.Messages; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.parameter.ICalParameters; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Base class for all iCalendar property classes. - * @author Michael Angstadt - */ -public abstract class ICalProperty { - /** - * The property parameters. - */ - protected ICalParameters parameters; - - public ICalProperty() { - parameters = new ICalParameters(); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - protected ICalProperty(ICalProperty original) { - parameters = new ICalParameters(original.parameters); - } - - /** - * Gets the property's parameters. - * @return the parameters - */ - public ICalParameters getParameters() { - return parameters; - } - - /** - * Sets the property's parameters - * @param parameters the parameters (cannot be null) - */ - public void setParameters(ICalParameters parameters) { - if (parameters == null) { - throw new NullPointerException(Messages.INSTANCE.getExceptionMessage(16)); - } - this.parameters = parameters; - } - - /** - * Gets the first value of a parameter with the given name. - * @param name the parameter name (case insensitive, e.g. "LANGUAGE") - * @return the parameter value or null if not found - */ - public String getParameter(String name) { - return parameters.first(name); - } - - /** - * Gets all values of a parameter with the given name. - * @param name the parameter name (case insensitive, e.g. "LANGUAGE") - * @return the parameter values (this list is immutable) - */ - public List getParameters(String name) { - return Collections.unmodifiableList(parameters.get(name)); - } - - /** - * Adds a value to a parameter. - * @param name the parameter name (case insensitive, e.g. "LANGUAGE") - * @param value the parameter value - */ - public void addParameter(String name, String value) { - parameters.put(name, value); - } - - /** - * Replaces all existing values of a parameter with the given value. - * @param name the parameter name (case insensitive, e.g. "LANGUAGE") - * @param value the parameter value - */ - public void setParameter(String name, String value) { - parameters.replace(name, value); - } - - /** - * Replaces all existing values of a parameter with the given values. - * @param name the parameter name (case insensitive, e.g. "LANGUAGE") - * @param values the parameter values - */ - public void setParameter(String name, Collection values) { - parameters.replace(name, values); - } - - /** - * Removes a parameter from the property. - * @param name the parameter name (case insensitive, e.g. "LANGUAGE") - */ - public void removeParameter(String name) { - parameters.removeAll(name); - } - - /* - * Note: The following parameter helper methods are package-scoped so that - * property classes can choose which ones they want to make public on their - * Javadoc page. Doing this also allows for the methods' Javadocs to be - * defined in one place. - */ - - /** - * Gets a URI pointing to additional information about the entity - * represented by the property. - * @return the URI or null if not set - * @see RFC 5545 - * p.14-5 - */ - String getAltRepresentation() { - return parameters.getAltRepresentation(); - } - - /** - * Sets a URI pointing to additional information about the entity - * represented by the property. - * @param uri the URI or null to remove - * @see RFC 5545 - * p.14-5 - */ - void setAltRepresentation(String uri) { - parameters.setAltRepresentation(uri); - } - - /** - * Gets the content-type of the property's value. - * @return the content type (e.g. "image/png") or null if not set - * @see RFC 5545 - * p.19-20 - */ - String getFormatType() { - return parameters.getFormatType(); - } - - /** - * Sets the content-type of the property's value. - * @param formatType the content type (e.g. "image/png") or null to remove - * @see RFC 5545 - * p.19-20 - */ - void setFormatType(String formatType) { - parameters.setFormatType(formatType); - } - - /** - * Gets the human-readable label for this property. - * @return the label or null if not set - * @see draft-ietf-calext-extensions-01 - * p.16 - */ - String getLabel() { - return parameters.getLabel(); - } - - /** - * Sets the human-readable label for this property. - * @param label the label or null to remove - * @see draft-ietf-calext-extensions-01 - * p.16 - */ - void setLabel(String label) { - parameters.setLabel(label); - } - - /** - * Gets the language that the property value is written in. - * @return the language (e.g. "en" for English) or null if not set - * @see RFC 5545 - * p.21 - */ - String getLanguage() { - return parameters.getLanguage(); - } - - /** - * Sets the language that the property value is written in. - * @param language the language (e.g. "en" for English) or null to remove - * @see RFC 5545 - * p.21 - */ - void setLanguage(String language) { - parameters.setLanguage(language); - } - - /** - *

- * Gets a URI which represents a person who is acting on behalf of the - * person that is defined in this property. - *

- *

- * Supported versions: {@code 2.0} - *

- * @return a URI representing the person (typically, an email URI, e.g. - * "mailto:janedoe@example.com") or null if not set - * @see RFC 5545 - * p.27 - */ - String getSentBy() { - return parameters.getSentBy(); - } - - /** - *

- * Sets a URI which represents a person who is acting on behalf of the - * person that is defined in this property. - *

- *

- * Supported versions: {@code 2.0} - *

- * @param uri a URI representing the person (typically, an email URI, e.g. - * "mailto:janedoe@example.com") or null to remove - * @see RFC 5545 - * p.27 - */ - void setSentBy(String uri) { - parameters.setSentBy(uri); - } - - /** - *

- * Gets the human-readable, display name of the entity represented by this - * property. - *

- *

- * Supported versions: {@code 2.0} - *

- * @return the display name (e.g. "John Doe") or null if not set - * @see RFC 5545 - * p.15-6 - */ - String getCommonName() { - return parameters.getCommonName(); - } - - /** - *

- * Sets the human-readable, display name of the entity represented by this - * property. - *

- *

- * Supported versions: {@code 2.0} - *

- * @param commonName the display name (e.g. "John Doe") or null to remove - * @see RFC 5545 - * p.15-6 - */ - void setCommonName(String commonName) { - parameters.setCommonName(commonName); - } - - /** - *

- * Gets a URI that contains additional information about the person. - *

- *

- * Supported versions: {@code 2.0} - *

- * @return the URI (e.g. an LDAP URI) or null if not set - * @see RFC 5545 - * p.18 - */ - String getDirectoryEntry() { - return parameters.getDirectoryEntry(); - } - - /** - *

- * Sets a URI that contains additional information about the person. - *

- *

- * Supported versions: {@code 2.0} - *

- * @param uri the URI (e.g. an LDAP URI) or null to remove - * @see RFC 5545 - * p.18 - */ - void setDirectoryEntry(String uri) { - parameters.setDirectoryEntry(uri); - } - - /** - *

- * Checks the property for data consistency problems or deviations from the - * specifications. - *

- *

- * The existence of validation warnings will not prevent the property object - * from being written to a data stream. Syntactically-correct output will - * still be produced. However, the consuming application may have trouble - * interpreting some of the data due to the presence of these warnings. - *

- *

- * These problems can largely be avoided by reading the Javadocs of the - * component and property classes, or by being familiar with the iCalendar - * standard. - *

- * @param components the hierarchy of components that the property belongs - * to - * @param version the version to validate against - * @see ICalendar#validate(List, ICalVersion) - * @return a list of warnings or an empty list if no problems were found - */ - public final List validate(List components, ICalVersion version) { - //validate property value - List warnings = new ArrayList(0); - validate(components, version, warnings); - - //validate parameters - warnings.addAll(parameters.validate(version)); - - return warnings; - } - - /** - *

- * Checks the property for data consistency problems or deviations from the - * specifications. - *

- *

- * This method should be overridden by child classes that wish to provide - * validation logic. The default implementation of this method does nothing. - *

- * @param components the hierarchy of components that the property belongs - * to - * @param version the version to validate against - * @param warnings the list to add the warnings to - */ - protected void validate(List components, ICalVersion version, List warnings) { - //do nothing - } - - /** - *

- * Gets string representations of the class's fields for the - * {@link #toString} method. - *

- *

- * Meant to be overridden by child classes. The default implementation - * returns an empty map. - *

- * @return the values of the class's fields (key = field name, value = field - * value) - */ - protected Map toStringValues() { - return Collections.emptyMap(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getName()); - sb.append(" [ parameters=").append(parameters); - for (Map.Entry field : toStringValues().entrySet()) { - String fieldName = field.getKey(); - Object fieldValue = field.getValue(); - sb.append(" | ").append(fieldName).append('=').append(fieldValue); - } - sb.append(" ]"); - return sb.toString(); - } - - /** - *

- * Creates a copy of this property object. - *

- *

- * The default implementation of this method uses reflection to look for a - * copy constructor. Child classes SHOULD override this method to avoid the - * performance overhead involved in using reflection. - *

- *

- * The child class's copy constructor, if present, MUST invoke the - * {@link #ICalProperty(ICalProperty)} super constructor to ensure that the - * parameters are also copied. - *

- *

- * This method MUST be overridden by the child class if the child class does - * not have a copy constructor. Otherwise, an - * {@link UnsupportedOperationException} will be thrown when an attempt is - * made to copy the property (such as in the - * {@link ICalendar#ICalendar(ICalendar) ICalendar class's copy constructor} - * ). - *

- * @return the copy - * @throws UnsupportedOperationException if the class does not have a copy - * constructor or there is a problem invoking it - */ - public ICalProperty copy() { - Class clazz = getClass(); - - try { - Constructor copyConstructor = clazz.getConstructor(clazz); - return copyConstructor.newInstance(this); - } catch (Exception e) { - throw new UnsupportedOperationException(Messages.INSTANCE.getExceptionMessage(17, clazz.getName()), e); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + parameters.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - ICalProperty other = (ICalProperty) obj; - if (!parameters.equals(other.parameters)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Image.java b/app/src/main/java/biweekly/property/Image.java deleted file mode 100644 index de9b57cda4..0000000000 --- a/app/src/main/java/biweekly/property/Image.java +++ /dev/null @@ -1,146 +0,0 @@ -package biweekly.property; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.parameter.Display; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines an image that is associated with the component that the property - * belongs to. Multiple instances with different DISPLAY parameters can be added - * to the component to define different images for the client to display in - * different circumstances. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //from a byte array
- * byte[] data = ...
- * Image image = new Image("image/png", data);
- * image.getDisplays().add(Display.BADGE);
- * event.addImage(image);
- * 
- * //referencing a URL
- * image = new Image("image/png", "http://example.com/image.png");
- * image.getDisplays().add(Display.THUMBNAIL);
- * image.setOnClickUri("http://example.com");
- * event.addImage(image);
- * 
- * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.10 - */ -public class Image extends BinaryProperty { - /** - * Creates a new attachment. - * @param formatType the content-type of the data (e.g. "image/png") - * @param file the file to attach - * @throws IOException if there's a problem reading from the file - */ - public Image(String formatType, File file) throws IOException { - super(file); - setFormatType(formatType); - } - - /** - * Creates a new attachment. - * @param formatType the content-type of the data (e.g. "image/png") - * @param data the binary data - */ - public Image(String formatType, byte[] data) { - super(data); - setFormatType(formatType); - } - - /** - * Creates a new attachment. - * @param formatType the content-type of the data (e.g. "image/png") - * @param uri a URL pointing to the resource (e.g. - * "http://example.com/image.png") - */ - public Image(String formatType, String uri) { - super(uri); - setFormatType(formatType); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Image(Image original) { - super(original); - } - - /** - * Gets the URI to go to when the user clicks on the image. - * @return the URI or null if not set - */ - public String getOnClickUri() { - return parameters.getAltRepresentation(); - } - - /** - * Sets the URI to go to when the user clicks on the image. - * @param uri the URI or null to remove - */ - public void setOnClickUri(String uri) { - parameters.setAltRepresentation(uri); - } - - /** - * Gets the list that holds the ways in which the client should display this - * image (for example, as a thumbnail-sized image). - * @return the display methods (this list is mutable) - */ - public List getDisplays() { - return parameters.getDisplays(); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - if (data != null && getFormatType() == null) { - warnings.add(new ValidationWarning(56)); - } - } - - @Override - public Image copy() { - return new Image(this); - } -} diff --git a/app/src/main/java/biweekly/property/IntegerProperty.java b/app/src/main/java/biweekly/property/IntegerProperty.java deleted file mode 100644 index 04ae26c650..0000000000 --- a/app/src/main/java/biweekly/property/IntegerProperty.java +++ /dev/null @@ -1,48 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is an integer. - * @author Michael Angstadt - */ -public class IntegerProperty extends ValuedProperty { - /** - * Creates a new integer property. - * @param value the property's value - */ - public IntegerProperty(Integer value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public IntegerProperty(IntegerProperty original) { - super(original); - } -} diff --git a/app/src/main/java/biweekly/property/LastModified.java b/app/src/main/java/biweekly/property/LastModified.java deleted file mode 100644 index 9dcf65b0cf..0000000000 --- a/app/src/main/java/biweekly/property/LastModified.java +++ /dev/null @@ -1,74 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the time that the calendar data in a component was last changed. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Date datetime = ...
- * LastModified lastModified = new LastModified(datetime);
- * event.setLastModified(lastModified);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.138 - * @see RFC 2445 p.131 - * @see vCal 1.0 p.31 - * @see draft-ietf-calext-extensions-01 - * p.7 - */ -public class LastModified extends DateTimeProperty { - /** - * Creates a last modified property. - * @param date the date - */ - public LastModified(Date date) { - super(date); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public LastModified(LastModified original) { - super(original); - } - - @Override - public LastModified copy() { - return new LastModified(this); - } -} diff --git a/app/src/main/java/biweekly/property/ListProperty.java b/app/src/main/java/biweekly/property/ListProperty.java deleted file mode 100644 index 530e033db1..0000000000 --- a/app/src/main/java/biweekly/property/ListProperty.java +++ /dev/null @@ -1,120 +0,0 @@ -package biweekly.property; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.Messages; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is a list of values. - * @author Michael Angstadt - * @param the value type - */ -public class ListProperty extends ICalProperty { - protected final List values; - - /** - * Creates a new list property. - */ - public ListProperty() { - values = new ArrayList(); - } - - /** - * Creates a new list property. - * @param values the values to initialize the property with - */ - public ListProperty(T... values) { - this.values = new ArrayList(Arrays.asList(values)); - } - - /** - * Creates a new list property. - * @param values the values to initialize the property with (cannot be null) - */ - public ListProperty(List values) { - if (values == null) { - throw new NullPointerException(Messages.INSTANCE.getExceptionMessage(18)); - } - this.values = values; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public ListProperty(ListProperty original) { - super(original); - values = new ArrayList(original.values); - } - - /** - * Gets the list that holds the values of this property. - * @return the values list (this list is mutable) - */ - public List getValues() { - return values; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (values.isEmpty()) { - warnings.add(new ValidationWarning(26)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("values", this.values); - return values; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + values.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - ListProperty other = (ListProperty) obj; - if (!values.equals(other.values)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Location.java b/app/src/main/java/biweekly/property/Location.java deleted file mode 100644 index e60c9c95f4..0000000000 --- a/app/src/main/java/biweekly/property/Location.java +++ /dev/null @@ -1,88 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the physical location of an event. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Location location = new Location("Room 32B");
- * event.setLocation(location);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.87-8 - * @see RFC 2445 p.84 - * @see vCal 1.0 p.32 - */ -public class Location extends TextProperty { - /** - * Creates a location property. - * @param location the location (e.g. "Room 101") - */ - public Location(String location) { - super(location); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Location(Location original) { - super(original); - } - - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Location copy() { - return new Location(this); - } -} diff --git a/app/src/main/java/biweekly/property/Method.java b/app/src/main/java/biweekly/property/Method.java deleted file mode 100644 index c09e3fcd57..0000000000 --- a/app/src/main/java/biweekly/property/Method.java +++ /dev/null @@ -1,227 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Specifies the type of iTIP - * request that the iCalendar object represents. If the iCalendar object is just - * being used as a container to hold calendar information, then this property - * does not need to be defined. - *

- *

- * If the iCalendar object is defined as a MIME message entity, this property - * MUST be set to the value of the "Content-Type" header's "method" parameter, - * if present. - *

- *

- * Code sample: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * Method method = Method.request();
- * ical.setMethod(method);
- * 
- * @author Michael Angstadt - * @see RFC 5546 - * @see RFC 5545 p.77-8 - * @see RFC 2445 p.74-5 - */ -public class Method extends EnumProperty { - public static final String ADD = "ADD"; - public static final String CANCEL = "CANCEL"; - public static final String COUNTER = "COUNTER"; - public static final String DECLINECOUNTER = "DECLINECOUNTER"; - public static final String PUBLISH = "PUBLISH"; - public static final String REFRESH = "REFRESH"; - public static final String REPLY = "REPLY"; - public static final String REQUEST = "REQUEST"; - - /** - * Creates a new method property. - * @param value the property value - */ - public Method(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Method(Method original) { - super(original); - } - - /** - * Constructs a METHOD property whose value is "ADD". - * @return the property - */ - public static Method add() { - return create(ADD); - } - - /** - * Determines if this property's value is "ADD". - * @return true if the value is "ADD", false if not - */ - public boolean isAdd() { - return is(ADD); - } - - /** - * Constructs a METHOD property whose value is "CANCEL". - * @return the property - */ - public static Method cancel() { - return create(CANCEL); - } - - /** - * Determines if this property's value is "CANCEL". - * @return true if the value is "CANCEL", false if not - */ - public boolean isCancel() { - return is(CANCEL); - } - - /** - * Constructs a METHOD property whose value is "COUNTER". - * @return the property - */ - public static Method counter() { - return create(COUNTER); - } - - /** - * Determines if this property's value is "COUNTER". - * @return true if the value is "COUNTER", false if not - */ - public boolean isCounter() { - return is(COUNTER); - } - - /** - * Constructs a METHOD property whose value is "DECLINECOUNTER". - * @return the property - */ - public static Method declineCounter() { - return create(DECLINECOUNTER); - } - - /** - * Determines if this property's value is "DECLINECOUNTER". - * @return true if the value is "DECLINECOUNTER", false if not - */ - public boolean isDeclineCounter() { - return is(DECLINECOUNTER); - } - - /** - * Constructs a METHOD property whose value is "PUBLISH". - * @return the property - */ - public static Method publish() { - return create(PUBLISH); - } - - /** - * Determines if this property's value is "PUBLISH". - * @return true if the value is "PUBLISH", false if not - */ - public boolean isPublish() { - return is(PUBLISH); - } - - /** - * Constructs a METHOD property whose value is "REFRESH". - * @return the property - */ - public static Method refresh() { - return create(REFRESH); - } - - /** - * Determines if this property's value is "REFRESH". - * @return true if the value is "REFRESH", false if not - */ - public boolean isRefresh() { - return is(REFRESH); - } - - /** - * Constructs a METHOD property whose value is "REPLY". - * @return the property - */ - public static Method reply() { - return create(REPLY); - } - - /** - * Determines if this property's value is "REPLY". - * @return true if the value is "REPLY", false if not - */ - public boolean isReply() { - return is(REPLY); - } - - /** - * Constructs a METHOD property whose value is "REQUEST". - * @return the property - */ - public static Method request() { - return create(REQUEST); - } - - /** - * Determines if this property's value is "REQUEST". - * @return true if the value is "REQUEST", false if not - */ - public boolean isRequest() { - return is(REQUEST); - } - - private static Method create(String value) { - return new Method(value); - } - - @Override - protected Collection getStandardValues(ICalVersion version) { - return Arrays.asList(ADD, CANCEL, COUNTER, DECLINECOUNTER, PUBLISH, REFRESH, REPLY, REQUEST); - } - - @Override - public Method copy() { - return new Method(this); - } -} diff --git a/app/src/main/java/biweekly/property/Name.java b/app/src/main/java/biweekly/property/Name.java deleted file mode 100644 index 4591590bbd..0000000000 --- a/app/src/main/java/biweekly/property/Name.java +++ /dev/null @@ -1,111 +0,0 @@ -package biweekly.property; - -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a human-readable name for the calendar as a whole. - *

- *

- * An {@link ICalendar} component can only have one name, but multiple Name - * properties can exist in order to specify the name in multiple languages. In - * this case, each property instance must be assigned a LANGUAGE parameter. - *

- *

- * Single language: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * Name name = new Name("Company Vacation Days");
- * ical.addName(name);
- * 
- * - *

- * Multiple languages: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * Name englishName = new Name("Company Vacation Days");
- * englishName.setLanguage("en");
- * ical.addName(englishName);
- * 
- * Name frenchName = new Name("Société Jours de Vacances");
- * frenchName.setLanguage("fr");
- * ical.addName(frenchName);
- * 
- * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.5 - */ -public class Name extends TextProperty { - /** - * Creates a name property. - * @param name the name of the calendar - */ - public Name(String name) { - super(name); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Name(Name original) { - super(original); - } - - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Name copy() { - return new Name(this); - } -} diff --git a/app/src/main/java/biweekly/property/Organizer.java b/app/src/main/java/biweekly/property/Organizer.java deleted file mode 100644 index a9a1f7804e..0000000000 --- a/app/src/main/java/biweekly/property/Organizer.java +++ /dev/null @@ -1,206 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.Map; - -import biweekly.component.VEvent; -import biweekly.component.VFreeBusy; -import biweekly.component.VJournal; -import biweekly.component.VTodo; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * This property has different meanings depending on the component it belongs - * to: - *

- *
    - *
  • {@link VEvent} - The organizer of the event.
  • - *
  • {@link VTodo} - The creator of the to-do task.
  • - *
  • {@link VJournal} - The owner of the journal entry.
  • - *
  • {@link VFreeBusy} - The person requesting the free/busy time.
  • - *
- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Organizer organizer = Organizer.email("johndoe@example.com");
- * organizer.setCommonName("John Doe");
- * event.setOrganizer(organizer);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.111-2 - * @see RFC 2445 - * p.106-7 - */ -public class Organizer extends ICalProperty { - private String uri, email, name; - - /** - * Creates an organizer property - * @param name the organizer's name (e.g. "John Doe") - * @param email the organizer's email address (e.g. "jdoe@example.com") - */ - public Organizer(String name, String email) { - this.name = name; - this.email = email; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Organizer(Organizer original) { - super(original); - name = original.name; - email = original.email; - uri = original.uri; - } - - /** - * Gets the organizer's email - * @return the email (e.g. "jdoe@company.com") - */ - public String getEmail() { - return email; - } - - /** - * Sets the organizer's email - * @param email the email (e.g. "jdoe@company.com") - */ - public void setEmail(String email) { - this.email = email; - } - - /** - * Gets a URI representing the organizer. - * @return the URI (e.g. "mailto:jdoe@company.com") - */ - public String getUri() { - return uri; - } - - /** - * Sets a URI representing the organizer. - * @param uri the URI (e.g. "mailto:jdoe@company.com") - */ - public void setUri(String uri) { - this.uri = uri; - } - - @Override - public String getSentBy() { - return super.getSentBy(); - } - - @Override - public void setSentBy(String sentBy) { - super.setSentBy(sentBy); - } - - @Override - public String getCommonName() { - return name; - } - - @Override - public void setCommonName(String commonName) { - this.name = commonName; - } - - @Override - public String getDirectoryEntry() { - return super.getDirectoryEntry(); - } - - @Override - public void setDirectoryEntry(String directoryEntry) { - super.setDirectoryEntry(directoryEntry); - } - - /** - * Gets the language that the common name parameter is written in. - */ - @Override - public String getLanguage() { - return super.getLanguage(); - } - - /** - * Sets the language that the common name parameter is written in. - */ - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("name", name); - values.put("email", email); - values.put("uri", uri); - return values; - } - - @Override - public Organizer copy() { - return new Organizer(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((uri == null) ? 0 : uri.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Organizer other = (Organizer) obj; - if (email == null) { - if (other.email != null) return false; - } else if (!email.equals(other.email)) return false; - if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - if (uri == null) { - if (other.uri != null) return false; - } else if (!uri.equals(other.uri)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/PercentComplete.java b/app/src/main/java/biweekly/property/PercentComplete.java deleted file mode 100644 index a8a0e8c87e..0000000000 --- a/app/src/main/java/biweekly/property/PercentComplete.java +++ /dev/null @@ -1,81 +0,0 @@ -package biweekly.property; - -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a to-do task's level of completion. - *

- *

- * Code sample: - *

- * - *
- * VTodo todo = new VTodo();
- * 
- * PercentComplete percentComplete = new PercentComplete(50); //50%
- * todo.setPercentComplete(percentComplete);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.88-9 - * @see RFC 2445 p.85 - */ -public class PercentComplete extends IntegerProperty { - /** - * Creates a percent complete property. - * @param percent the percentage (e.g. "50" for 50%) - */ - public PercentComplete(Integer percent) { - super(percent); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public PercentComplete(PercentComplete original) { - super(original); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - if (value != null && (value < 0 || value > 100)) { - warnings.add(new ValidationWarning(29, value)); - } - } - - @Override - public PercentComplete copy() { - return new PercentComplete(this); - } -} diff --git a/app/src/main/java/biweekly/property/Priority.java b/app/src/main/java/biweekly/property/Priority.java deleted file mode 100644 index b4f149c190..0000000000 --- a/app/src/main/java/biweekly/property/Priority.java +++ /dev/null @@ -1,116 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the priority of an event or to-do task. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * event.setPriority(1); //highest
- * event.setPriority(9); //lowest
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.89-90 - * @see RFC 2445 p.85-7 - * @see vCal 1.0 p.33 - */ -public class Priority extends IntegerProperty { - /** - * Creates a priority property. - * @param priority the priority ("0" is undefined, "1" is the highest, "9" - * is the lowest) - */ - public Priority(Integer priority) { - super(priority); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Priority(Priority original) { - super(original); - } - - /** - * Determines if this priority is considered "high" priority. - * @return true if the priority is between 1 and 4, false if not - */ - public boolean isHigh() { - return value != null && value >= 1 && value <= 4; - } - - /** - * Determines if this priority is considered "medium" priority. - * @return true if the priority is "5", false if not - */ - public boolean isMedium() { - return value != null && value == 5; - } - - /** - * Determines if this priority is considered "low" priority. - * @return true if the priority is between 6 and 9, false if not - */ - public boolean isLow() { - return value != null && value >= 6 && value <= 9; - } - - /** - * Determines if this priority has an "undefined" value. - * @return true if the priority is "0", false if not - */ - public boolean isUndefined() { - return value != null && value == 0; - } - - /** - * Converts this priority to its two-character CUA code. - * @return the CUA code (e.g. "B1" for "4") or null if the priority cannot - * be converted to a CUA code - */ - public String toCuaPriority() { - if (value == null || value < 1 || value > 9) { - return null; - } - int letter = ((value - 1) / 3) + 'A'; - int number = ((value - 1) % 3) + 1; - return (char) letter + "" + number; - } - - @Override - public Priority copy() { - return new Priority(this); - } -} diff --git a/app/src/main/java/biweekly/property/ProcedureAlarm.java b/app/src/main/java/biweekly/property/ProcedureAlarm.java deleted file mode 100644 index 65bdf56d21..0000000000 --- a/app/src/main/java/biweekly/property/ProcedureAlarm.java +++ /dev/null @@ -1,107 +0,0 @@ -package biweekly.property; - -import java.util.Map; - -import biweekly.component.VAlarm; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines an alarm that executes a procedure when triggered. It is recommended - * that the {@link VAlarm} component be used to created alarms. - * @author Michael Angstadt - * @see vCal 1.0 p.33 - * @see VAlarm#procedure - */ -public class ProcedureAlarm extends VCalAlarmProperty { - private String path; - - /** - * @param path the path or name of the procedure to run when the alarm is - * triggered - */ - public ProcedureAlarm(String path) { - this.path = path; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public ProcedureAlarm(ProcedureAlarm original) { - super(original); - path = original.path; - } - - /** - * Gets the path or name of the procedure to run when the alarm is - * triggered. - * @return the path - */ - public String getPath() { - return path; - } - - /** - * Sets the path or name of the procedure to run when the alarm is - * triggered. - * @param path the path - */ - public void getPath(String path) { - this.path = path; - } - - @Override - protected Map toStringValues() { - Map values = super.toStringValues(); - values.put("path", path); - return values; - } - - @Override - public ProcedureAlarm copy() { - return new ProcedureAlarm(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((path == null) ? 0 : path.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - ProcedureAlarm other = (ProcedureAlarm) obj; - if (path == null) { - if (other.path != null) return false; - } else if (!path.equals(other.path)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/ProductId.java b/app/src/main/java/biweekly/property/ProductId.java deleted file mode 100644 index 4917262da7..0000000000 --- a/app/src/main/java/biweekly/property/ProductId.java +++ /dev/null @@ -1,79 +0,0 @@ -package biweekly.property; - -import biweekly.Biweekly; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Identifies the application that created the iCalendar object. - *

- *

- * Code sample: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * ProductId prodid = new ProductId("-//Company//Application Name//EN");
- * ical.setProductId(prodid);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.78-9 - * @see RFC 2445 p.75-6 - * @see vCal 1.0 p.24 - */ -public class ProductId extends TextProperty { - /** - * Creates a new product identifier property. - * @param value a unique string representing the application (e.g. - * "-//Company//Application Name//EN") - */ - public ProductId(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public ProductId(ProductId original) { - super(original); - } - - /** - * Creates a new product identifier property that represents this library. - * @return the property - */ - public static ProductId biweekly() { - return new ProductId("-//Michael Angstadt//biweekly " + Biweekly.VERSION + "//EN"); - } - - @Override - public ProductId copy() { - return new ProductId(this); - } -} diff --git a/app/src/main/java/biweekly/property/RawProperty.java b/app/src/main/java/biweekly/property/RawProperty.java deleted file mode 100644 index 1f7053e8ca..0000000000 --- a/app/src/main/java/biweekly/property/RawProperty.java +++ /dev/null @@ -1,183 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalDataType; -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -import com.github.mangstadt.vinnie.SyntaxStyle; -import com.github.mangstadt.vinnie.validate.AllowedCharacters; -import com.github.mangstadt.vinnie.validate.VObjectValidator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property that does not have a scribe associated with it. - * @author Michael Angstadt - */ -public class RawProperty extends ICalProperty { - private String name; - private ICalDataType dataType; - private String value; - - /** - * Creates a raw property. - * @param name the property name (e.g. "X-MS-ANNIVERSARY") - * @param value the property value - */ - public RawProperty(String name, String value) { - this(name, null, value); - } - - /** - * Creates a raw property. - * @param name the property name (e.g. "X-MS-ANNIVERSARY") - * @param dataType the property value's data type - * @param value the property value - */ - public RawProperty(String name, ICalDataType dataType, String value) { - this.name = name; - this.dataType = dataType; - this.value = value; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RawProperty(RawProperty original) { - super(original); - name = original.name; - dataType = original.dataType; - value = original.value; - } - - /** - * Gets the property value. - * @return the property value - */ - public String getValue() { - return value; - } - - /** - * Sets the property value. - * @param value the property value - */ - public void setValue(String value) { - this.value = value; - } - - /** - * Gets the property value's data type. - * @return the data type - */ - public ICalDataType getDataType() { - return dataType; - } - - /** - * Sets the property value's data type. - * @param dataType the data type - */ - public void setDataType(ICalDataType dataType) { - this.dataType = dataType; - } - - /** - * Gets the property name. - * @return the property name (e.g. "X-MS-ANNIVERSARY") - */ - public String getName() { - return name; - } - - /** - * Sets the property name. - * @param name the property name (e.g. "X-MS-ANNIVERSARY") - */ - public void setName(String name) { - this.name = name; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - SyntaxStyle syntax = version.getSyntaxStyle(); - AllowedCharacters allowed = VObjectValidator.allowedCharactersParameterName(syntax, true); - if (!allowed.check(name)) { - if (syntax == SyntaxStyle.OLD) { - AllowedCharacters notAllowed = allowed.flip(); - warnings.add(new ValidationWarning(59, name, notAllowed.toString(true))); - } else { - warnings.add(new ValidationWarning(52, name)); - } - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("name", name); - values.put("value", value); - values.put("dataType", dataType); - return values; - } - - @Override - public RawProperty copy() { - return new RawProperty(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((dataType == null) ? 0 : dataType.hashCode()); - result = prime * result + ((name == null) ? 0 : name.toLowerCase().hashCode()); - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - RawProperty other = (RawProperty) obj; - if (dataType != other.dataType) return false; - if (name == null) { - if (other.name != null) return false; - } else if (!name.equalsIgnoreCase(other.name)) return false; - if (value == null) { - if (other.value != null) return false; - } else if (!value.equals(other.value)) return false; - return true; - } - -} diff --git a/app/src/main/java/biweekly/property/RecurrenceDates.java b/app/src/main/java/biweekly/property/RecurrenceDates.java deleted file mode 100644 index 649428296a..0000000000 --- a/app/src/main/java/biweekly/property/RecurrenceDates.java +++ /dev/null @@ -1,180 +0,0 @@ -package biweekly.property; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.ICalDate; -import biweekly.util.Period; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a list of dates or time periods that help define a recurrence rule. - * It must contain either dates or time periods. It cannot contain a combination - * of both. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //date-time values
- * Date datetime = ...
- * RecurrenceDates rdate = new RecurrenceDates();
- * rdate.getDates().add(new ICalDate(datetime, true));
- * event.addRecurrenceDates(rdate);
- * 
- * //date values
- * Date date = ...
- * RecurrenceDates rdate = new RecurrenceDates();
- * rdate.getDates().add(new ICalDate(date, false));
- * event.addRecurrenceDates(rdate);
- * 
- * //periods
- * Period period = ...
- * rdate = new RecurrenceDates();
- * rdate.getPeriods().add(period);
- * event.addRecurrenceDates(rdate);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.120-2 - * @see RFC 2445 - * p.115-7 - * @see vCal 1.0 p.34 - */ -public class RecurrenceDates extends ICalProperty { - private final List dates; - private final List periods; - - public RecurrenceDates() { - dates = new ArrayList(); - periods = new ArrayList(); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RecurrenceDates(RecurrenceDates original) { - super(original); - - dates = new ArrayList(original.dates.size()); - for (ICalDate date : original.dates) { - dates.add(new ICalDate(date)); - } - - periods = new ArrayList(original.periods.size()); - for (Period period : original.periods) { - periods.add(new Period(period)); - } - } - - /** - * Gets the list that stores this property's recurrence dates. - * @return the dates (this list is mutable) - */ - public List getDates() { - return dates; - } - - /** - * Gets the list that stores this property's time periods. - * @return the time periods (this list is mutable) - */ - public List getPeriods() { - return periods; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (dates.isEmpty() && periods.isEmpty()) { - //no value - warnings.add(new ValidationWarning(26)); - } - - if (!dates.isEmpty() && !periods.isEmpty()) { - //can't mix dates and periods - warnings.add(new ValidationWarning(49)); - } - - if (version == ICalVersion.V1_0 && !periods.isEmpty()) { - //1.0 doesn't support periods - warnings.add(new ValidationWarning(51)); - } - - if (!dates.isEmpty()) { - //can't mix date and date-time values - boolean hasTime = dates.get(0).hasTime(); - for (ICalDate date : dates.subList(1, dates.size())) { - if (date.hasTime() != hasTime) { - warnings.add(new ValidationWarning(50)); - break; - } - } - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("dates", dates); - values.put("periods", periods); - return values; - } - - @Override - public RecurrenceDates copy() { - return new RecurrenceDates(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + dates.hashCode(); - result = prime * result + periods.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - RecurrenceDates other = (RecurrenceDates) obj; - if (!dates.equals(other.dates)) return false; - if (!periods.equals(other.periods)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/RecurrenceId.java b/app/src/main/java/biweekly/property/RecurrenceId.java deleted file mode 100644 index af1b260f11..0000000000 --- a/app/src/main/java/biweekly/property/RecurrenceId.java +++ /dev/null @@ -1,123 +0,0 @@ -package biweekly.property; - -import java.util.Date; - -import biweekly.parameter.Range; -import biweekly.util.ICalDate; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Records the original value of the {@link DateStart} property if a recurrence - * instance has been modified. It is used in conjunction with the {@link Uid} - * and {@link Sequence} properties to uniquely identify a recurrence instance. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * //date-time value
- * Date datetime = ...
- * RecurrenceId recurrenceId = new RecurrenceId(datetime);
- * event.setRecurrenceId(recurrenceId);
- * 
- * //date value
- * Date date = ...
- * RecurrenceId recurrenceId = new RecurrenceId(date, false);
- * event.setRecurrenceId(recurrenceId);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.112-4 - * @see RFC 2445 - * p.107-9 - */ -public class RecurrenceId extends DateOrDateTimeProperty { - /** - * Creates a recurrence ID property. - * @param originalStartDate the original start date - */ - public RecurrenceId(ICalDate originalStartDate) { - super(originalStartDate); - } - - /** - * Creates a recurrence ID property. - * @param originalStartDate the original start date - */ - public RecurrenceId(Date originalStartDate) { - super(originalStartDate); - } - - /** - * Creates a recurrence ID property. - * @param originalStartDate the original start date - * @param hasTime true to include the time component of the date, false not - * to - */ - public RecurrenceId(Date originalStartDate, boolean hasTime) { - super(originalStartDate, hasTime); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RecurrenceId(RecurrenceId original) { - super(original); - } - - /** - * Gets the effective range of recurrence instances from the instance - * specified by this property. - * @return the range or null if not set - * @see RFC 5545 - * p.23-4 - */ - public Range getRange() { - return parameters.getRange(); - } - - /** - * Sets the effective range of recurrence instances from the instance - * specified by this property. - * @param range the range or null to remove - * @see RFC 5545 - * p.23-4 - */ - public void setRange(Range range) { - parameters.setRange(range); - } - - @Override - public RecurrenceId copy() { - return new RecurrenceId(this); - } -} diff --git a/app/src/main/java/biweekly/property/RecurrenceProperty.java b/app/src/main/java/biweekly/property/RecurrenceProperty.java deleted file mode 100644 index f86040ae12..0000000000 --- a/app/src/main/java/biweekly/property/RecurrenceProperty.java +++ /dev/null @@ -1,133 +0,0 @@ -package biweekly.property; - -import java.util.Date; -import java.util.List; -import java.util.TimeZone; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.Frequency; -import biweekly.util.Google2445Utils; -import biweekly.util.ICalDate; -import biweekly.util.Recurrence; -import biweekly.util.com.google.ical.compat.javautil.DateIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is a recurrence rule. - * @author Michael Angstadt - */ -public class RecurrenceProperty extends ValuedProperty { - /** - * Creates a new recurrence property. - * @param recur the recurrence value - */ - public RecurrenceProperty(Recurrence recur) { - super(recur); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RecurrenceProperty(RecurrenceProperty original) { - super(original); - } - - /** - * Creates an iterator that computes the dates defined by this property. - * @param startDate the date that the recurrence starts (typically, the - * value of the accompanying {@link DateStart} property) - * @param timezone the timezone to iterate in (typically, the timezone - * associated with the {@link DateStart} property). This is needed in order - * to adjust for when the iterator passes over a daylight savings boundary. - * @return the iterator - * @see google-rfc-2445 - */ - public DateIterator getDateIterator(Date startDate, TimeZone timezone) { - return getDateIterator(new ICalDate(startDate), timezone); - } - - /** - * Creates an iterator that computes the dates defined by this property. - * @param startDate the date that the recurrence starts (typically, the - * value of the accompanying {@link DateStart} property) - * @param timezone the timezone to iterate in (typically, the timezone - * associated with the {@link DateStart} property). This is needed in order - * to adjust for when the iterator passes over a daylight savings boundary. - * @return the iterator - * @see google-rfc-2445 - */ - public DateIterator getDateIterator(ICalDate startDate, TimeZone timezone) { - Recurrence recur = getValue(); - return (recur == null) ? new Google2445Utils.EmptyDateIterator() : recur.getDateIterator(startDate, timezone); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - if (value == null) { - return; - } - - if (value.getFrequency() == null) { - warnings.add(new ValidationWarning(30)); - } - - if (value.getUntil() != null && value.getCount() != null) { - warnings.add(new ValidationWarning(31)); - } - - switch (version) { - case V1_0: - if (!value.getXRules().isEmpty()) { - warnings.add(new ValidationWarning("X-Rules are not supported by vCal.")); - } - if (!value.getBySetPos().isEmpty()) { - warnings.add(new ValidationWarning("BYSETPOS is not supported by vCal.")); - } - if (value.getFrequency() == Frequency.SECONDLY) { - warnings.add(new ValidationWarning(Frequency.SECONDLY.name() + " frequency is not supported by vCal.")); - } - break; - - case V2_0_DEPRECATED: - //empty - break; - - case V2_0: - if (!value.getXRules().isEmpty()) { - warnings.add(new ValidationWarning(32)); - } - - break; - } - } -} diff --git a/app/src/main/java/biweekly/property/RecurrenceRule.java b/app/src/main/java/biweekly/property/RecurrenceRule.java deleted file mode 100644 index 901194f7fd..0000000000 --- a/app/src/main/java/biweekly/property/RecurrenceRule.java +++ /dev/null @@ -1,73 +0,0 @@ -package biweekly.property; - -import biweekly.util.Recurrence; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines how often a component repeats. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Recurrence recur = new Recurrence.Builder(Frequency.WEEKLY).interval(2).build();
- * RecurrenceRule rrule = new RecurrenceRule(recur);
- * event.setRecurrenceRule(rruel);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.122-32 - * @see RFC 2445 - * p.117-25 - * @see vCal 1.0 p.34 - */ -public class RecurrenceRule extends RecurrenceProperty { - /** - * Creates a new recurrence rule property. - * @param recur the recurrence rule - */ - public RecurrenceRule(Recurrence recur) { - super(recur); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RecurrenceRule(RecurrenceRule original) { - super(original); - } - - @Override - public RecurrenceRule copy() { - return new RecurrenceRule(this); - } -} diff --git a/app/src/main/java/biweekly/property/RefreshInterval.java b/app/src/main/java/biweekly/property/RefreshInterval.java deleted file mode 100644 index b54d063f9e..0000000000 --- a/app/src/main/java/biweekly/property/RefreshInterval.java +++ /dev/null @@ -1,72 +0,0 @@ -package biweekly.property; - -import biweekly.util.Duration; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the suggested minimum polling interval for checking for updates to - * the calendar data. - *

- *

- * Code sample: - *

- * - *
- * ICalendar ical = new ICalendar()
- * 
- * Duration duration = Duration.builder().weeks(1).build();
- * RefreshInterval refreshInterval = new RefreshInterval(duration);
- * ical.setRefreshInterval(refreshInterval);
- * 
- * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.7 - */ -public class RefreshInterval extends ValuedProperty { - /** - * Creates a refresh interval property. - * @param duration the duration value (e.g. "2 hours and 30 minutes") - */ - public RefreshInterval(Duration duration) { - super(duration); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RefreshInterval(RefreshInterval original) { - super(original); - } - - @Override - public RefreshInterval copy() { - return new RefreshInterval(this); - } -} diff --git a/app/src/main/java/biweekly/property/RelatedTo.java b/app/src/main/java/biweekly/property/RelatedTo.java deleted file mode 100644 index 49e8c21ced..0000000000 --- a/app/src/main/java/biweekly/property/RelatedTo.java +++ /dev/null @@ -1,95 +0,0 @@ -package biweekly.property; - -import biweekly.parameter.RelationshipType; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a relationship between the component that this property belongs to - * and another component. - *

- *

- * Code samples: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * RelatedTo relatedTo = new RelatedTo("uid-value");
- * event.addRelatedTo(relatedTo);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.115-6 - * @see RFC 2445 - * p.109-10 - * @see vCal 1.0 p.33-4 - */ -public class RelatedTo extends TextProperty { - /** - * Creates a related-to property. - * @param uid the value of the {@link Uid} property of the component that - * this property is referencing - */ - public RelatedTo(String uid) { - super(uid); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RelatedTo(RelatedTo original) { - super(original); - } - - /** - * Gets the relationship type. - * @return the relationship type (e.g. "child") or null if not set - * @see RFC 5545 - * p.25 - */ - public RelationshipType getRelationshipType() { - return parameters.getRelationshipType(); - } - - /** - * Sets the relationship type. - * @param relationshipType the relationship type (e.g. "child") or null to - * remove - * @see RFC 5545 - * p.25 - */ - public void setRelationshipType(RelationshipType relationshipType) { - parameters.setRelationshipType(relationshipType); - } - - @Override - public RelatedTo copy() { - return new RelatedTo(this); - } -} diff --git a/app/src/main/java/biweekly/property/Repeat.java b/app/src/main/java/biweekly/property/Repeat.java deleted file mode 100644 index 766a9e8379..0000000000 --- a/app/src/main/java/biweekly/property/Repeat.java +++ /dev/null @@ -1,71 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the number of times an alarm should be repeated after its initial - * trigger. Used in conjunction with {@link DurationProperty}, which defines the - * length of the pause between repeats. - *

- *

- * Code sample: - *

- * - *
- * //repeat 5 more times after the first time
- * VAlarm alarm = ...;
- * alarm.setRepeat(5);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.133 - * @see RFC 2445 - * p.126-7 - */ -public class Repeat extends IntegerProperty { - /** - * Creates a repeat property. - * @param count the number of times to repeat the alarm (e.g. "2" to repeat - * it two more times after it was initially triggered, for a total of three - * times) - */ - public Repeat(Integer count) { - super(count); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Repeat(Repeat original) { - super(original); - } - - @Override - public Repeat copy() { - return new Repeat(this); - } -} diff --git a/app/src/main/java/biweekly/property/RequestStatus.java b/app/src/main/java/biweekly/property/RequestStatus.java deleted file mode 100644 index 42259bf7ba..0000000000 --- a/app/src/main/java/biweekly/property/RequestStatus.java +++ /dev/null @@ -1,217 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Represents a response to a scheduling request. - *

- *

- * This property must have a status code defined. The iCalendar specification - * defines the following status code families. However, these can have different - * meanings depending upon the type of scheduling request system being used - * (such as iTIP). - *

- *
    - *
  • 1.x - The request has been received, but is still being processed. - *
  • - *
  • 2.x - The request was processed successfully.
  • - *
  • 3.x - There is a client-side problem with the request (such as - * some incorrect syntax).
  • - *
  • 4.x - A scheduling error occurred on the server that prevented the - * request from being processed.
  • - *
- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * RequestStatus requestStatus = new RequestStatus("2.0");
- * requestStatus.setDescription("Success");
- * event.setRequestStatus(requestStatus);
- * 
- * @author Michael Angstadt - * @see RFC 5546 - * Section 3.6 - * @see RFC 5545 - * p.141-3 - * @see RFC 2445 - * p.134-6 - */ -public class RequestStatus extends ICalProperty { - private String statusCode, description, exceptionText; - - /** - * Creates a request status property. - * @param statusCode the status code (e.g. "1.1.3") - */ - public RequestStatus(String statusCode) { - setStatusCode(statusCode); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public RequestStatus(RequestStatus original) { - super(original); - statusCode = original.statusCode; - description = original.description; - exceptionText = original.exceptionText; - } - - /** - * Gets the status code. The following status code families are defined: - *
    - *
  • 1.x - The request has been received, but is still being - * processed.
  • - *
  • 2.x - The request was processed successfully.
  • - *
  • 3.x - There is a client-side problem with the request (such as - * some incorrect syntax).
  • - *
  • 4.x - A server-side error occurred.
  • - *
- * @return the status code (e.g. "1.1.3") - */ - public String getStatusCode() { - return statusCode; - } - - /** - * Sets a status code. The following status code families are defined: - *
    - *
  • 1.x - The request has been received, but is still being - * processed.
  • - *
  • 2.x - The request was processed successfully.
  • - *
  • 3.x - There is a client-side problem with the request (such as - * some incorrect syntax).
  • - *
  • 4.x - A server-side error occurred.
  • - *
- * @param statusCode the status code (e.g. "1.1.3") - */ - public void setStatusCode(String statusCode) { - this.statusCode = statusCode; - } - - /** - * Gets the human-readable description of the status. - * @return the description (e.g. "Success") or null if not set - */ - public String getDescription() { - return description; - } - - /** - * Sets a human-readable description of the status. - * @param description the description (e.g. "Success") or null to remove - */ - public void setDescription(String description) { - this.description = description; - } - - /** - * Gets any additional data related to the response. - * @return the additional data or null if not set - */ - public String getExceptionText() { - return exceptionText; - } - - /** - * Sets any additional data related to the response. - * @param exceptionText the additional data or null to remove - */ - public void setExceptionText(String exceptionText) { - this.exceptionText = exceptionText; - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (statusCode == null) { - warnings.add(new ValidationWarning(36)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("statusCode", statusCode); - values.put("description", description); - values.put("exceptionText", exceptionText); - return values; - } - - @Override - public RequestStatus copy() { - return new RequestStatus(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((description == null) ? 0 : description.hashCode()); - result = prime * result + ((exceptionText == null) ? 0 : exceptionText.hashCode()); - result = prime * result + ((statusCode == null) ? 0 : statusCode.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - RequestStatus other = (RequestStatus) obj; - if (description == null) { - if (other.description != null) return false; - } else if (!description.equals(other.description)) return false; - if (exceptionText == null) { - if (other.exceptionText != null) return false; - } else if (!exceptionText.equals(other.exceptionText)) return false; - if (statusCode == null) { - if (other.statusCode != null) return false; - } else if (!statusCode.equals(other.statusCode)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Resources.java b/app/src/main/java/biweekly/property/Resources.java deleted file mode 100644 index 78886d7030..0000000000 --- a/app/src/main/java/biweekly/property/Resources.java +++ /dev/null @@ -1,108 +0,0 @@ -package biweekly.property; - -import java.util.List; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a list of physical resources that are needed for an event or to-do - * task (for example, a "projector" or "DVD player"). - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Resources resources = new Resources("projector", "DVD player");
- * event.addResources(resources);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.91 - * @see RFC 2445 p.87-8 - * @see vCal 1.0 p.34-5 - */ -public class Resources extends ListProperty { - /** - * Creates a new resources property. - */ - public Resources() { - super(); - } - - /** - * Creates a new resources property. - * @param values the values to initialize the property with (e.g. "easel", - * "projector") - */ - public Resources(String... values) { - super(values); - } - - /** - * Creates a new resources property. - * @param values the values to initialize the property with (e.g. "easel", - * "projector") - */ - public Resources(List values) { - super(values); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Resources(Resources original) { - super(original); - } - - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Resources copy() { - return new Resources(this); - } -} diff --git a/app/src/main/java/biweekly/property/Sequence.java b/app/src/main/java/biweekly/property/Sequence.java deleted file mode 100644 index ea3d9a169f..0000000000 --- a/app/src/main/java/biweekly/property/Sequence.java +++ /dev/null @@ -1,82 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a revision number for an event, to-do task, or journal entry. This - * number can be incremented every time a significant change is made to the - * component. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = ...
- * event.setSequence(2);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.138-9 - * @see RFC 2445 - * p.131-3 - * @see vCal 1.0 p.35 - */ -public class Sequence extends IntegerProperty { - /** - * Creates a sequence property. - * @param sequence the sequence number (e.g. "0" for the initial version, - * "1" for the first revision, etc) - */ - public Sequence(Integer sequence) { - super(sequence); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Sequence(Sequence original) { - super(original); - } - - /** - * Increments the sequence number. - */ - public void increment() { - if (value == null) { - value = 1; - } else { - value++; - } - } - - @Override - public Sequence copy() { - return new Sequence(this); - } -} diff --git a/app/src/main/java/biweekly/property/Source.java b/app/src/main/java/biweekly/property/Source.java deleted file mode 100644 index 1a5e83e4c4..0000000000 --- a/app/src/main/java/biweekly/property/Source.java +++ /dev/null @@ -1,68 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a URI where the calendar data can be refreshed from. - *

- *

- * Code sample: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * Source source = new Source("http://example.com/holidays.ics");
- * ical.setSource(source);
- * 
- * @author Michael Angstadt - * @see draft-ietf-calext-extensions-01 - * p.8 - */ -public class Source extends TextProperty { - /** - * Creates a source property. - * @param uri the URI (e.g. "http://example.com/holidays.ics") - */ - public Source(String uri) { - super(uri); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Source(Source original) { - super(original); - } - - @Override - public Source copy() { - return new Source(this); - } -} diff --git a/app/src/main/java/biweekly/property/Status.java b/app/src/main/java/biweekly/property/Status.java deleted file mode 100644 index 498b77c2d2..0000000000 --- a/app/src/main/java/biweekly/property/Status.java +++ /dev/null @@ -1,347 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; - -import biweekly.ICalVersion; -import biweekly.component.VEvent; -import biweekly.component.VJournal; -import biweekly.component.VTodo; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the status of the component that this property belongs to, such as a - * to-do task being "completed". - *

- * - *

- * Code sample (creating): - *

- * - *
- * VTodo todo = new VTodo();
- * 
- * Status status = Status.completed();
- * todo.setStatus(status);
- * 
- * - *

- * Code sample (retrieving): - *

- * - *
- * ICalendar ical = ...
- * for (VTodo todo : ical.getTodos()) {
- *   Status status = todo.getStatus();
- *   if (action.isCompleted()) {
- *     //...
- *   } else if (action.isDraft()) {
- *     //...
- *   }
- *   //etc.
- * }
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.92-3 - * @see RFC 2445 p.88-9 - * @see vCal 1.0 p.35-6 - */ -public class Status extends EnumProperty { - //2.0 - public static final String CANCELLED = "CANCELLED"; - public static final String DRAFT = "DRAFT"; - public static final String FINAL = "FINAL"; - public static final String IN_PROGRESS = "IN-PROGRESS"; - - //1.0 - public static final String ACCEPTED = "ACCEPTED"; - public static final String DECLINED = "DECLINED"; - public static final String DELEGATED = "DELEGATED"; - public static final String SENT = "SENT"; - - //1.0 and 2.0 - public static final String COMPLETED = "COMPLETED"; - public static final String CONFIRMED = "CONFIRMED"; - public static final String NEEDS_ACTION = "NEEDS-ACTION"; - public static final String TENTATIVE = "TENTATIVE"; - - /** - * Creates a status property. Use of this constructor is discouraged and may - * put the property in an invalid state. Use one of the static factory - * methods instead. - * @param status the status (e.g. "TENTATIVE") - */ - public Status(String status) { - super(status); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Status(Status original) { - super(original); - } - - /** - * Creates a "tentative" status property (only valid for event components). - * @return the property - */ - public static Status tentative() { - return create(TENTATIVE); - } - - /** - * Determines if the status is set to "tentative". - * @return true if it is, false if not - */ - public boolean isTentative() { - return is(TENTATIVE); - } - - /** - * Creates a "confirmed" status property (only valid for event components). - * @return the property - */ - public static Status confirmed() { - return create(CONFIRMED); - } - - /** - * Determines if the status is set to "confirmed". - * @return true if it is, false if not - */ - public boolean isConfirmed() { - return is(CONFIRMED); - } - - /** - * Creates a "cancelled" status property (only valid in iCalendar 2.0 in - * {@link VEvent}, {@link VTodo}, and {@link VJournal} components). - * @return the property - */ - public static Status cancelled() { - return create(CANCELLED); - } - - /** - * Determines if the status is set to "cancelled". - * @return true if it is, false if not - */ - public boolean isCancelled() { - return is(CANCELLED); - } - - /** - * Creates a "needs-action" status property. - * @return the property - */ - public static Status needsAction() { - return create(NEEDS_ACTION); - } - - /** - * Determines if the status is set to "needs-action". - * @return true if it is, false if not - */ - public boolean isNeedsAction() { - return is(NEEDS_ACTION); - } - - /** - * Creates a "completed" status property (only valid in {@link VTodo} - * components). - * @return the property - */ - public static Status completed() { - return create(COMPLETED); - } - - /** - * Determines if the status is set to "completed". - * @return true if it is, false if not - */ - public boolean isCompleted() { - return is(COMPLETED); - } - - /** - * Creates a "in-progress" status property (only valid in iCalendar 2.0 in - * {@link VTodo} components). - * @return the property - */ - public static Status inProgress() { - return create(IN_PROGRESS); - } - - /** - * Determines if the status is set to "in-progress". - * @return true if it is, false if not - */ - public boolean isInProgress() { - return is(IN_PROGRESS); - } - - /** - * Creates a "draft" status property (only valid in iCalendar 2.0 in - * {@link VJournal} components). - * @return the property - */ - public static Status draft() { - return create(DRAFT); - } - - /** - * Determines if the status is set to "draft". - * @return true if it is, false if not - */ - public boolean isDraft() { - return is(DRAFT); - } - - /** - * Creates a "final" status property (only valid in iCalendar 2.0 in - * {@link VJournal} components). - * @return the property - */ - public static Status final_() { - return create(FINAL); - } - - /** - * Determines if the status is set to "final". - * @return true if it is, false if not - */ - public boolean isFinal() { - return is(FINAL); - } - - /** - * Creates an "accepted" status property (only valid in vCal 1.0 in - * {@link VTodo} components). - * @return the property - */ - public static Status accepted() { - return create(ACCEPTED); - } - - /** - * Determines if the status is set to "accepted". - * @return true if it is, false if not - */ - public boolean isAccepted() { - return is(ACCEPTED); - } - - /** - * Creates a "declined" status property (only valid in vCal 1.0). - * @return the property - */ - public static Status declined() { - return create(DECLINED); - } - - /** - * Determines if the status is set to "declined". - * @return true if it is, false if not - */ - public boolean isDeclined() { - return is(DECLINED); - } - - /** - * Creates a "delegated" status property (only valid in vCal 1.0). - * @return the property - */ - public static Status delegated() { - return create(DELEGATED); - } - - /** - * Determines if the status is set to "delegated". - * @return true if it is, false if not - */ - public boolean isDelegated() { - return is(DELEGATED); - } - - /** - * Creates a "sent" status property (only valid in vCal 1.0). - * @return the property - */ - public static Status sent() { - return create(SENT); - } - - /** - * Determines if the status is set to "sent". - * @return true if it is, false if not - */ - public boolean isSent() { - return is(SENT); - } - - public static Status create(String status) { - return new Status(status); - } - - @Override - protected Collection getStandardValues(ICalVersion version) { - switch (version) { - case V1_0: - return Arrays.asList(ACCEPTED, COMPLETED, CONFIRMED, DECLINED, DELEGATED, NEEDS_ACTION, SENT, TENTATIVE); - default: - return Arrays.asList(CANCELLED, COMPLETED, CONFIRMED, DRAFT, FINAL, IN_PROGRESS, NEEDS_ACTION, TENTATIVE); - } - } - - @Override - protected Collection getValueSupportedVersions() { - if (value == null) { - return Collections.emptyList(); - } - - if (isCompleted() || isConfirmed() || isNeedsAction() || isTentative()) { - return Arrays.asList(ICalVersion.values()); - } - if (isCancelled() || isDraft() || isFinal() || isInProgress()) { - return Arrays.asList(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0); - } - if (isAccepted() || isDeclined() || isDelegated() || isSent()) { - return Collections.singletonList(ICalVersion.V1_0); - } - - return Collections.emptyList(); - } - - @Override - public Status copy() { - return new Status(this); - } -} diff --git a/app/src/main/java/biweekly/property/Summary.java b/app/src/main/java/biweekly/property/Summary.java deleted file mode 100644 index 4f4b8c5513..0000000000 --- a/app/src/main/java/biweekly/property/Summary.java +++ /dev/null @@ -1,91 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a short, one line summary of the component that this property belongs - * to. The summary should be a more concise version of the text provided by the - * {@link Description} property. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Summary summary = new Summary("Team Meeting");
- * event.setSummary(summary);
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.93-4 - * @see RFC 2445 - * p.89-90 - * @see vCal 1.0 p.36 - */ -public class Summary extends TextProperty { - /** - * Creates a new summary property. - * @param summary the summary - */ - public Summary(String summary) { - super(summary); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Summary(Summary original) { - super(original); - } - - @Override - public String getAltRepresentation() { - return super.getAltRepresentation(); - } - - @Override - public void setAltRepresentation(String uri) { - super.setAltRepresentation(uri); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public Summary copy() { - return new Summary(this); - } -} diff --git a/app/src/main/java/biweekly/property/TextProperty.java b/app/src/main/java/biweekly/property/TextProperty.java deleted file mode 100644 index 80aa8ab95f..0000000000 --- a/app/src/main/java/biweekly/property/TextProperty.java +++ /dev/null @@ -1,49 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is a plain-text string. Note that this - * includes both text and URI values. - * @author Michael Angstadt - */ -public class TextProperty extends ValuedProperty { - /** - * Creates a new text property. - * @param value the property's value - */ - public TextProperty(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public TextProperty(TextProperty original) { - super(original); - } -} diff --git a/app/src/main/java/biweekly/property/Timezone.java b/app/src/main/java/biweekly/property/Timezone.java deleted file mode 100644 index eb8269146d..0000000000 --- a/app/src/main/java/biweekly/property/Timezone.java +++ /dev/null @@ -1,74 +0,0 @@ -package biweekly.property; - -import java.util.List; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - */ - -/** - * Defines the local timezone. - * @author Michael Angstadt - * @see vCal 1.0 p.24 - */ -public class Timezone extends UtcOffsetProperty { - /** - * Creates a timezone property. - * @param offset the UTC offset - */ - public Timezone(UtcOffset offset) { - super(offset); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Timezone(Timezone original) { - super(original); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - super.validate(components, version, warnings); - - if (version != ICalVersion.V1_0) { - warnings.add(new ValidationWarning(45, version)); - } - } - - @Override - public Timezone copy() { - return new Timezone(this); - } -} diff --git a/app/src/main/java/biweekly/property/TimezoneId.java b/app/src/main/java/biweekly/property/TimezoneId.java deleted file mode 100644 index 91b22899fe..0000000000 --- a/app/src/main/java/biweekly/property/TimezoneId.java +++ /dev/null @@ -1,59 +0,0 @@ -package biweekly.property; - -import biweekly.component.VTimezone; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines a unique identifier for a {@link VTimezone} component. The identifier - * must be unique within the scope of the iCalendar object. - * @author Michael Angstadt - * @see RFC 5545 - * p.102-3 - * @see RFC 2445 p.97-8 - */ -public class TimezoneId extends TextProperty { - /** - * Creates a timezone identifier property. - * @param timezone the timezone identifier - */ - public TimezoneId(String timezone) { - super(timezone); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public TimezoneId(TimezoneId original) { - super(original); - } - - @Override - public TimezoneId copy() { - return new TimezoneId(this); - } -} diff --git a/app/src/main/java/biweekly/property/TimezoneName.java b/app/src/main/java/biweekly/property/TimezoneName.java deleted file mode 100644 index ae404f2258..0000000000 --- a/app/src/main/java/biweekly/property/TimezoneName.java +++ /dev/null @@ -1,82 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a traditional, human-readable, non-standard name for a timezone - * observance (for example, "Eastern Standard Time" for standard time on the US - * east coast). - *

- *

- * Code sample: - *

- * - *
- * VTimezone timezone = new VTimezone("East Coast");
- * 
- * StandardTime standard = new StandardTime();
- * standard.setTimezoneName("Eastern Standard Time");
- * ...
- * timezone.addStandardTime(standard);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.103-4 - * @see RFC 2445 p.98-9 - */ -public class TimezoneName extends TextProperty { - /** - * Creates a timezone name property. - * @param name the timezone name (e.g. "EST") - */ - public TimezoneName(String name) { - super(name); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public TimezoneName(TimezoneName original) { - super(original); - } - - @Override - public String getLanguage() { - return super.getLanguage(); - } - - @Override - public void setLanguage(String language) { - super.setLanguage(language); - } - - @Override - public TimezoneName copy() { - return new TimezoneName(this); - } -} diff --git a/app/src/main/java/biweekly/property/TimezoneOffsetFrom.java b/app/src/main/java/biweekly/property/TimezoneOffsetFrom.java deleted file mode 100644 index fd2549537b..0000000000 --- a/app/src/main/java/biweekly/property/TimezoneOffsetFrom.java +++ /dev/null @@ -1,73 +0,0 @@ -package biweekly.property; - -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the timezone offset that was in affect before the timezone observance - * began. - *

- *

- * Code sample: - *

- * - *
- * VTimezone timezone = ...
- * StandardTime standard = new StandardTime();
- * standard.setTimezoneOffsetFrom(-5, 0);
- * ...
- * timezone.addStandardTime(standard);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.104-5 - * @see RFC 2445 - * p.99-100 - */ -public class TimezoneOffsetFrom extends UtcOffsetProperty { - /** - * Creates a new timezone offset from property. - * @param offset the UTC offset - */ - public TimezoneOffsetFrom(UtcOffset offset) { - super(offset); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public TimezoneOffsetFrom(TimezoneOffsetFrom original) { - super(original); - } - - @Override - public TimezoneOffsetFrom copy() { - return new TimezoneOffsetFrom(this); - } -} diff --git a/app/src/main/java/biweekly/property/TimezoneOffsetTo.java b/app/src/main/java/biweekly/property/TimezoneOffsetTo.java deleted file mode 100644 index e72d74efe3..0000000000 --- a/app/src/main/java/biweekly/property/TimezoneOffsetTo.java +++ /dev/null @@ -1,72 +0,0 @@ -package biweekly.property; - -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the timezone offset that a timezone observance uses. - *

- *

- * Code sample: - *

- * - *
- * VTimezone timezone = ...
- * StandardTime standard = new StandardTime();
- * standard.setTimezoneOffsetTo(-4, 0);
- * ...
- * timezone.addStandardTime(standard);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.105-6 - * @see RFC 2445 - * p.100-1 - */ -public class TimezoneOffsetTo extends UtcOffsetProperty { - /** - * Creates a new timezone offset to property. - * @param offset the UTC offset - */ - public TimezoneOffsetTo(UtcOffset offset) { - super(offset); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public TimezoneOffsetTo(TimezoneOffsetTo original) { - super(original); - } - - @Override - public TimezoneOffsetTo copy() { - return new TimezoneOffsetTo(this); - } -} diff --git a/app/src/main/java/biweekly/property/TimezoneUrl.java b/app/src/main/java/biweekly/property/TimezoneUrl.java deleted file mode 100644 index 10eacfa216..0000000000 --- a/app/src/main/java/biweekly/property/TimezoneUrl.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.property; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a URL that points to an iCalendar object that contains further - * information on a timezone. - *

- *

- * Code sample: - *

- * - *
- * VTimezone timezone = ...
- * timezone.setTimezoneUrl("http://example.com/tz.ics");
- * 
- * @author Michael Angstadt - * @see RFC 5545 p.106 - * @see RFC 2445 p.101 - */ -public class TimezoneUrl extends TextProperty { - /** - * Creates a timezone URL property. - * @param url the timezone URL (e.g. - * "http://example.com/America-New_York.ics") - */ - public TimezoneUrl(String url) { - super(url); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public TimezoneUrl(TimezoneUrl original) { - super(original); - } - - @Override - public TimezoneUrl copy() { - return new TimezoneUrl(this); - } -} diff --git a/app/src/main/java/biweekly/property/Transparency.java b/app/src/main/java/biweekly/property/Transparency.java deleted file mode 100644 index 44dd0eb849..0000000000 --- a/app/src/main/java/biweekly/property/Transparency.java +++ /dev/null @@ -1,141 +0,0 @@ -package biweekly.property; - -import java.util.Arrays; -import java.util.Collection; - -import biweekly.ICalVersion; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines whether an event is visible to free/busy time searches or not. If an - * event does not have this property, the event should be considered opaque - * (visible) to searches. - *

- *

- * Code sample (creating): - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Transparency transp = Transparency.opaque();
- * event.setTransparency(transp);
- * 
- * event.setTransparency(true); //hidden from searches
- * event.setTransparency(false); //visible to searches
- * 
- * - *

- * Code sample (retrieving): - *

- * - *
- * ICalendar ical = ...
- * for (VEvent event : ical.getEvents()) {
- *   Transparency transp = event.getTransparency();
- *   if (transp.isOpaque()) {
- *     //...
- *   } else if (transp.isTransparent()) {
- *     //...
- *   }
- * }
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.101-2 - * @see RFC 2445 p.96-7 - * @see vCal 1.0 p.36-7 - */ -public class Transparency extends EnumProperty { - public static final String OPAQUE = "OPAQUE"; - public static final String TRANSPARENT = "TRANSPARENT"; - - /** - * Creates a new transparency property. - * @param value the value - */ - public Transparency(String value) { - super(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Transparency(Transparency original) { - super(original); - } - - /** - * Creates a property that marks the event as being visible to free/busy - * time searches. - * @return the property - */ - public static Transparency opaque() { - return create(OPAQUE); - } - - /** - * Determines if the event is visible to free/busy time searches. - * @return true if it's visible, false if not - */ - public boolean isOpaque() { - return is(OPAQUE); - } - - /** - * Creates a property that marks the event as being hidden from free/busy - * time searches. - * @return the property - */ - public static Transparency transparent() { - return create(TRANSPARENT); - } - - /** - * Determines if the event is hidden from free/busy time searches. - * @return true if it's hidden, false if not - */ - public boolean isTransparent() { - return is(TRANSPARENT); - } - - private static Transparency create(String value) { - return new Transparency(value); - } - - @Override - protected Collection getStandardValues(ICalVersion version) { - return Arrays.asList(OPAQUE, TRANSPARENT); - } - - @Override - public Transparency copy() { - return new Transparency(this); - } -} diff --git a/app/src/main/java/biweekly/property/Trigger.java b/app/src/main/java/biweekly/property/Trigger.java deleted file mode 100644 index 6aae5cccb1..0000000000 --- a/app/src/main/java/biweekly/property/Trigger.java +++ /dev/null @@ -1,194 +0,0 @@ -package biweekly.property; - -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.parameter.Related; -import biweekly.util.Duration; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines when to trigger an alarm. - *

- *

- * Code sample: - *

- * - *
- * //15 minutes before the start time
- * Duration duration = Duration.builder().prior(true).minutes(15).build();
- * Trigger trigger = new Trigger(duration, Related.START);
- * VAlarm alarm = VAlarm.display(trigger, "Meeting in 15 minutes");
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.133-6 - * @see RFC 2445 - * p.127-9 - */ -public class Trigger extends ICalProperty { - private Duration duration; - private Date date; - - /** - * Creates a trigger property. - * @param duration the relative time - * @param related the date-time field that the duration is relative to - */ - public Trigger(Duration duration, Related related) { - setDuration(duration, related); - } - - /** - * Creates a trigger property. - * @param date the date-time the alarm will trigger. - */ - public Trigger(Date date) { - setDate(date); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Trigger(Trigger original) { - super(original); - date = (original.date == null) ? null : new Date(original.date.getTime()); - duration = original.duration; - } - - /** - * Gets the relative time at which the alarm will trigger. - * @return the relative time or null if an absolute time is set - */ - public Duration getDuration() { - return duration; - } - - /** - * Sets a relative time at which the alarm will trigger. - * @param duration the relative time - * @param related the date-time field that the duration is relative to - */ - public void setDuration(Duration duration, Related related) { - this.date = null; - this.duration = duration; - setRelated(related); - } - - /** - * Gets the date-time that the alarm will trigger. - * @return the date-time or null if a relative duration is set - */ - public Date getDate() { - return date; - } - - /** - * Sets the date-time that the alarm will trigger. - * @param date the date-time the alarm will trigger. - */ - public void setDate(Date date) { - this.date = date; - this.duration = null; - setRelated(null); - } - - /** - * Gets the date-time field that the duration is relative to. - * @return the field or null if not set - * @see RFC 5545 - * p.24 - */ - public Related getRelated() { - return parameters.getRelated(); - } - - /** - * Sets the date-time field that the duration is relative to. - * @param related the field or null to remove - * @see RFC 5545 - * p.24 - */ - public void setRelated(Related related) { - parameters.setRelated(related); - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (duration == null && date == null) { - warnings.add(new ValidationWarning(33)); - } - - Related related = getRelated(); - if (duration != null && related == null) { - warnings.add(new ValidationWarning(10)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("duration", duration); - values.put("date", date); - return values; - } - - @Override - public Trigger copy() { - return new Trigger(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((date == null) ? 0 : date.hashCode()); - result = prime * result + ((duration == null) ? 0 : duration.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Trigger other = (Trigger) obj; - if (date == null) { - if (other.date != null) return false; - } else if (!date.equals(other.date)) return false; - if (duration == null) { - if (other.duration != null) return false; - } else if (!duration.equals(other.duration)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Uid.java b/app/src/main/java/biweekly/property/Uid.java deleted file mode 100644 index 243b0d966e..0000000000 --- a/app/src/main/java/biweekly/property/Uid.java +++ /dev/null @@ -1,86 +0,0 @@ -package biweekly.property; - -import java.util.UUID; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a unique identifier for a component. Note that all components that - * require UID properties are automatically given a random one on creation. - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Uid uid = new Uid("19970610T172345Z-AF23B2@example.com");
- * event.setUid(uid);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.117-8 - * @see RFC 2445 - * p.111-2 - * @see vCal 1.0 p.37 - * @see draft-ietf-calext-extensions-01 - * p.6 - */ -public class Uid extends TextProperty { - /** - * Creates a UID property. - * @param uid the UID (can be anything) - */ - public Uid(String uid) { - super(uid); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Uid(Uid original) { - super(original); - } - - /** - * Creates a UID property that contains a {@link UUID universally unique - * identifier}. - * @return the property - */ - public static Uid random() { - String uuid = UUID.randomUUID().toString(); - return new Uid(uuid); - } - - @Override - public Uid copy() { - return new Uid(this); - } -} diff --git a/app/src/main/java/biweekly/property/Url.java b/app/src/main/java/biweekly/property/Url.java deleted file mode 100644 index 5317485b9a..0000000000 --- a/app/src/main/java/biweekly/property/Url.java +++ /dev/null @@ -1,80 +0,0 @@ -package biweekly.property; - -import biweekly.ICalendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines a website that contains additional information about a component. - *

- *

- * If defined in the top-level {@link ICalendar} component, this property - * defines the location of a more dynamic, alternate representation of the - * calendar (for example, a Google Calendar). - *

- *

- * Code sample: - *

- * - *
- * VEvent event = new VEvent();
- * 
- * Url url = new Url("http://example.com");
- * event.setUrl(url);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.116-7 - * @see RFC 2445 - * p.110-1 - * @see vCal 1.0 p.37 - * @see draft-ietf-calext-extensions-01 - * p.6 - */ -public class Url extends TextProperty { - /** - * Creates a URL property. - * @param url the URL (e.g. "http://example.com/resource.ics") - */ - public Url(String url) { - super(url); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Url(Url original) { - super(original); - } - - @Override - public Url copy() { - return new Url(this); - } -} diff --git a/app/src/main/java/biweekly/property/UtcOffsetProperty.java b/app/src/main/java/biweekly/property/UtcOffsetProperty.java deleted file mode 100644 index 654e54971a..0000000000 --- a/app/src/main/java/biweekly/property/UtcOffsetProperty.java +++ /dev/null @@ -1,46 +0,0 @@ -package biweekly.property; - -import biweekly.util.UtcOffset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose value is a timezone offset. - * @author Michael Angstadt - */ -public class UtcOffsetProperty extends ValuedProperty { - public UtcOffsetProperty(UtcOffset offset) { - super(offset); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public UtcOffsetProperty(UtcOffsetProperty original) { - super(original); - } -} diff --git a/app/src/main/java/biweekly/property/VCalAlarmProperty.java b/app/src/main/java/biweekly/property/VCalAlarmProperty.java deleted file mode 100644 index fe7b808c28..0000000000 --- a/app/src/main/java/biweekly/property/VCalAlarmProperty.java +++ /dev/null @@ -1,128 +0,0 @@ -package biweekly.property; - -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; - -import biweekly.component.VAlarm; -import biweekly.util.Duration; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines an alarm property that is part of the vCalendar (1.0) standard (such - * as {@link AudioAlarm}). - *

- *

- * Classes that extend this class are used internally by this library for - * parsing purposes. If you are creating a new iCalendar object and need to - * define an alarm, it is recommended that you use the {@link VAlarm} component - * to create a new alarm. - *

- * @author Michael Angstadt - * @see vCal 1.0 - */ -public class VCalAlarmProperty extends ICalProperty { - protected Date start; - protected Duration snooze; - protected Integer repeat; - - public VCalAlarmProperty() { - //empty - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public VCalAlarmProperty(VCalAlarmProperty original) { - super(original); - start = new Date(original.start.getTime()); - snooze = original.snooze; - repeat = original.repeat; - } - - public Date getStart() { - return start; - } - - public void setStart(Date start) { - this.start = start; - } - - public Duration getSnooze() { - return snooze; - } - - public void setSnooze(Duration snooze) { - this.snooze = snooze; - } - - public Integer getRepeat() { - return repeat; - } - - public void setRepeat(Integer repeat) { - this.repeat = repeat; - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("start", start); - values.put("snooze", snooze); - values.put("repeat", repeat); - return values; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((repeat == null) ? 0 : repeat.hashCode()); - result = prime * result + ((snooze == null) ? 0 : snooze.hashCode()); - result = prime * result + ((start == null) ? 0 : start.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - VCalAlarmProperty other = (VCalAlarmProperty) obj; - if (repeat == null) { - if (other.repeat != null) return false; - } else if (!repeat.equals(other.repeat)) return false; - if (snooze == null) { - if (other.snooze != null) return false; - } else if (!snooze.equals(other.snooze)) return false; - if (start == null) { - if (other.start != null) return false; - } else if (!start.equals(other.start)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/ValuedProperty.java b/app/src/main/java/biweekly/property/ValuedProperty.java deleted file mode 100644 index 3603568cc8..0000000000 --- a/app/src/main/java/biweekly/property/ValuedProperty.java +++ /dev/null @@ -1,169 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a property whose data model consists of a single Java object (such - * as a String). - * @author Michael Angstadt - * @param the value class (e.g. String) - */ -public class ValuedProperty extends ICalProperty { - protected T value; - - /** - * Creates a new valued property. - * @param value the property's value - */ - public ValuedProperty(T value) { - setValue(value); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public ValuedProperty(ValuedProperty original) { - super(original); - value = original.value; - } - - /** - * Gets the value of this property. - * @return the value - */ - public T getValue() { - return value; - } - - /** - * Sets the value of this property. - * @param value the value - */ - public void setValue(T value) { - this.value = value; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (value == null) { - warnings.add(new ValidationWarning(26)); - } - } - - /** - * Utility method that gets the value of a {@link ValuedProperty} object. - * @param property the property object (may be null) - * @param the value class - * @return the property value (may be null), or null if the property object - * itself is null - */ - public static T getValue(ValuedProperty property) { - return (property == null) ? null : property.getValue(); - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("value", value); - return values; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((value == null) ? 0 : valueHashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - - /* - * This cast will not fail because each property's Class objects are - * checked for equality in super.equals(). - */ - @SuppressWarnings("unchecked") - ValuedProperty other = (ValuedProperty) obj; - - if (value == null) { - if (other.value != null) return false; - } else if (!valueEquals(other.value)) return false; - return true; - } - - /** - *

- * Calculates the hash code of this property's value. - *

- *

- * This method is meant by to overridden by child classes whose value's hash - * code cannot be calculated by just invoking {@code hashCode()}. For - * example, a property whose value is case insensitive. The default - * implementation of this method calls {@code value.hashCode()}. - *

- *

- * This method is only invoked when this property's value is not null. - *

- * @return the value's hash code - */ - protected int valueHashCode() { - return value.hashCode(); - } - - /** - *

- * Compares this property's value with another property's value for - * equality. - *

- *

- * This method is meant by to overridden by child classes when their value's - * equality cannot be calculated by just invoking {@code equals()}. For - * example, a property whose value is case insensitive. The default - * implementation of this method calls {@code value.equals(otherValue)}. - *

- *

- * This method is only invoked when this property's value is not null. - *

- * @param otherValue the other property's value - * @return true if this property's value is equal to the other property's - * value, false if not - */ - protected boolean valueEquals(T otherValue) { - return value.equals(otherValue); - } -} diff --git a/app/src/main/java/biweekly/property/Version.java b/app/src/main/java/biweekly/property/Version.java deleted file mode 100644 index 5353f395e0..0000000000 --- a/app/src/main/java/biweekly/property/Version.java +++ /dev/null @@ -1,238 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.VersionNumber; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Defines the min/max iCalendar versions a consumer must support in order to - * successfully parse the iCalendar object. - *

- *

- * Code sample: - *

- * - *
- * ICalendar ical = new ICalendar();
- * 
- * //all ICalendar objects are given a VERSION property on creation
- * ical.getVersion(); //"2.0"
- * 
- * //get the default iCal version
- * Version version = Version.v2_0();
- * ical.setVersion(version);
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.79-80 - * @see RFC 2445 p.76-7 - * @see vCal 1.0 p.24 - */ -public class Version extends ICalProperty { - public static final VersionNumber VCAL = new VersionNumber(ICalVersion.V1_0.getVersion()); - public static final VersionNumber ICAL = new VersionNumber(ICalVersion.V2_0.getVersion()); - - private VersionNumber minVersion, maxVersion; - - /** - * Creates a new version property. - * @param version the version that a consumer must support in order to - * successfully parse the iCalendar object - */ - public Version(ICalVersion version) { - this((version == null) ? null : version.getVersion()); - } - - /** - * Creates a new version property. - * @param version the version that a consumer must support in order to - * successfully parse the iCalendar object - * @throws IllegalArgumentException if the version string is invalid - */ - public Version(String version) { - this(null, version); - } - - /** - * Creates a new version property. - * @param minVersion the minimum version that a consumer must support in - * order to successfully parse the iCalendar object - * @param maxVersion the maximum version that a consumer must support in - * order to successfully parse the iCalendar object - * @throws IllegalArgumentException if one of the versions strings are - * invalid - */ - public Version(String minVersion, String maxVersion) { - this((minVersion == null) ? null : new VersionNumber(minVersion), (maxVersion == null) ? null : new VersionNumber(maxVersion)); - } - - private Version(VersionNumber minVersion, VersionNumber maxVersion) { - this.minVersion = minVersion; - this.maxVersion = maxVersion; - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Version(Version original) { - super(original); - minVersion = original.minVersion; - maxVersion = original.maxVersion; - } - - /** - * Creates a version property that is set to the older vCalendar version - * (1.0). - * @return the property instance - */ - public static Version v1_0() { - return new Version(ICalVersion.V1_0); - } - - /** - * Creates a version property that is set to the latest iCalendar version - * (2.0). - * @return the property instance - */ - public static Version v2_0() { - return new Version(ICalVersion.V2_0); - } - - /** - * Determines if this property is set to the older vCalendar version. - * @return true if the version is "1.0", false if not - */ - public boolean isV1_0() { - return VCAL.equals(maxVersion); - } - - /** - * Determines if this property is set to the latest iCalendar version. - * @return true if the version is "2.0", false if not - */ - public boolean isV2_0() { - return ICAL.equals(maxVersion); - } - - /** - * Gets the minimum version that a consumer must support in order to - * successfully parse the iCalendar object. - * @return the minimum version or null if not set - */ - public VersionNumber getMinVersion() { - return minVersion; - } - - /** - * Sets the minimum version that a consumer must support in order to - * successfully parse the iCalendar object. - * @param minVersion the minimum version or null to remove - */ - public void setMinVersion(VersionNumber minVersion) { - this.minVersion = minVersion; - } - - /** - * Gets the maximum version that a consumer must support in order to - * successfully parse the iCalendar object. - * @return the maximum version or null if not set - */ - public VersionNumber getMaxVersion() { - return maxVersion; - } - - /** - * Sets the maximum version that a consumer must support in order to - * successfully parse the iCalendar object. - * @param maxVersion the maximum version (this field is required) - */ - public void setMaxVersion(VersionNumber maxVersion) { - this.maxVersion = maxVersion; - } - - /** - * Converts this property's value to an {@link ICalVersion} enum. - * @return the {@link ICalVersion} enum or null if it couldn't be converted - */ - public ICalVersion toICalVersion() { - if (minVersion == null && maxVersion != null) { - return ICalVersion.get(maxVersion.toString()); - } - return null; - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (maxVersion == null) { - warnings.add(new ValidationWarning(35)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("minVersion", minVersion); - values.put("maxVersion", maxVersion); - return values; - } - - @Override - public Version copy() { - return new Version(this); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((maxVersion == null) ? 0 : maxVersion.hashCode()); - result = prime * result + ((minVersion == null) ? 0 : minVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - Version other = (Version) obj; - if (maxVersion == null) { - if (other.maxVersion != null) return false; - } else if (!maxVersion.equals(other.maxVersion)) return false; - if (minVersion == null) { - if (other.minVersion != null) return false; - } else if (!minVersion.equals(other.minVersion)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/property/Xml.java b/app/src/main/java/biweekly/property/Xml.java deleted file mode 100644 index 5b088d73c7..0000000000 --- a/app/src/main/java/biweekly/property/Xml.java +++ /dev/null @@ -1,124 +0,0 @@ -package biweekly.property; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -import biweekly.ICalVersion; -import biweekly.ValidationWarning; -import biweekly.component.ICalComponent; -import biweekly.util.XmlUtils; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Stores a property that was parsed from an xCal document (XML-encoded - * iCalendar object) whose XML namespace was not part of the xCal XML namespace. - * @author Michael Angstadt - * @see RFC 6321 p.17-8 - */ -public class Xml extends ValuedProperty { - /** - * Creates an XML property. - * @param xml the XML to use as the property's value - * @throws SAXException if the XML cannot be parsed - */ - public Xml(String xml) throws SAXException { - this((xml == null) ? null : XmlUtils.toDocument(xml)); - } - - /** - * Creates an XML property. - * @param element the XML element to use as the property's value (the - * element is imported into an empty {@link Document} object) - */ - public Xml(Element element) { - this((element == null) ? null : XmlUtils.createDocument()); - if (element != null) { - Node imported = value.importNode(element, true); - value.appendChild(imported); - } - } - - /** - * Creates an XML property. - * @param document the XML document to use as the property's value - */ - public Xml(Document document) { - super(document); - } - - /** - * Copy constructor. - * @param original the property to make a copy of - */ - public Xml(Xml original) { - super(original); - if (original.value != null) { - value = XmlUtils.createDocument(); - Element root = original.value.getDocumentElement(); - if (root != null) { - Node node = value.importNode(root, true); - value.appendChild(node); - } - } - } - - @Override - protected void validate(List components, ICalVersion version, List warnings) { - if (value == null) { - warnings.add(new ValidationWarning(26)); - } - } - - @Override - protected Map toStringValues() { - Map values = new LinkedHashMap(); - values.put("value", (value == null) ? "null" : XmlUtils.toString(value)); - return values; - } - - @Override - public Xml copy() { - return new Xml(this); - } - - @Override - protected int valueHashCode() { - return XmlUtils.toString(value).hashCode(); - } - - @Override - protected boolean valueEquals(Document otherValue) { - if (otherValue == null) return false; - return XmlUtils.toString(value).equals(XmlUtils.toString(otherValue)); - } -} diff --git a/app/src/main/java/biweekly/property/package-info.java b/app/src/main/java/biweekly/property/package-info.java deleted file mode 100644 index aaa76dc56c..0000000000 --- a/app/src/main/java/biweekly/property/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains DTO classes for each property. - */ -package biweekly.property; \ No newline at end of file diff --git a/app/src/main/java/biweekly/util/ByDay.java b/app/src/main/java/biweekly/util/ByDay.java deleted file mode 100644 index 04ae667b4a..0000000000 --- a/app/src/main/java/biweekly/util/ByDay.java +++ /dev/null @@ -1,104 +0,0 @@ -package biweekly.util; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - *

- * Represents a specific day or all days in a month or year. - *

- *

- * Examples: - *

- *
    - *
  • {@code new ByDay(3, DayOfWeek.MONDAY)} - The third Monday in - * the month/year.
  • - *
  • {@code new ByDay(-1, DayOfWeek.MONDAY)} - The last Monday in the - * month/year.
  • - *
  • {@code new ByDay(DayOfWeek.MONDAY)} - Every Monday in the month/year. - *
  • - *
- * @author Michael Angstadt - */ -public class ByDay { - private final Integer num; - private final DayOfWeek day; - - /** - * Creates a BYDAY rule that represents all days in the month/year. - * @param day the day of the week (cannot be null) - */ - public ByDay(DayOfWeek day) { - this(null, day); - } - - /** - * Creates a BYDAY rule. - * @param num the number (e.g. 3 for "third Sunday", cannot be zero) - * @param day the day of the week (cannot be null) - */ - public ByDay(Integer num, DayOfWeek day) { - this.num = num; - this.day = day; - } - - /** - * Gets the number. - * @return the number (can be null) - */ - public Integer getNum() { - return num; - } - - /** - * Gets the day of the week. - * @return the day of the week - */ - public DayOfWeek getDay() { - return day; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((day == null) ? 0 : day.hashCode()); - result = prime * result + ((num == null) ? 0 : num.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - ByDay other = (ByDay) obj; - if (day != other.day) return false; - if (num == null) { - if (other.num != null) return false; - } else if (!num.equals(other.num)) return false; - return true; - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/util/CaseClasses.java b/app/src/main/java/biweekly/util/CaseClasses.java deleted file mode 100644 index e69e1027af..0000000000 --- a/app/src/main/java/biweekly/util/CaseClasses.java +++ /dev/null @@ -1,162 +0,0 @@ -package biweekly.util; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Manages objects that are like enums in that they are constant, but unlike - * enums in that new instances can be created during runtime. This class ensures - * that all instances of a class are unique, so they can be safely compared - * using "==" (provided their constructors are private). It mimics the - * "case class" feature in Scala. - * @author Michael Angstadt - * - * @param the class - * @param the value that the class holds (e.g. String) - */ -public abstract class CaseClasses { - protected final Class clazz; - protected volatile Collection preDefined = null; - protected Collection runtimeDefined = null; - - /** - * Creates a new case class collection. - * @param clazz the case class - */ - public CaseClasses(Class clazz) { - this.clazz = clazz; - } - - /** - * Creates a new instance of the case class. - * @param value the value to give the instance - * @return the new instance - */ - protected abstract T create(V value); - - /** - * Determines if a value is associated with a case object. - * @param object the object - * @param value the value - * @return true if it matches, false if not - */ - protected abstract boolean matches(T object, V value); - - /** - * Searches for a case object by value, only looking at the case class' - * static constants (does not include runtime-defined objects). - * @param value the value - * @return the object or null if one wasn't found - */ - public T find(V value) { - checkInit(); - - for (T obj : preDefined) { - if (matches(obj, value)) { - return obj; - } - } - return null; - } - - /** - * Searches for a case object by value, creating a new object if one cannot - * be found. - * @param value the value - * @return the object - */ - public T get(V value) { - T found = find(value); - if (found != null) { - return found; - } - - synchronized (runtimeDefined) { - for (T obj : runtimeDefined) { - if (matches(obj, value)) { - return obj; - } - } - - T created = create(value); - runtimeDefined.add(created); - return created; - } - } - - /** - * Gets all the static constants of the case class. - * @return all static constants - */ - public Collection all() { - checkInit(); - return preDefined; - } - - private void checkInit() { - if (preDefined == null) { - synchronized (this) { - //"double check idiom" (Bloch p.283) - if (preDefined == null) { - init(); - } - } - } - } - - private void init() { - Collection preDefined = new ArrayList(); - for (Field field : clazz.getFields()) { - int modifiers = field.getModifiers(); - //@formatter:off - if (Modifier.isStatic(modifiers) && - Modifier.isPublic(modifiers) && - field.getDeclaringClass() == clazz && - field.getType() == clazz) { - //@formatter:on - try { - Object obj = field.get(null); - if (obj != null) { - T c = clazz.cast(obj); - preDefined.add(c); - } - } catch (Exception ex) { - //reflection error - //should never be thrown because we check for "public static" and the correct type - throw new RuntimeException(ex); - } - } - } - - runtimeDefined = new ArrayList(0); - this.preDefined = Collections.unmodifiableCollection(preDefined); - } -} diff --git a/app/src/main/java/biweekly/util/DataUri.java b/app/src/main/java/biweekly/util/DataUri.java deleted file mode 100644 index cc471395c4..0000000000 --- a/app/src/main/java/biweekly/util/DataUri.java +++ /dev/null @@ -1,265 +0,0 @@ -package biweekly.util; - -import java.io.UnsupportedEncodingException; -import java.util.Arrays; - -import biweekly.Messages; -import biweekly.util.org.apache.commons.codec.binary.Base64; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Represents a data URI. - *

- *

- * Example: {@code data:image/jpeg;base64,[base64 string]} - *

- * @author Michael Angstadt - */ -public final class DataUri { - private final byte[] data; - private final String text; - private final String contentType; - - /** - * Creates a data URI. - * @param contentType the content type of the data (e.g. "image/png") - * @param data the data - */ - public DataUri(String contentType, byte[] data) { - this(contentType, data, null); - } - - /** - * Creates a data URI. - * @param contentType the content type of the text (e.g. "text/html") - * @param text the text - */ - public DataUri(String contentType, String text) { - this(contentType, null, text); - } - - /** - * Creates a data URI with a content type of "text/plain". - * @param text the text - */ - public DataUri(String text) { - this("text/plain", text); - } - - /** - * Copies a data URI. - * @param original the data URI to copy - */ - public DataUri(DataUri original) { - this(original.contentType, (original.data == null) ? null : original.data.clone(), original.text); - } - - private DataUri(String contentType, byte[] data, String text) { - this.contentType = (contentType == null) ? "" : contentType.toLowerCase(); - this.data = data; - this.text = text; - } - - /** - * Parses a data URI string. - * @param uri the URI string (e.g. "data:image/jpeg;base64,[base64 string]") - * @return the parsed data URI - * @throws IllegalArgumentException if the string is not a valid data URI or - * it cannot be parsed - */ - public static DataUri parse(String uri) { - //Syntax: data:[][;charset=][;base64], - - String scheme = "data:"; - if (uri.length() < scheme.length() || !uri.substring(0, scheme.length()).equalsIgnoreCase(scheme)) { - //not a data URI - throw Messages.INSTANCE.getIllegalArgumentException(22); - } - - String contentType = null; - String charset = null; - boolean base64 = false; - String dataStr = null; - int tokenStart = scheme.length(); - for (int i = scheme.length(); i < uri.length(); i++) { - char c = uri.charAt(i); - - if (c == ';') { - String token = uri.substring(tokenStart, i); - if (contentType == null) { - contentType = token.toLowerCase(); - } else { - String cs = StringUtils.afterPrefixIgnoreCase(token, "charset="); - if (cs != null) { - charset = cs; - } else if ("base64".equalsIgnoreCase(token)) { - base64 = true; - } - } - tokenStart = i + 1; - continue; - } - - if (c == ',') { - String token = uri.substring(tokenStart, i); - if (contentType == null) { - contentType = token.toLowerCase(); - } else { - String cs = StringUtils.afterPrefixIgnoreCase(token, "charset="); - if (cs != null) { - charset = cs; - } else if ("base64".equalsIgnoreCase(token)) { - base64 = true; - } - } - - dataStr = uri.substring(i + 1); - break; - } - } - - if (dataStr == null) { - throw Messages.INSTANCE.getIllegalArgumentException(23); - } - - String text = null; - byte[] data = null; - if (base64) { - dataStr = dataStr.replaceAll("\\s", ""); - data = Base64.decodeBase64(dataStr); - if (charset != null) { - try { - text = new String(data, charset); - } catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException(Messages.INSTANCE.getExceptionMessage(24, charset), e); - } - data = null; - } - } else { - text = dataStr; - } - - return new DataUri(contentType, data, text); - } - - /** - * Gets the binary data. - * @return the binary data or null if the value was text - */ - public byte[] getData() { - return data; - } - - /** - * Gets the content type. - * @return the content type (e.g. "image/png") - */ - public String getContentType() { - return contentType; - } - - /** - * Gets the text value. - * @return the text value or null if the value was binary - */ - public String getText() { - return text; - } - - /** - * Creates a data URI string. - * @return the data URI (e.g. "data:image/jpeg;base64,[base64 string]") - */ - @Override - public String toString() { - return toString(null); - } - - /** - * Creates a data URI string. - * @param charset only applicable if the data URI's value is text. Defines - * the character set to encode the text in, or null not to specify a - * character set - * @return the data URI (e.g. "data:image/jpeg;base64,[base64 string]") - * @throws IllegalArgumentException if the given character set is not - * supported by this JVM - */ - public String toString(String charset) { - StringBuilder sb = new StringBuilder(); - sb.append("data:"); - sb.append(contentType); - - if (data != null) { - sb.append(";base64,"); - sb.append(Base64.encodeBase64String(data)); - } else if (text != null) { - if (charset == null) { - sb.append(',').append(text); - } else { - byte[] data; - try { - data = text.getBytes(charset); - } catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException(Messages.INSTANCE.getExceptionMessage(25, charset), e); - } - - sb.append(";charset=").append(charset); - sb.append(";base64,"); - sb.append(Base64.encodeBase64String(data)); - } - } else { - sb.append(','); - } - - return sb.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + contentType.hashCode(); - result = prime * result + Arrays.hashCode(data); - result = prime * result + ((text == null) ? 0 : text.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - DataUri other = (DataUri) obj; - if (!contentType.equals(other.contentType)) return false; - if (!Arrays.equals(data, other.data)) return false; - if (text == null) { - if (other.text != null) return false; - } else if (!text.equals(other.text)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/util/DateTimeComponents.java b/app/src/main/java/biweekly/util/DateTimeComponents.java deleted file mode 100644 index 481ff74b59..0000000000 --- a/app/src/main/java/biweekly/util/DateTimeComponents.java +++ /dev/null @@ -1,426 +0,0 @@ -package biweekly.util; - -import java.io.Serializable; -import java.text.NumberFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import biweekly.Messages; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Contains the raw components of a date-time value. - *

- *

- * Examples: - *

- * - *
- * //July 22, 2013 at 17:25
- * DateTimeComponents components = new DateTimeComponents(2013, 07, 22, 17, 25, 0, false);
- * 
- * //parsing a date string (accepts basic and extended formats)
- * DateTimeComponents components = DateTimeComponents.parse("20130722T172500");
- * 
- * //converting to date string
- * DateTimeComponents components = new DateTimeComponents(2013, 07, 22, 17, 25, 0, false);
- * String str = components.toString(true); //"2013-07-22T17:25:00"
- * 
- * //converting to a Date object
- * DateTimeComponents components = new DateTimeComponents(2013, 07, 22, 17, 25, 0, false);
- * Date date = components.toDate();
- * 
- * 
- * @author Michael Angstadt - */ -public final class DateTimeComponents implements Comparable, Serializable { - private static final long serialVersionUID = 7668029303206402368L; - private static final Pattern regex = Pattern.compile("^(\\d{4})-?(\\d{2})-?(\\d{2})(T(\\d{2}):?(\\d{2}):?(\\d{2})(Z?))?.*"); - private final int year, month, date, hour, minute, second; - private final boolean hasTime, utc; - - /** - * Parses the components out of a date-time string. - * @param dateString the date-time string (basic and extended formats are - * supported, e.g. "20130331T020000" or "2013-03-31T02:00:00") - * @return the parsed components - * @throws IllegalArgumentException if the date string cannot be parsed - */ - public static DateTimeComponents parse(String dateString) { - return parse(dateString, null); - } - - /** - * Parses the components out of a date-time string. - * @param dateString the date-time string (basic and extended formats are - * supported, e.g. "20130331T020000" or "2013-03-31T02:00:00") - * @param hasTime true to force the value to be parsed as a date-time value, - * false to force the value to be parsed as a date value, null to parse the - * value however it is - * @return the parsed components - * @throws IllegalArgumentException if the date string cannot be parsed - */ - public static DateTimeComponents parse(String dateString, Boolean hasTime) { - Matcher m = regex.matcher(dateString); - if (!m.find()) { - throw Messages.INSTANCE.getIllegalArgumentException(19, dateString); - } - - int i = 1; - int year = Integer.parseInt(m.group(i++)); - int month = Integer.parseInt(m.group(i++)); - int date = Integer.parseInt(m.group(i++)); - - i++; //skip - - String hourStr = m.group(i++); - if (hasTime == null) { - hasTime = (hourStr != null); - } - if (!hasTime) { - return new DateTimeComponents(year, month, date); - } - - int hour = (hourStr == null) ? 0 : Integer.parseInt(hourStr); - - String minuteStr = m.group(i++); - int minute = (minuteStr == null) ? 0 : Integer.parseInt(minuteStr); - - String secondStr = m.group(i++); - int second = (secondStr == null) ? 0 : Integer.parseInt(secondStr); - - boolean utc = "Z".equals(m.group(i++)); - - return new DateTimeComponents(year, month, date, hour, minute, second, utc); - } - - /** - * Copies an existing DateTimeComponents object. - * @param original the object to copy from - */ - public DateTimeComponents(DateTimeComponents original) { - this(original, null, null, null, null, null, null, null); - } - - /** - * Copies an existing DateTimeComponents object. - * @param original the object to copy from - * @param year the new year value or null not to change - * @param month the new month value or null not to change - * @param date the new date value or null not to change - * @param hour the new hour value or null not to change - * @param minute the new minute value or null not to change - * @param second the new second value or null not to change - * @param utc true if the time is in UTC, false if not, or null not to - * change - */ - public DateTimeComponents(DateTimeComponents original, Integer year, Integer month, Integer date, Integer hour, Integer minute, Integer second, Boolean utc) { - //@formatter:off - this( - (year == null) ? original.year : year, - (month == null) ? original.month : month, - (date == null) ? original.date : date, - (hour == null) ? original.hour : hour, - (minute == null) ? original.minute : minute, - (second == null) ? original.second : second, - (utc == null) ? original.utc : utc - ); - //@formatter:on - } - - /** - * Creates a set of date components. - * @param year the year (e.g. "2013") - * @param month the month (e.g. "1" for January) - * @param date the date of the month (e.g. "15") - */ - public DateTimeComponents(int year, int month, int date) { - this(year, month, date, 0, 0, 0, false, false); - } - - /** - * Creates a set of date-time components. - * @param year the year (e.g. "2013") - * @param month the month (e.g. "1" for January) - * @param date the date of the month (e.g. "15") - * @param hour the hour (e.g. "13") - * @param minute the minute - * @param second the second - * @param utc true if the time is in UTC, false if not - */ - public DateTimeComponents(int year, int month, int date, int hour, int minute, int second, boolean utc) { - this(year, month, date, hour, minute, second, utc, true); - } - - private DateTimeComponents(int year, int month, int date, int hour, int minute, int second, boolean utc, boolean hasTime) { - this.year = year; - this.month = month; - this.date = date; - this.hour = hour; - this.minute = minute; - this.second = second; - this.utc = utc; - this.hasTime = hasTime; - } - - /** - * Creates a set of date-time components in the local timezone from a - * {@link Date} object. - * @param date the date object - */ - public DateTimeComponents(Date date) { - this(date, TimeZone.getDefault()); - } - - /** - * Creates a set of date-time components from a {@link Date} object. - * @param date the date object - * @param timezone the timezone the date-time components will be in - */ - public DateTimeComponents(Date date, TimeZone timezone) { - Calendar cal = Calendar.getInstance(timezone); - cal.setTime(date); - - year = cal.get(Calendar.YEAR); - month = cal.get(Calendar.MONTH) + 1; - this.date = cal.get(Calendar.DATE); - hour = cal.get(Calendar.HOUR_OF_DAY); - minute = cal.get(Calendar.MINUTE); - second = cal.get(Calendar.SECOND); - utc = false; - hasTime = true; - } - - /** - * Gets the year component. - * @return the year - */ - public int getYear() { - return year; - } - - /** - * Gets the month component. - * @return the month (e.g. "1" for January) - */ - public int getMonth() { - return month; - } - - /** - * Gets the date component - * @return the date - */ - public int getDate() { - return date; - } - - /** - * Gets whether these components contain a time component - * @return true if it has a time component, false if it's strictly a date - */ - public boolean hasTime() { - return hasTime; - } - - /** - * Gets the hour component - * @return the hour - */ - public int getHour() { - return hour; - } - - /** - * Gets the minute component. - * @return the minute - */ - public int getMinute() { - return minute; - } - - /** - * Gets the second component. - * @return the second - */ - public int getSecond() { - return second; - } - - /** - * Gets whether the time is in UTC or not - * @return true if the time is in UTC, false if not - */ - public boolean isUtc() { - return utc; - } - - /** - * Converts the date-time components to a string using "basic" format. - * @return the date string - */ - @Override - public String toString() { - return toString(true, false); - } - - /** - * Converts the date-time components to a string. - * @param includeTime true to include the time portion, false not to - * @param extended true to use extended format, false to use basic - * @return the date string - */ - public String toString(boolean includeTime, boolean extended) { - NumberFormat nf = NumberFormat.getNumberInstance(Locale.ENGLISH); - nf.setMinimumIntegerDigits(2); - nf.setMaximumIntegerDigits(2); - String dash = extended ? "-" : ""; - String colon = extended ? ":" : ""; - String z = utc ? "Z" : ""; - - StringBuilder sb = new StringBuilder(); - sb.append(year).append(dash).append(nf.format(month)).append(dash).append(nf.format(date)); - if (includeTime) { - sb.append("T").append(nf.format(hour)).append(colon).append(nf.format(minute)).append(colon).append(nf.format(second)).append(z); - } - return sb.toString(); - } - - /** - * Converts the date-time components to a {@link Date} object. - * @return the date object - */ - public Date toDate() { - TimeZone timezone = utc ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault(); - return toDate(timezone); - } - - /** - * Converts the date-time components to a {@link Date} object. - * @param timezone the timezone that the date-time components are assumed to - * be in - * @return the date object - */ - public Date toDate(TimeZone timezone) { - return toDate(Calendar.getInstance(timezone)); - } - - /** - * Converts the date-time components to a {@link Date} object. - * @param c the calendar object to use - * @return the date object - */ - public Date toDate(Calendar c) { - c.clear(); - c.set(Calendar.YEAR, year); - c.set(Calendar.MONTH, month - 1); - c.set(Calendar.DATE, date); - c.set(Calendar.HOUR_OF_DAY, hour); - c.set(Calendar.MINUTE, minute); - c.set(Calendar.SECOND, second); - return c.getTime(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + date; - result = prime * result + (hasTime ? 1231 : 1237); - result = prime * result + hour; - result = prime * result + minute; - result = prime * result + month; - result = prime * result + second; - result = prime * result + (utc ? 1231 : 1237); - result = prime * result + year; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - DateTimeComponents other = (DateTimeComponents) obj; - if (date != other.date) return false; - if (hasTime != other.hasTime) return false; - if (hour != other.hour) return false; - if (minute != other.minute) return false; - if (month != other.month) return false; - if (second != other.second) return false; - if (utc != other.utc) return false; - if (year != other.year) return false; - return true; - } - - public int compareTo(DateTimeComponents that) { - int c = this.year - that.year; - if (c != 0) { - return c; - } - - c = this.month - that.month; - if (c != 0) { - return c; - } - - c = this.date - that.date; - if (c != 0) { - return c; - } - - c = this.hour - that.hour; - if (c != 0) { - return c; - } - - c = this.minute - that.minute; - if (c != 0) { - return c; - } - - c = this.second - that.second; - if (c != 0) { - return c; - } - - return 0; - } - - public boolean before(DateTimeComponents that) { - return this.compareTo(that) < 0; - } - - public boolean after(DateTimeComponents that) { - return this.compareTo(that) > 0; - } -} diff --git a/app/src/main/java/biweekly/util/DayOfWeek.java b/app/src/main/java/biweekly/util/DayOfWeek.java deleted file mode 100644 index 9f1c901cb6..0000000000 --- a/app/src/main/java/biweekly/util/DayOfWeek.java +++ /dev/null @@ -1,88 +0,0 @@ -package biweekly.util; - -import java.util.Calendar; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents each of the seven days of the week. - * @author Michael Angstadt - */ -public enum DayOfWeek { - /* - * These constants are defined in the order that the days of the week are - * arranged on a calendar. Do not rearrange them. Other parts of the code - * base rely on this ordering (i.e. this class's ordinal() and values() - * methods are used). - */ - //@formatter:off - SUNDAY("SU", Calendar.SUNDAY), - MONDAY("MO", Calendar.MONDAY), - TUESDAY("TU", Calendar.TUESDAY), - WEDNESDAY("WE", Calendar.WEDNESDAY), - THURSDAY("TH", Calendar.THURSDAY), - FRIDAY("FR", Calendar.FRIDAY), - SATURDAY("SA", Calendar.SATURDAY); - //@formatter:on - - private final String abbr; - private final int calendarConstant; - - DayOfWeek(String abbr, int calendarConstant) { - this.abbr = abbr; - this.calendarConstant = calendarConstant; - } - - /** - * Gets the day's abbreviation. - * @return the abbreviation (e.g. "MO" for Monday) - */ - public String getAbbr() { - return abbr; - } - - /** - * Gets the integer constant the {@link Calendar} class uses for this day. - * @return the constant - */ - public int getCalendarConstant() { - return calendarConstant; - } - - /** - * Gets a day by its abbreviation. - * @param abbr the abbreviation (case-insensitive, e.g. "MO" for Monday) - * @return the day or null if not found - */ - public static DayOfWeek valueOfAbbr(String abbr) { - for (DayOfWeek day : values()) { - if (day.abbr.equalsIgnoreCase(abbr)) { - return day; - } - } - return null; - } -} \ No newline at end of file diff --git a/app/src/main/java/biweekly/util/Duration.java b/app/src/main/java/biweekly/util/Duration.java deleted file mode 100644 index 228013517d..0000000000 --- a/app/src/main/java/biweekly/util/Duration.java +++ /dev/null @@ -1,508 +0,0 @@ -package biweekly.util; - -import java.util.Calendar; -import java.util.Date; - -import biweekly.Messages; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Represents a period of time (for example, "2 hours and 30 minutes"). - *

- *

- * This class is immutable. Use the {@link #builder} method to construct a new - * instance, or the {@link #parse} method to parse a duration string. - *

- * - *

- * Examples: - *

- * - *
- * Duration duration = Duration.builder().hours(2).minutes(30).build();
- * Duration duration = Duration.parse("PT2H30M");
- * 
- * //add a duration value to a Date
- * Date start = ...
- * Date end = duration.add(start);
- * 
- * @author Michael Angstadt - */ -public final class Duration { - private final Integer weeks, days, hours, minutes, seconds; - private final boolean prior; - - private Duration(Builder b) { - weeks = b.weeks; - days = b.days; - hours = b.hours; - minutes = b.minutes; - seconds = b.seconds; - prior = b.prior; - } - - /** - * Parses a duration string. - * @param value the duration string (e.g. "P30DT10H") - * @return the parsed duration - * @throws IllegalArgumentException if the duration string is invalid - */ - public static Duration parse(String value) { - /* - * Implementation note: Regular expressions are not used to improve - * performance. - */ - - if (value.isEmpty()) { - throw parseError(value); - } - - int index = 0; - char first = value.charAt(index); - boolean prior = (first == '-'); - if (first == '-' || first == '+') { - index++; - } - if (index >= value.length() || value.charAt(index) != 'P') { - throw parseError(value); - } - - Builder builder = new Builder(); - builder.prior(prior); - - StringBuilder buffer = new StringBuilder(); - for (int i = index + 1; i < value.length(); i++) { - char c = value.charAt(i); - - if (c == 'T') { - /* - * A "T" character is supposed to immediately precede the time - * component value(s). It is required by the syntax, but not - * really necessary. Ignore it. - */ - continue; - } - - if (c >= '0' && c <= '9') { - buffer.append(c); - continue; - } - - if (buffer.length() == 0) { - throw parseError(value); - } - - Integer num = Integer.valueOf(buffer.toString()); - buffer.setLength(0); - - switch (c) { - case 'W': - builder.weeks(num); - break; - case 'D': - builder.days(num); - break; - case 'H': - builder.hours(num); - break; - case 'M': - builder.minutes(num); - break; - case 'S': - builder.seconds(num); - break; - default: - throw parseError(value); - } - } - - return builder.build(); - } - - private static IllegalArgumentException parseError(String value) { - return Messages.INSTANCE.getIllegalArgumentException(20, value); - } - - /** - * Builds a duration based on the difference between two dates. - * @param start the start date - * @param end the end date - * @return the duration - */ - public static Duration diff(Date start, Date end) { - return fromMillis(end.getTime() - start.getTime()); - } - - /** - * Builds a duration from a number of milliseconds. - * @param milliseconds the number of milliseconds - * @return the duration - */ - public static Duration fromMillis(long milliseconds) { - Duration.Builder builder = builder(); - - if (milliseconds < 0) { - builder.prior(true); - milliseconds *= -1; - } - - int seconds = (int) (milliseconds / 1000); - - int weeks = seconds / (60 * 60 * 24 * 7); - if (weeks > 0) { - builder.weeks(weeks); - } - seconds %= 60 * 60 * 24 * 7; - - int days = seconds / (60 * 60 * 24); - if (days > 0) { - builder.days(days); - } - seconds %= 60 * 60 * 24; - - int hours = seconds / (60 * 60); - if (hours > 0) { - builder.hours(hours); - } - seconds %= 60 * 60; - - int minutes = seconds / (60); - if (minutes > 0) { - builder.minutes(minutes); - } - seconds %= 60; - - if (seconds > 0) { - builder.seconds(seconds); - } - - return builder.build(); - } - - /** - * Creates a builder object for constructing new instances of this class. - * @return the builder object - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Gets whether the duration is negative. - * @return true if it's negative, false if not - */ - public boolean isPrior() { - return prior; - } - - /** - * Gets the number of weeks. - * @return the number of weeks or null if not set - */ - public Integer getWeeks() { - return weeks; - } - - /** - * Gets the number of days. - * @return the number of days or null if not set - */ - public Integer getDays() { - return days; - } - - /** - * Gets the number of hours. - * @return the number of hours or null if not set - */ - public Integer getHours() { - return hours; - } - - /** - * Gets the number of minutes. - * @return the number of minutes or null if not set - */ - public Integer getMinutes() { - return minutes; - } - - /** - * Gets the number of seconds. - * @return the number of seconds or null if not set - */ - public Integer getSeconds() { - return seconds; - } - - /** - * Adds this duration value to a {@link Date} object. - * @param date the date to add to - * @return the new date value - */ - public Date add(Date date) { - Calendar c = Calendar.getInstance(); - c.setTime(date); - - if (weeks != null) { - int weeks = this.weeks * (prior ? -1 : 1); - c.add(Calendar.DATE, weeks * 7); - } - if (days != null) { - int days = this.days * (prior ? -1 : 1); - c.add(Calendar.DATE, days); - } - if (hours != null) { - int hours = this.hours * (prior ? -1 : 1); - c.add(Calendar.HOUR_OF_DAY, hours); - } - if (minutes != null) { - int minutes = this.minutes * (prior ? -1 : 1); - c.add(Calendar.MINUTE, minutes); - } - if (seconds != null) { - int seconds = this.seconds * (prior ? -1 : 1); - c.add(Calendar.SECOND, seconds); - } - - return c.getTime(); - } - - /** - * Converts the duration value to milliseconds. - * @return the duration value in milliseconds (will be negative if - * {@link #isPrior} is true) - */ - public long toMillis() { - long totalSeconds = 0; - - if (weeks != null) { - totalSeconds += 60L * 60 * 24 * 7 * weeks; - } - if (days != null) { - totalSeconds += 60L * 60 * 24 * days; - } - if (hours != null) { - totalSeconds += 60L * 60 * hours; - } - if (minutes != null) { - totalSeconds += 60L * minutes; - } - if (seconds != null) { - totalSeconds += seconds; - } - if (prior) { - totalSeconds *= -1; - } - - return totalSeconds * 1000; - } - - /** - * Determines if any time components are present. - * @return true if the duration has at least one time component, false if - * not - */ - public boolean hasTime() { - return hours != null || minutes != null || seconds != null; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((days == null) ? 0 : days.hashCode()); - result = prime * result + ((hours == null) ? 0 : hours.hashCode()); - result = prime * result + ((minutes == null) ? 0 : minutes.hashCode()); - result = prime * result + (prior ? 1231 : 1237); - result = prime * result + ((seconds == null) ? 0 : seconds.hashCode()); - result = prime * result + ((weeks == null) ? 0 : weeks.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - Duration other = (Duration) obj; - if (days == null) { - if (other.days != null) return false; - } else if (!days.equals(other.days)) return false; - if (hours == null) { - if (other.hours != null) return false; - } else if (!hours.equals(other.hours)) return false; - if (minutes == null) { - if (other.minutes != null) return false; - } else if (!minutes.equals(other.minutes)) return false; - if (prior != other.prior) return false; - if (seconds == null) { - if (other.seconds != null) return false; - } else if (!seconds.equals(other.seconds)) return false; - if (weeks == null) { - if (other.weeks != null) return false; - } else if (!weeks.equals(other.weeks)) return false; - return true; - } - - /** - * Converts the duration to its string representation. - * @return the string representation (e.g. "P4DT1H" for "4 days and 1 hour") - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - if (prior) { - sb.append('-'); - } - sb.append('P'); - - if (weeks != null) { - sb.append(weeks).append('W'); - } - - if (days != null) { - sb.append(days).append('D'); - } - - if (hasTime()) { - sb.append('T'); - - if (hours != null) { - sb.append(hours).append('H'); - } - - if (minutes != null) { - sb.append(minutes).append('M'); - } - - if (seconds != null) { - sb.append(seconds).append('S'); - } - } - - return sb.toString(); - } - - /** - * Builds {@link Duration} objects. - */ - public static class Builder { - private Integer weeks, days, hours, minutes, seconds; - private boolean prior = false; - - /** - * Creates a new {@link Duration} builder. - */ - public Builder() { - //empty - } - - /** - * Creates a new {@link Duration} builder. - * @param source the object to copy from - */ - public Builder(Duration source) { - weeks = source.weeks; - days = source.days; - hours = source.hours; - minutes = source.minutes; - seconds = source.seconds; - prior = source.prior; - } - - /** - * Sets the number of weeks. - * @param weeks the number of weeks - * @return this - */ - public Builder weeks(Integer weeks) { - this.weeks = weeks; - return this; - } - - /** - * Sets the number of days - * @param days the number of days - * @return this - */ - public Builder days(Integer days) { - this.days = days; - return this; - } - - /** - * Sets the number of hours - * @param hours the number of hours - * @return this - */ - public Builder hours(Integer hours) { - this.hours = hours; - return this; - } - - /** - * Sets the number of minutes - * @param minutes the number of minutes - * @return this - */ - public Builder minutes(Integer minutes) { - this.minutes = minutes; - return this; - } - - /** - * Sets the number of seconds. - * @param seconds the number of seconds - * @return this - */ - public Builder seconds(Integer seconds) { - this.seconds = seconds; - return this; - } - - /** - * Sets whether the duration should be negative. - * @param prior true to be negative, false not to be - * @return this - */ - public Builder prior(boolean prior) { - this.prior = prior; - return this; - } - - /** - * Builds the final {@link Duration} object. - * @return the object - */ - public Duration build() { - return new Duration(this); - } - } -} diff --git a/app/src/main/java/biweekly/util/Frequency.java b/app/src/main/java/biweekly/util/Frequency.java deleted file mode 100644 index f73cdc184a..0000000000 --- a/app/src/main/java/biweekly/util/Frequency.java +++ /dev/null @@ -1,35 +0,0 @@ -package biweekly.util; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - * Represents the frequency at which a recurrence rule repeats itself. - * @author Michael Angstadt - */ -public enum Frequency { - //in order of increasing length - SECONDLY, MINUTELY, HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY -} diff --git a/app/src/main/java/biweekly/util/Gobble.java b/app/src/main/java/biweekly/util/Gobble.java deleted file mode 100644 index 881e047387..0000000000 --- a/app/src/main/java/biweekly/util/Gobble.java +++ /dev/null @@ -1,152 +0,0 @@ -package biweekly.util; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.Charset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Gets the entire contents of an input stream or a file. - * @author Michael Angstadt - */ -public class Gobble { - private final File file; - private final InputStream in; - private final Reader reader; - - /** - * Gets the contents of a file. - * @param file the file - */ - public Gobble(File file) { - this(file, null, null); - } - - /** - * Gets the contents of an input stream. - * @param in the input stream - */ - public Gobble(InputStream in) { - this(null, in, null); - } - - /** - * Gets the contents of a reader. - * @param reader the reader - */ - public Gobble(Reader reader) { - this(null, null, reader); - } - - private Gobble(File file, InputStream in, Reader reader) { - this.file = file; - this.in = in; - this.reader = reader; - } - - /** - * Gets the stream contents as a string. If something other than a - * {@link Reader} was passed into this class's constructor, this method - * decodes the stream data using the system's default character encoding. - * @return the string - * @throws IOException if there was a problem reading from the stream - */ - public String asString() throws IOException { - return asString(Charset.defaultCharset().name()); - } - - /** - * Gets the stream contents as a string. - * @param charset the character set to decode the stream data with (this - * parameter is ignored if a {@link Reader} was passed into this class's - * constructor) - * @return the string - * @throws IOException if there was a problem reading from the stream - */ - public String asString(String charset) throws IOException { - Reader reader = buildReader(charset); - return consumeReader(reader); - } - - /** - * Gets the stream contents as a byte array. - * @return the byte array - * @throws IOException if there was a problem reading from the stream - * @throws IllegalStateException if a {@link Reader} object was passed into - * this class's constructor - */ - public byte[] asByteArray() throws IOException { - if (reader != null) { - throw new IllegalStateException("Cannot get raw bytes from a Reader object."); - } - - InputStream in = buildInputStream(); - return consumeInputStream(in); - } - - private Reader buildReader(String charset) throws IOException { - return (reader == null) ? new InputStreamReader(buildInputStream(), charset) : reader; - } - - private InputStream buildInputStream() throws IOException { - return (in == null) ? new BufferedInputStream(new FileInputStream(file)) : in; - } - - private String consumeReader(Reader reader) throws IOException { - StringBuilder sb = new StringBuilder(); - char[] buffer = new char[4096]; - int read; - try { - while ((read = reader.read(buffer)) != -1) { - sb.append(buffer, 0, read); - } - } finally { - reader.close(); - } - return sb.toString(); - } - - private byte[] consumeInputStream(InputStream in) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] buffer = new byte[4096]; - int read; - try { - while ((read = in.read(buffer)) != -1) { - out.write(buffer, 0, read); - } - } finally { - in.close(); - } - return out.toByteArray(); - } -} diff --git a/app/src/main/java/biweekly/util/Google2445Utils.java b/app/src/main/java/biweekly/util/Google2445Utils.java deleted file mode 100644 index 9aefa61353..0000000000 --- a/app/src/main/java/biweekly/util/Google2445Utils.java +++ /dev/null @@ -1,393 +0,0 @@ -package biweekly.util; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.TimeZone; - -import biweekly.component.ICalComponent; -import biweekly.property.DateStart; -import biweekly.property.ExceptionDates; -import biweekly.property.ExceptionRule; -import biweekly.property.RecurrenceDates; -import biweekly.property.RecurrenceRule; -import biweekly.property.ValuedProperty; -import biweekly.util.com.google.ical.compat.javautil.DateIterator; -import biweekly.util.com.google.ical.compat.javautil.DateIteratorFactory; -import biweekly.util.com.google.ical.iter.RecurrenceIterable; -import biweekly.util.com.google.ical.iter.RecurrenceIterator; -import biweekly.util.com.google.ical.iter.RecurrenceIteratorFactory; -import biweekly.util.com.google.ical.values.DateTimeValue; -import biweekly.util.com.google.ical.values.DateTimeValueImpl; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Contains utility methods related to the google-rfc-2445 project. - * @author Michael Angstadt - * @see google-rfc-2445 - */ -public final class Google2445Utils { - /** - *

- * Converts an {@link ICalDate} object to a google-rfc-2445 - * {@link DateValue} object using the {@link DateTimeComponents raw date - * components} of the {@link ICalDate}. - *

- *

- * If the {@link ICalDate} object does not have raw date components, then - * the returned {@link DateValue} object will represent the {@link ICalDate} - * in the local timezone. - *

- * @param date the date object - * @return the google-rfc-2445 object - */ - public static DateValue convertFromRawComponents(ICalDate date) { - DateTimeComponents raw = date.getRawComponents(); - if (raw == null) { - raw = new DateTimeComponents(date); - } - - return convert(raw); - } - - /** - * Converts a {@link DateTimeComponents} object to a google-rfc-2445 - * {@link DateValue} object. - * @param components the date time components object - * @return the google-rfc-2445 object - */ - public static DateValue convert(DateTimeComponents components) { - if (components.hasTime()) { - //@formatter:off - return new DateTimeValueImpl( - components.getYear(), - components.getMonth(), - components.getDate(), - components.getHour(), - components.getMinute(), - components.getSecond() - ); - //@formatter:on - } - - //@formatter:off - return new DateValueImpl( - components.getYear(), - components.getMonth(), - components.getDate() - ); - //@formatter:on - } - - /** - * Converts an {@link ICalDate} object to a google-rfc-2445 - * {@link DateValue} object. - * @param date the date object - * @param timezone the timezone the returned object will be in - * @return the google-rfc-2445 object - */ - public static DateValue convert(ICalDate date, TimeZone timezone) { - Calendar c = Calendar.getInstance(timezone); - c.setTime(date); - - /* - * Do not create a "DateValueImpl" object if "date.hasTime() == false". - * This interferes with any recurrence iterators the object is passed - * into. - * - * See: https://github.com/mangstadt/biweekly/issues/47 - */ - - //@formatter:off - return new DateTimeValueImpl( - c.get(Calendar.YEAR), - c.get(Calendar.MONTH)+1, - c.get(Calendar.DATE), - c.get(Calendar.HOUR_OF_DAY), - c.get(Calendar.MINUTE), - c.get(Calendar.SECOND) - ); - //@formatter:on - } - - /** - * Converts an {@link ICalDate} object to a google-rfc-2445 - * {@link DateValue} object. The returned object will be in UTC. - * @param date the date object - * @return the google-rfc-2445 object (in UTC) - */ - public static DateValue convertUtc(ICalDate date) { - return convert(date, utc()); - } - - /** - * Converts a google-rfc-2445 {@link DateValue} object to a {@link ICalDate} - * object. - * @param date the date value object - * @param timezone the timezone the date value is in - * @return the converted object - */ - public static ICalDate convert(DateValue date, TimeZone timezone) { - Calendar c = Calendar.getInstance(timezone); - c.clear(); - c.set(Calendar.YEAR, date.year()); - c.set(Calendar.MONTH, date.month() - 1); - c.set(Calendar.DATE, date.day()); - - boolean hasTime = (date instanceof DateTimeValue); - if (hasTime) { - DateTimeValue dateTime = (DateTimeValue) date; - c.set(Calendar.HOUR_OF_DAY, dateTime.hour()); - c.set(Calendar.MINUTE, dateTime.minute()); - c.set(Calendar.SECOND, dateTime.second()); - } - - return new ICalDate(c.getTime(), hasTime); - } - - /** - * Converts a google-rfc-2445 {@link DateValue} object to a {@link ICalDate} - * object. It is assumed that the given {@link DateValue} object is in UTC. - * @param date the date value object (in UTC) - * @return the converted object - */ - public static ICalDate convertUtc(DateValue date) { - return convert(date, utc()); - } - - /** - * Creates a recurrence iterator based on the given recurrence rule. - * @param recurrence the recurrence rule - * @param start the start date - * @param timezone the timezone to iterate in. This is needed in order to - * account for when the iterator passes over a daylight savings boundary. - * @return the recurrence iterator - */ - public static RecurrenceIterator createRecurrenceIterator(Recurrence recurrence, ICalDate start, TimeZone timezone) { - DateValue startValue = convert(start, timezone); - return RecurrenceIteratorFactory.createRecurrenceIterator(recurrence, startValue, timezone); - } - - /** - * Creates a recurrence iterator based on the given recurrence rule. - * @param recurrence the recurrence rule - * @param start the start date - * @param timezone the timezone to iterate in. This is needed in order to - * account for when the iterator passes over a daylight savings boundary. - * @return the recurrence iterator - */ - public static RecurrenceIterable createRecurrenceIterable(Recurrence recurrence, ICalDate start, TimeZone timezone) { - DateValue startValue = convert(start, timezone); - return RecurrenceIteratorFactory.createRecurrenceIterable(recurrence, startValue, timezone); - } - - /** - *

- * Creates an iterator that computes the dates defined by the - * {@link RecurrenceRule} and {@link RecurrenceDates} properties (if - * present), and excludes those dates which are defined by the - * {@link ExceptionRule} and {@link ExceptionDates} properties (if present). - *

- *

- * In order for {@link RecurrenceRule} and {@link ExceptionRule} properties - * to be included in this iterator, a {@link DateStart} property must be - * defined. - *

- *

- * {@link Period} values in {@link RecurrenceDates} properties are not - * supported and are ignored. - *

- * @param component the component - * @param timezone the timezone to iterate in. This is needed in order to - * adjust for when the iterator passes over a daylight savings boundary. - * This parameter is ignored if the start date of the given component does - * not have a time component. - * @return the iterator - */ - public static DateIterator getDateIterator(ICalComponent component, TimeZone timezone) { - DateStart dtstart = component.getProperty(DateStart.class); - ICalDate start = ValuedProperty.getValue(dtstart); - - /* - * If the start date is just a date and does not have a time component, - * then the default timezone must be used, because this is the timezone - * biweekly used to parse the date. - */ - if (start != null && !start.hasTime()) { - timezone = TimeZone.getDefault(); - } - - /////////////INCLUDE///////////// - - List include = new ArrayList(); - - if (start != null) { - for (RecurrenceRule rrule : component.getProperties(RecurrenceRule.class)) { - Recurrence recurrence = ValuedProperty.getValue(rrule); - if (recurrence != null) { - include.add(createRecurrenceIterator(recurrence, start, timezone)); - } - } - } - - List allDates = new ArrayList(); - for (RecurrenceDates rdate : component.getProperties(RecurrenceDates.class)) { - allDates.addAll(rdate.getDates()); - } - if (!allDates.isEmpty()) { - include.add(new ICalDateRecurrenceIterator(allDates)); - } - - if (include.isEmpty()) { - if (start == null) { - return new EmptyDateIterator(); - } - include.add(new ICalDateRecurrenceIterator(Collections.singletonList(start))); - } - - /////////////EXCLUDE///////////// - - List exclude = new ArrayList(); - - if (start != null) { - for (ExceptionRule exrule : component.getProperties(ExceptionRule.class)) { - Recurrence recurrence = ValuedProperty.getValue(exrule); - if (recurrence != null) { - exclude.add(createRecurrenceIterator(recurrence, start, timezone)); - } - } - } - - allDates = new ArrayList(); - for (ExceptionDates exdate : component.getProperties(ExceptionDates.class)) { - allDates.addAll(exdate.getValues()); - } - if (!allDates.isEmpty()) { - exclude.add(new ICalDateRecurrenceIterator(allDates)); - } - - /////////////JOIN///////////// - - RecurrenceIterator includeJoined = join(include); - if (exclude.isEmpty()) { - return DateIteratorFactory.createDateIterator(includeJoined); - } - - RecurrenceIterator excludeJoined = join(exclude); - RecurrenceIterator iterator = RecurrenceIteratorFactory.except(includeJoined, excludeJoined); - return DateIteratorFactory.createDateIterator(iterator); - } - - /** - * Creates a single {@link RecurrenceIterator} that is a union of the given - * iterators. - * @param iterators the iterators - * @return the union of the given iterators - * @see RecurrenceIteratorFactory#join - */ - private static RecurrenceIterator join(List iterators) { - if (iterators.size() == 1) { - return iterators.get(0); - } - RecurrenceIterator first = iterators.get(0); - List rest = iterators.subList(1, iterators.size()); - return RecurrenceIteratorFactory.join(first, rest.toArray(new RecurrenceIterator[0])); - } - - /** - * Returns a UTC timezone object. - * @return the timezone object - */ - private static TimeZone utc() { - return TimeZone.getTimeZone("UTC"); - } - - /** - * A {@link DateIterator} with nothing in it. - */ - public static class EmptyDateIterator implements DateIterator { - public boolean hasNext() { - return false; - } - - public Date next() { - throw new NoSuchElementException(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public void advanceTo(Date newStartUtc) { - //empty - } - } - - private static class ICalDateRecurrenceIterator implements RecurrenceIterator { - private final List dates; - private int index = 0; - - /* - * Note: I don't think a timezone needs to be passed in here, because it - * appears that the DateValue objects are expected to be in UTC (judging - * by the parameter name in the "advanceTo" method). - */ - public ICalDateRecurrenceIterator(List dates) { - this.dates = new ArrayList(dates); - Collections.sort(this.dates); - } - - public boolean hasNext() { - return index < dates.size(); - } - - public DateValue next() { - ICalDate next = dates.get(index++); - return convertUtc(next); - } - - public void advanceTo(DateValue newStartUtc) { - ICalDate newStart = convertUtc(newStartUtc); - while (index < dates.size() && newStart.compareTo(dates.get(index)) > 0) { - index++; - } - } - - public void remove() { - throw new UnsupportedOperationException(); - } - } - - private Google2445Utils() { - //hide - } -} diff --git a/app/src/main/java/biweekly/util/ICalDate.java b/app/src/main/java/biweekly/util/ICalDate.java deleted file mode 100644 index 76fa21b7ef..0000000000 --- a/app/src/main/java/biweekly/util/ICalDate.java +++ /dev/null @@ -1,141 +0,0 @@ -package biweekly.util; - -import java.util.Calendar; -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a date-time value. Includes extra information that is used within - * this library. - * @author Michael Angstadt - */ -public class ICalDate extends Date { - private static final long serialVersionUID = -8172624513821588097L; - - private final DateTimeComponents rawComponents; - private final boolean hasTime; - - /** - * Creates a new date-time value set to the current date and time. - */ - public ICalDate() { - this(true); - } - - /** - * Creates a new date-time value set to the current date or time. - * @param hasTime true to include the time component, false not to - */ - public ICalDate(boolean hasTime) { - this(new Date(), null, hasTime); - } - - /** - * Creates a new date-time value (includes the time component). - * @param date the date-time value - */ - public ICalDate(Date date) { - this(date, true); - } - - /** - * Creates a new date-time value. - * @param date the date-time value - * @param hasTime true to include the time component, false not to - */ - public ICalDate(Date date, boolean hasTime) { - this(date, null, hasTime); - } - - /** - * Creates a new date-time value. - * @param date the date-time value components - * @param hasTime true to include the time component, false not to - */ - public ICalDate(DateTimeComponents date, boolean hasTime) { - this(date.toDate(), date, hasTime); - } - - /** - * Copies another iCal date-time value. - * @param date the date-time value - */ - public ICalDate(ICalDate date) { - this(date, (date.rawComponents == null) ? null : new DateTimeComponents(date.rawComponents), date.hasTime); - } - - /** - * Creates a new date-time value. - * @param date the date-time value - * @param rawComponents the raw date-time value as parsed from the input - * stream - * @param hasTime true if the date-time value has a time component, false if - * not - */ - public ICalDate(Date date, DateTimeComponents rawComponents, boolean hasTime) { - if (!hasTime) { - Calendar c = Calendar.getInstance(); - c.setTime(date); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - date = c.getTime(); - } - - setTime(date.getTime()); - this.rawComponents = rawComponents; - this.hasTime = hasTime; - } - - /** - * Gets the raw date-time components of the value as read from the input - * stream. - * @return the raw date-time components or null if not set - */ - public DateTimeComponents getRawComponents() { - return rawComponents; - } - - /** - * Gets whether the value contains a time component. - * @return true if the value contains a time component, false if it's - * strictly a date. - */ - public boolean hasTime() { - return hasTime; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof ICalDate) { - ICalDate other = (ICalDate) obj; - if (hasTime != other.hasTime) return false; - } - return super.equals(obj); - } -} diff --git a/app/src/main/java/biweekly/util/ICalDateFormat.java b/app/src/main/java/biweekly/util/ICalDateFormat.java deleted file mode 100644 index fa77c5b70f..0000000000 --- a/app/src/main/java/biweekly/util/ICalDateFormat.java +++ /dev/null @@ -1,379 +0,0 @@ -package biweekly.util; - -import java.text.DateFormat; -import java.text.FieldPosition; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Defines all of the date formats that are used in iCalendar objects, and also - * parses/formats iCalendar dates. These date formats are defined in the ISO8601 - * specification. - * @author Michael Angstadt - */ -public enum ICalDateFormat { - //@formatter:off - /** - * Example: 20120701 - */ - DATE_BASIC( - "yyyyMMdd"), - - /** - * Example: 2012-07-01 - */ - DATE_EXTENDED( - "yyyy-MM-dd"), - - /** - * Example: 20120701T142110-0500 - */ - DATE_TIME_BASIC( - "yyyyMMdd'T'HHmmssZ"), - - /** - * Example: 20120701T142110 - */ - DATE_TIME_BASIC_WITHOUT_TZ( - "yyyyMMdd'T'HHmmss"), - - /** - * Example: 2012-07-01T14:21:10-05:00 - */ - DATE_TIME_EXTENDED( - "yyyy-MM-dd'T'HH:mm:ssZ"){ - @Override - public DateFormat getDateFormat(TimeZone timezone) { - DateFormat df = new SimpleDateFormat(formatStr, Locale.ROOT){ - private static final long serialVersionUID = -297452842012115768L; - - @Override - public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition){ - StringBuffer sb = super.format(date, toAppendTo, fieldPosition); - - //add a colon between the hour and minute offsets - sb.insert(sb.length()-2, ':'); - - return sb; - } - }; - - if (timezone != null){ - df.setTimeZone(timezone); - } - - return df; - } - }, - - /** - * Example: 2012-07-01T14:21:10 - */ - DATE_TIME_EXTENDED_WITHOUT_TZ( - "yyyy-MM-dd'T'HH:mm:ss"), - - /** - * Example: 20120701T192110Z - */ - UTC_TIME_BASIC( - "yyyyMMdd'T'HHmmss'Z'"){ - @Override - public DateFormat getDateFormat(TimeZone timezone) { - //always use the UTC timezone - timezone = TimeZone.getTimeZone("UTC"); - return super.getDateFormat(timezone); - } - }, - - /** - * Example: 2012-07-01T19:21:10Z - */ - UTC_TIME_EXTENDED( - "yyyy-MM-dd'T'HH:mm:ss'Z'"){ - @Override - public DateFormat getDateFormat(TimeZone timezone) { - //always use the UTC timezone - timezone = TimeZone.getTimeZone("UTC"); - return super.getDateFormat(timezone); - } - }; - //@formatter:on - - /** - * The {@link SimpleDateFormat} format string used for parsing dates. - */ - protected final String formatStr; - - /** - * @param formatStr the {@link SimpleDateFormat} format string used for - * parsing dates. - */ - ICalDateFormat(String formatStr) { - this.formatStr = formatStr; - } - - /** - * Builds a {@link DateFormat} object for parsing and formating dates in - * this ISO format. - * @return the {@link DateFormat} object - */ - public DateFormat getDateFormat() { - return getDateFormat(null); - } - - /** - * Builds a {@link DateFormat} object for parsing and formating dates in - * this ISO format. - * @param timezone the timezone the date is in or null for the default - * timezone - * @return the {@link DateFormat} object - */ - public DateFormat getDateFormat(TimeZone timezone) { - DateFormat df = new SimpleDateFormat(formatStr, Locale.ROOT); - if (timezone != null) { - df.setTimeZone(timezone); - } - return df; - } - - /** - * Formats a date in this ISO format. - * @param date the date to format - * @return the date string - */ - public String format(Date date) { - return format(date, null); - } - - /** - * Formats a date in this ISO format. - * @param date the date to format - * @param timezone the timezone to format the date in or null for the - * default timezone - * @return the date string - */ - public String format(Date date, TimeZone timezone) { - DateFormat df = getDateFormat(timezone); - return df.format(date); - } - - /** - * Parses an iCalendar date. - * @param dateStr the date string to parse (e.g. "20130609T181023Z") - * @return the parsed date - * @throws IllegalArgumentException if the date string isn't in one of the - * accepted ISO8601 formats - */ - public static Date parse(String dateStr) { - return parse(dateStr, null); - } - - /** - * Parses an iCalendar date. - * @param dateStr the date string to parse (e.g. "20130609T181023Z") - * @param timezone the timezone to parse the date under or null to use the - * JVM's default timezone. If the date string contains its own UTC offset, - * then that will be used instead. - * @return the parsed date - * @throws IllegalArgumentException if the date string isn't in one of the - * accepted ISO8601 formats - */ - public static Date parse(String dateStr, TimeZone timezone) { - TimestampPattern p = new TimestampPattern(dateStr); - if (!p.matches()) { - throw parseException(dateStr); - } - - if (p.hasOffset()) { - timezone = TimeZone.getTimeZone("UTC"); - } else if (timezone == null) { - timezone = TimeZone.getDefault(); - } - - Calendar c = Calendar.getInstance(timezone); - c.clear(); - - c.set(Calendar.YEAR, p.year()); - c.set(Calendar.MONTH, p.month() - 1); - c.set(Calendar.DATE, p.date()); - - if (p.hasTime()) { - c.set(Calendar.HOUR_OF_DAY, p.hour()); - c.set(Calendar.MINUTE, p.minute()); - c.set(Calendar.SECOND, p.second()); - c.set(Calendar.MILLISECOND, p.millisecond()); - - if (p.hasOffset()) { - c.set(Calendar.ZONE_OFFSET, p.offsetMillis()); - } - } - - return c.getTime(); - } - - /** - * Wrapper for a complex regular expression that parses multiple date - * formats. - */ - private static class TimestampPattern { - //@formatter:off - private static final Pattern regex = Pattern.compile( - "^(\\d{4})-?(\\d{2})-?(\\d{2})" + - "(" + - "T(\\d{2}):?(\\d{2}):?(\\d{2})(\\.\\d+)?" + - "(" + - "Z|([-+])((\\d{2})|((\\d{2}):?(\\d{2})))" + - ")?" + - ")?$" - ); - //@formatter:on - - private final Matcher m; - private final boolean matches; - - public TimestampPattern(String str) { - m = regex.matcher(str); - matches = m.find(); - } - - public boolean matches() { - return matches; - } - - public int year() { - return parseInt(1); - } - - public int month() { - return parseInt(2); - } - - public int date() { - return parseInt(3); - } - - public boolean hasTime() { - return m.group(5) != null; - } - - public int hour() { - return parseInt(5); - } - - public int minute() { - return parseInt(6); - } - - public int second() { - return parseInt(7); - } - - public int millisecond() { - if (m.group(8) == null) { - return 0; - } - - double ms = Double.parseDouble(m.group(8)) * 1000; - return (int) Math.round(ms); - } - - public boolean hasOffset() { - return m.group(9) != null; - } - - public int offsetMillis() { - if (m.group(9).equals("Z")) { - return 0; - } - - int positive = m.group(10).equals("+") ? 1 : -1; - - int offsetHour, offsetMinute; - if (m.group(12) != null) { - offsetHour = parseInt(12); - offsetMinute = 0; - } else { - offsetHour = parseInt(14); - offsetMinute = parseInt(15); - } - - return (offsetHour * 60 * 60 * 1000 + offsetMinute * 60 * 1000) * positive; - } - - private int parseInt(int group) { - return Integer.parseInt(m.group(group)); - } - } - - /** - * Determines whether a date string has a time component. - * @param dateStr the date string (e.g. "20130601T120000") - * @return true if it has a time component, false if not - */ - public static boolean dateHasTime(String dateStr) { - return dateStr.contains("T"); - } - - /** - * Determines whether a date string is in UTC time or has a timezone offset. - * @param dateStr the date string (e.g. "20130601T120000Z", - * "20130601T120000-0400") - * @return true if it has a timezone, false if not - */ - public static boolean dateHasTimezone(String dateStr) { - return isUTC(dateStr) || dateStr.matches(".*?[-+]\\d\\d:?\\d\\d"); - } - - /** - * Determines if a date string is in UTC time. - * @param dateStr the date string (e.g. "20130601T120000Z") - * @return true if it's in UTC, false if not - */ - public static boolean isUTC(String dateStr) { - return dateStr.endsWith("Z"); - } - - /** - * Gets the {@link TimeZone} object that corresponds to the given ID. - * @param timezoneId the timezone ID (e.g. "America/New_York") - * @return the timezone object or null if not found - */ - public static TimeZone parseTimeZoneId(String timezoneId) { - TimeZone timezone = TimeZone.getTimeZone(timezoneId); - return "GMT".equals(timezone.getID()) && !"GMT".equalsIgnoreCase(timezoneId) ? null : timezone; - } - - private static IllegalArgumentException parseException(String dateStr) { - return new IllegalArgumentException("Date string \"" + dateStr + "\" is not in a valid ISO-8601 format."); - } -} diff --git a/app/src/main/java/biweekly/util/ICalFloatFormatter.java b/app/src/main/java/biweekly/util/ICalFloatFormatter.java deleted file mode 100644 index de04807fce..0000000000 --- a/app/src/main/java/biweekly/util/ICalFloatFormatter.java +++ /dev/null @@ -1,71 +0,0 @@ -package biweekly.util; - -import java.text.NumberFormat; -import java.util.Locale; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Formats floating-point values for iCalendar objects. This ensures that numbers - * are rendered the same, no matter the default locale. - *

- *
    - *
  • Decimal separator can differ by locale (e.g. Germany uses ",")
  • - *
  • Number characters can differ by locale (e.g. "1.0" is "Û±Ù«Û°" in Iran)
  • - *
- * @author Michael Angstadt - */ -public class ICalFloatFormatter { - private final NumberFormat nf = NumberFormat.getNumberInstance(Locale.ROOT); - - /** - * Creates a new formatter with a max of 6 decimals. - */ - public ICalFloatFormatter() { - this(6); - } - - /** - * Creates a new formatter. - * @param decimals the max number of decimal places - */ - public ICalFloatFormatter(int decimals) { - nf.setMaximumFractionDigits(decimals); - if (decimals > 0) { - nf.setMinimumFractionDigits(1); - } - } - - /** - * Formats a number for inclusion in an iCalendar object. - * @param number the number - * @return the formatted number - */ - public String format(double number) { - return nf.format(number); - } -} diff --git a/app/src/main/java/biweekly/util/IOUtils.java b/app/src/main/java/biweekly/util/IOUtils.java deleted file mode 100644 index f9d8cc3d2f..0000000000 --- a/app/src/main/java/biweekly/util/IOUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -package biweekly.util; - -import java.io.Closeable; -import java.io.IOException; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * I/O helper classes. - * @author Michael Angstadt - */ -public final class IOUtils { - /** - * Closes a closeable resource, catching its {@link IOException}. - * @param closeable the resource to close (can be null) - */ - public static void closeQuietly(Closeable closeable) { - try { - if (closeable != null) { - closeable.close(); - } - } catch (IOException e) { - //ignore - } - } - - private IOUtils() { - //hide - } -} diff --git a/app/src/main/java/biweekly/util/ListMultimap.java b/app/src/main/java/biweekly/util/ListMultimap.java deleted file mode 100644 index f5c20e5c83..0000000000 --- a/app/src/main/java/biweekly/util/ListMultimap.java +++ /dev/null @@ -1,746 +0,0 @@ -package biweekly.util; - -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (C) 2007 The Guava Authors - * - * 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. - */ - -/** - * A multimap that uses {@link ArrayList} objects to store its values. The - * internal {@link Map} implementation is a {@link LinkedHashMap}. - * @author Michael Angstadt - * @param the key - * @param the value - */ -public class ListMultimap implements Iterable>> { - private final Map> map; - - /** - * Creates an empty multimap. - */ - public ListMultimap() { - this(new LinkedHashMap>()); - } - - /** - * Creates an empty multimap. - * @param initialCapacity the initial capacity of the underlying map. - */ - public ListMultimap(int initialCapacity) { - this(new LinkedHashMap>(initialCapacity)); - } - - /** - * Creates a copy of an existing multimap. - * @param orig the multimap to copy from - */ - public ListMultimap(ListMultimap orig) { - this(copy(orig.map)); - } - - private static Map> copy(Map> orig) { - Map> map = new LinkedHashMap>(orig.size()); - for (Map.Entry> entry : orig.entrySet()) { - List values = new ArrayList(entry.getValue()); - map.put(entry.getKey(), values); - } - return map; - } - - /** - *

- * Creates a new multimap backed by the given map. Changes made to the given - * map will effect the multimap and vice versa. - *

- *

- * To avoid problems, it is highly recommended that the given map NOT be - * modified by anything other than this {@link ListMultimap} class after - * being passed into this constructor. - *

- * @param map the backing map - */ - public ListMultimap(Map> map) { - this.map = map; - } - - /** - * Adds a value to the multimap. - * @param key the key - * @param value the value to add - */ - public void put(K key, V value) { - key = sanitizeKey(key); - List list = map.get(key); - if (list == null) { - list = new ArrayList(); - map.put(key, list); - } - list.add(value); - } - - /** - * Adds multiple values to the multimap. - * @param key the key - * @param values the values to add - */ - public void putAll(K key, Collection values) { - if (values.isEmpty()) { - return; - } - - key = sanitizeKey(key); - List list = map.get(key); - if (list == null) { - list = new ArrayList(); - map.put(key, list); - } - list.addAll(values); - } - - /** - * Gets the values associated with the key. Changes to the returned list - * will update the underlying multimap, and vice versa. - * @param key the key - * @return the list of values or empty list if the key doesn't exist - */ - public List get(K key) { - key = sanitizeKey(key); - List value = map.get(key); - if (value == null) { - value = new ArrayList(0); - } - return new WrappedList(key, value, null); - } - - /** - * Gets the first value that's associated with a key. - * @param key the key - * @return the first value or null if the key doesn't exist - */ - public V first(K key) { - key = sanitizeKey(key); - List values = map.get(key); - - /* - * The list can be null, but never empty. Empty lists are removed from - * the map. - */ - return (values == null) ? null : values.get(0); - } - - /** - * Determines whether the given key exists. - * @param key the key - * @return true if the key exists, false if not - */ - public boolean containsKey(K key) { - key = sanitizeKey(key); - return map.containsKey(key); - } - - /** - * Removes a particular value. - * @param key the key - * @param value the value to remove - * @return true if the multimap contained the value, false if not - */ - public boolean remove(K key, V value) { - key = sanitizeKey(key); - List values = map.get(key); - if (values == null) { - return false; - } - - boolean success = values.remove(value); - if (values.isEmpty()) { - map.remove(key); - } - return success; - } - - /** - * Removes all the values associated with a key - * @param key the key to remove - * @return the removed values or an empty list if the key doesn't exist - * (this list is immutable) - */ - public List removeAll(K key) { - key = sanitizeKey(key); - List removed = map.remove(key); - if (removed == null) { - return Collections.emptyList(); - } - - List unmodifiableCopy = Collections.unmodifiableList(new ArrayList(removed)); - removed.clear(); - return unmodifiableCopy; - } - - /** - * Replaces all values with the given value. - * @param key the key - * @param value the value with which to replace all existing values, or null - * to remove all values - * @return the values that were replaced (this list is immutable) - */ - public List replace(K key, V value) { - List replaced = removeAll(key); - if (value != null) { - put(key, value); - } - return replaced; - } - - /** - * Replaces all values with the given values. - * @param key the key - * @param values the values with which to replace all existing values - * @return the values that were replaced (this list is immutable) - */ - public List replace(K key, Collection values) { - List replaced = removeAll(key); - putAll(key, values); - return replaced; - } - - /** - * Clears all entries from the multimap. - */ - public void clear() { - //clear each collection to make previously returned lists empty - for (List value : map.values()) { - value.clear(); - } - map.clear(); - } - - /** - * Gets all the keys in the multimap. - * @return the keys (this set is immutable) - */ - public Set keySet() { - return Collections.unmodifiableSet(map.keySet()); - } - - /** - * Gets all the values in the multimap. - * @return the values (this list is immutable) - */ - public List values() { - List list = new ArrayList(); - for (List value : map.values()) { - list.addAll(value); - } - return Collections.unmodifiableList(list); - } - - /** - * Determines if the multimap is empty or not. - * @return true if it's empty, false if not - */ - public boolean isEmpty() { - return size() == 0; - } - - /** - * Gets the number of values in the map. - * @return the number of values - */ - public int size() { - int size = 0; - for (List value : map.values()) { - size += value.size(); - } - return size; - } - - /** - * Gets an immutable view of the underlying {@link Map} object. - * @return an immutable map - */ - public Map> asMap() { - Map> view = new LinkedHashMap>(map.size()); - for (Map.Entry> entry : map.entrySet()) { - K key = entry.getKey(); - List value = entry.getValue(); - view.put(key, Collections.unmodifiableList(value)); - } - return Collections.unmodifiableMap(view); - } - - /** - * Gets the {@link Map} that backs this multimap. This method is here for - * performances reasons. The returned map should NOT be modified by anything - * other than the {@link ListMultimap} object that owns it. - * @return the map - */ - public Map> getMap() { - return map; - } - - /** - * Modifies a given key before it is used to interact with the internal map. - * This method is meant to be overridden by child classes if necessary. - * @param key the key - * @return the modified key (by default, the key is returned as-is) - */ - protected K sanitizeKey(K key) { - return key; - } - - /** - * Gets an iterator for iterating over the entries in the map. This iterator - * iterates over an immutable view of the map. - * @return the iterator - */ - //@Override - public Iterator>> iterator() { - final Iterator>> it = map.entrySet().iterator(); - return new Iterator>>() { - public boolean hasNext() { - return it.hasNext(); - } - - public Entry> next() { - final Entry> next = it.next(); - return new Entry>() { - public K getKey() { - return next.getKey(); - } - - public List getValue() { - return Collections.unmodifiableList(next.getValue()); - } - - public List setValue(List value) { - throw new UnsupportedOperationException(); - } - }; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public String toString() { - return map.toString(); - } - - @Override - public int hashCode() { - return map.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - ListMultimap other = (ListMultimap) obj; - return map.equals(other.map); - } - - /** - * Note: This class is a modified version of the - * "AbstractMapBasedMultimap.WrappedList" class from the - * Guava. - * - *

- * Collection decorator that stays in sync with the multimap values for a - * key. There are two kinds of wrapped collections: full and subcollections. - * Both have a delegate pointing to the underlying collection class. - * - *

- * Full collections, identified by a null ancestor field, contain all - * multimap values for a given key. Its delegate is a value in the - * multimap's underlying {@link Map} whenever the delegate is non-empty. The - * {@code refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} - * methods ensure that the {@code WrappedList} and map remain consistent. - * - *

- * A subcollection, such as a sublist, contains some of the values for a - * given key. Its ancestor field points to the full wrapped collection with - * all values for the key. The subcollection {@code refreshIfEmpty}, - * {@code removeIfEmpty}, and {@code addToMap} methods call the - * corresponding methods of the full wrapped collection. - */ - private class WrappedList extends AbstractCollection implements List { - final K key; - List delegate; - final WrappedList ancestor; - final List ancestorDelegate; - - WrappedList(K key, List delegate, WrappedList ancestor) { - this.key = key; - this.delegate = delegate; - this.ancestor = ancestor; - this.ancestorDelegate = (ancestor == null) ? null : ancestor.getDelegate(); - } - - public boolean addAll(int index, Collection collection) { - if (collection.isEmpty()) { - return false; - } - int oldSize = size(); // calls refreshIfEmpty - boolean changed = getDelegate().addAll(index, collection); - if (changed && oldSize == 0) { - addToMap(); - } - return changed; - } - - public V get(int index) { - refreshIfEmpty(); - return getDelegate().get(index); - } - - public V set(int index, V element) { - refreshIfEmpty(); - return getDelegate().set(index, element); - } - - public void add(int index, V element) { - refreshIfEmpty(); - boolean wasEmpty = getDelegate().isEmpty(); - getDelegate().add(index, element); - if (wasEmpty) { - addToMap(); - } - } - - public V remove(int index) { - refreshIfEmpty(); - V value = getDelegate().remove(index); - removeIfEmpty(); - return value; - } - - public int indexOf(Object o) { - refreshIfEmpty(); - return getDelegate().indexOf(o); - } - - public int lastIndexOf(Object o) { - refreshIfEmpty(); - return getDelegate().lastIndexOf(o); - } - - public ListIterator listIterator() { - refreshIfEmpty(); - return new WrappedListIterator(); - } - - public ListIterator listIterator(int index) { - refreshIfEmpty(); - return new WrappedListIterator(index); - } - - public List subList(int fromIndex, int toIndex) { - refreshIfEmpty(); - return new WrappedList(getKey(), getDelegate().subList(fromIndex, toIndex), (getAncestor() == null) ? this : getAncestor()); - } - - /** - * If the delegate collection is empty, but the multimap has values for - * the key, replace the delegate with the new collection for the key. - * - *

- * For a subcollection, refresh its ancestor and validate that the - * ancestor delegate hasn't changed. - */ - void refreshIfEmpty() { - if (ancestor != null) { - ancestor.refreshIfEmpty(); - if (ancestor.getDelegate() != ancestorDelegate) { - throw new ConcurrentModificationException(); - } - } else if (delegate.isEmpty()) { - List newDelegate = map.get(key); - if (newDelegate != null) { - delegate = newDelegate; - } - } - } - - /** - * If collection is empty, remove it from - * {@code AbstractMapBasedMultimap.this.map}. For subcollections, check - * whether the ancestor collection is empty. - */ - void removeIfEmpty() { - if (ancestor != null) { - ancestor.removeIfEmpty(); - } else if (delegate.isEmpty()) { - map.remove(key); - } - } - - K getKey() { - return key; - } - - /** - * Add the delegate to the map. Other {@code WrappedCollection} methods - * should call this method after adding elements to a previously empty - * collection. - * - *

- * Subcollection add the ancestor's delegate instead. - */ - void addToMap() { - if (ancestor != null) { - ancestor.addToMap(); - } else { - map.put(key, delegate); - } - } - - @Override - public int size() { - refreshIfEmpty(); - return delegate.size(); - } - - @Override - public boolean equals(Object object) { - if (object == this) { - return true; - } - refreshIfEmpty(); - return delegate.equals(object); - } - - @Override - public int hashCode() { - refreshIfEmpty(); - return delegate.hashCode(); - } - - @Override - public String toString() { - refreshIfEmpty(); - return delegate.toString(); - } - - List getDelegate() { - return delegate; - } - - @Override - public Iterator iterator() { - refreshIfEmpty(); - return new WrappedListIterator(); - } - - @Override - public boolean add(V value) { - refreshIfEmpty(); - boolean wasEmpty = delegate.isEmpty(); - boolean changed = delegate.add(value); - if (changed && wasEmpty) { - addToMap(); - } - return changed; - } - - WrappedList getAncestor() { - return ancestor; - } - - // The following methods are provided for better performance. - - @Override - public boolean addAll(Collection collection) { - if (collection.isEmpty()) { - return false; - } - int oldSize = size(); // calls refreshIfEmpty - boolean changed = delegate.addAll(collection); - if (changed && oldSize == 0) { - addToMap(); - } - return changed; - } - - @Override - public boolean contains(Object o) { - refreshIfEmpty(); - return delegate.contains(o); - } - - @Override - public boolean containsAll(Collection c) { - refreshIfEmpty(); - return delegate.containsAll(c); - } - - @Override - public void clear() { - int oldSize = size(); // calls refreshIfEmpty - if (oldSize == 0) { - return; - } - delegate.clear(); - removeIfEmpty(); // maybe shouldn't be removed if this is a sublist - } - - @Override - public boolean remove(Object o) { - refreshIfEmpty(); - boolean changed = delegate.remove(o); - if (changed) { - removeIfEmpty(); - } - return changed; - } - - @Override - public boolean removeAll(Collection collection) { - if (collection.isEmpty()) { - return false; - } - refreshIfEmpty(); - boolean changed = delegate.removeAll(collection); - if (changed) { - removeIfEmpty(); - } - return changed; - } - - @Override - public boolean retainAll(Collection c) { - refreshIfEmpty(); - boolean changed = delegate.retainAll(c); - if (changed) { - removeIfEmpty(); - } - return changed; - } - - /** ListIterator decorator. */ - private class WrappedListIterator implements ListIterator { - final ListIterator delegateIterator; - final List originalDelegate = delegate; - - WrappedListIterator() { - delegateIterator = delegate.listIterator(); - } - - public WrappedListIterator(int index) { - delegateIterator = delegate.listIterator(index); - } - - public boolean hasPrevious() { - return getDelegateIterator().hasPrevious(); - } - - public V previous() { - return getDelegateIterator().previous(); - } - - public int nextIndex() { - return getDelegateIterator().nextIndex(); - } - - public int previousIndex() { - return getDelegateIterator().previousIndex(); - } - - public void set(V value) { - getDelegateIterator().set(value); - } - - public void add(V value) { - boolean wasEmpty = isEmpty(); - getDelegateIterator().add(value); - if (wasEmpty) { - addToMap(); - } - } - - /** - * If the delegate changed since the iterator was created, the - * iterator is no longer valid. - */ - void validateIterator() { - refreshIfEmpty(); - if (delegate != originalDelegate) { - throw new ConcurrentModificationException(); - } - } - - public boolean hasNext() { - validateIterator(); - return delegateIterator.hasNext(); - } - - public V next() { - validateIterator(); - return delegateIterator.next(); - } - - public void remove() { - delegateIterator.remove(); - removeIfEmpty(); - } - - ListIterator getDelegateIterator() { - validateIterator(); - return delegateIterator; - } - } - } -} diff --git a/app/src/main/java/biweekly/util/Period.java b/app/src/main/java/biweekly/util/Period.java deleted file mode 100644 index b86ae46c91..0000000000 --- a/app/src/main/java/biweekly/util/Period.java +++ /dev/null @@ -1,160 +0,0 @@ -package biweekly.util; - -import java.util.Date; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * A period of time. - * @author Michael Angstadt - */ -public final class Period { - /* - * Note: The getter methods must not make copies of the date objects they - * return! The date objects in this class must be directly referenced in - * order to support timezones. - * - * Yes, this means that this class is not fully immutable. Date objects can - * be modified by calling "setTime()", but biweekly makes use of this method - * in order to convert dates into their proper timezones. - */ - private final ICalDate startDate; - private final ICalDate endDate; - private final Duration duration; - - /** - * Creates a new time period. - * @param startDate the start date - * @param endDate the end date - */ - public Period(Date startDate, Date endDate) { - //@formatter:off - this( - (startDate == null) ? null : new ICalDate(startDate), - (endDate == null) ? null : new ICalDate(endDate) - ); - //@formatter:on - } - - /** - * Creates a new time period. - * @param startDate the start date - * @param endDate the end date - */ - public Period(ICalDate startDate, ICalDate endDate) { - this.startDate = startDate; - this.endDate = endDate; - duration = null; - } - - /** - * Creates a new time period. - * @param startDate the start date - * @param duration the length of time after the start date - */ - public Period(Date startDate, Duration duration) { - //@formatter:off - this( - (startDate == null) ? null : new ICalDate(startDate), - duration - ); - //@formatter:on - } - - /** - * Creates a new time period. - * @param startDate the start date - * @param duration the length of time after the start date - */ - public Period(ICalDate startDate, Duration duration) { - this.startDate = startDate; - this.duration = duration; - endDate = null; - } - - /** - * Copies an existing time period. - * @param period the period to copy - */ - public Period(Period period) { - this.startDate = (period.startDate == null) ? null : new ICalDate(period.startDate); - this.endDate = (period.endDate == null) ? null : new ICalDate(period.endDate); - this.duration = period.duration; - } - - /** - * Gets the start date. - * @return the start date - */ - public ICalDate getStartDate() { - return startDate; - } - - /** - * Gets the end date. This will be null if a duration was defined. - * @return the end date or null if not set - */ - public ICalDate getEndDate() { - return endDate; - } - - /** - * Gets the length of time after the start date. This will be null if an end - * date was defined. - * @return the duration or null if not set - */ - public Duration getDuration() { - return duration; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((duration == null) ? 0 : duration.hashCode()); - result = prime * result + ((endDate == null) ? 0 : endDate.hashCode()); - result = prime * result + ((startDate == null) ? 0 : startDate.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - Period other = (Period) obj; - if (duration == null) { - if (other.duration != null) return false; - } else if (!duration.equals(other.duration)) return false; - if (endDate == null) { - if (other.endDate != null) return false; - } else if (!endDate.equals(other.endDate)) return false; - if (startDate == null) { - if (other.startDate != null) return false; - } else if (!startDate.equals(other.startDate)) return false; - return true; - } -} diff --git a/app/src/main/java/biweekly/util/Recurrence.java b/app/src/main/java/biweekly/util/Recurrence.java deleted file mode 100644 index 555c7dd01e..0000000000 --- a/app/src/main/java/biweekly/util/Recurrence.java +++ /dev/null @@ -1,651 +0,0 @@ -package biweekly.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; - -import biweekly.property.DateStart; -import biweekly.util.com.google.ical.compat.javautil.DateIterator; -import biweekly.util.com.google.ical.compat.javautil.DateIteratorFactory; -import biweekly.util.com.google.ical.iter.RecurrenceIterator; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - *

- * Represents a recurrence rule value. - *

- *

- * This class is immutable. Use the inner class {@link Builder} to construct a - * new instance. - *

- *

- * Code sample: - *

- * - *
- * Recurrence rrule = new Recurrence.Builder(Frequency.WEEKLY).interval(2).build();
- * Recurrence copy = new Recurrence.Builder(rrule).interval(3).build();
- * 
- * @author Michael Angstadt - * @see RFC 5545 - * p.38-45 - */ -public final class Recurrence { - private final Frequency frequency; - private final Integer interval; - private final Integer count; - private final ICalDate until; - private final List bySecond; - private final List byMinute; - private final List byHour; - private final List byMonthDay; - private final List byYearDay; - private final List byWeekNo; - private final List byMonth; - private final List bySetPos; - private final List byDay; - private final DayOfWeek workweekStarts; - private final Map> xrules; - - private Recurrence(Builder builder) { - frequency = builder.frequency; - interval = builder.interval; - count = builder.count; - until = builder.until; - bySecond = Collections.unmodifiableList(builder.bySecond); - byMinute = Collections.unmodifiableList(builder.byMinute); - byHour = Collections.unmodifiableList(builder.byHour); - byMonthDay = Collections.unmodifiableList(builder.byMonthDay); - byYearDay = Collections.unmodifiableList(builder.byYearDay); - byWeekNo = Collections.unmodifiableList(builder.byWeekNo); - byMonth = Collections.unmodifiableList(builder.byMonth); - bySetPos = Collections.unmodifiableList(builder.bySetPos); - byDay = Collections.unmodifiableList(builder.byDay); - workweekStarts = builder.workweekStarts; - xrules = Collections.unmodifiableMap(builder.xrules.getMap()); - } - - /** - * Gets the frequency. - * @return the frequency or null if not set - */ - public Frequency getFrequency() { - return frequency; - } - - /** - * Gets the date that the recurrence stops. - * @return the date or null if not set - */ - public ICalDate getUntil() { - return (until == null) ? null : new ICalDate(until); - } - - /** - * Gets the number of times the rule will be repeated. - * @return the number of times to repeat the rule or null if not set - */ - public Integer getCount() { - return count; - } - - /** - * Gets how often the rule repeats, in relation to the frequency. - * @return the repetition interval or null if not set - */ - public Integer getInterval() { - return interval; - } - - /** - * Gets the BYSECOND rule part. - * @return the BYSECOND rule part or empty list if not set - */ - public List getBySecond() { - return bySecond; - } - - /** - * Gets the BYMINUTE rule part. - * @return the BYMINUTE rule part or empty list if not set - */ - public List getByMinute() { - return byMinute; - } - - /** - * Gets the BYHOUR rule part. - * @return the BYHOUR rule part or empty list if not set - */ - public List getByHour() { - return byHour; - } - - /** - * Gets the day components of the BYDAY rule part. - * @return the day components of the BYDAY rule part or empty list if not - * set - */ - public List getByDay() { - return byDay; - } - - /** - * Gets the BYMONTHDAY rule part. - * @return the BYMONTHDAY rule part or empty list if not set - */ - public List getByMonthDay() { - return byMonthDay; - } - - /** - * Gets the BYYEARDAY rule part. - * @return the BYYEARDAY rule part or empty list if not set - */ - public List getByYearDay() { - return byYearDay; - } - - /** - * Gets the BYWEEKNO rule part. - * @return the BYWEEKNO rule part or empty list if not set - */ - public List getByWeekNo() { - return byWeekNo; - } - - /** - * Gets the BYMONTH rule part. - * @return the BYMONTH rule part or empty list if not set - */ - public List getByMonth() { - return byMonth; - } - - /** - * Gets the BYSETPOS rule part. - * @return the BYSETPOS rule part or empty list if not set - */ - public List getBySetPos() { - return bySetPos; - } - - /** - * Gets the day that the work week starts. - * @return the day that the work week starts or null if not set - */ - public DayOfWeek getWorkweekStarts() { - return workweekStarts; - } - - /** - * Gets the non-standard rule parts. - * @return the non-standard rule parts - */ - public Map> getXRules() { - return xrules; - } - - /** - * Creates an iterator that computes the dates defined by this recurrence. - * @param startDate the date that the recurrence starts (typically, the - * value of the {@link DateStart} property) - * @param timezone the timezone to iterate in (typically, the timezone - * associated with the {@link DateStart} property). This is needed in order - * to adjust for when the iterator passes over a daylight savings boundary. - * @return the iterator - * @see google-rfc-2445 - */ - public DateIterator getDateIterator(Date startDate, TimeZone timezone) { - return getDateIterator(new ICalDate(startDate), timezone); - } - - /** - * Creates an iterator that computes the dates defined by this recurrence. - * @param startDate the date that the recurrence starts (typically, the - * value of the {@link DateStart} property) - * @param timezone the timezone to iterate in (typically, the timezone - * associated with the {@link DateStart} property). This is needed in order - * to adjust for when the iterator passes over a daylight savings boundary. - * @return the iterator - * @see google-rfc-2445 - */ - public DateIterator getDateIterator(ICalDate startDate, TimeZone timezone) { - RecurrenceIterator iterator = Google2445Utils.createRecurrenceIterator(this, startDate, timezone); - return DateIteratorFactory.createDateIterator(iterator); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + byDay.hashCode(); - result = prime * result + byHour.hashCode(); - result = prime * result + byMinute.hashCode(); - result = prime * result + byMonth.hashCode(); - result = prime * result + byMonthDay.hashCode(); - result = prime * result + bySecond.hashCode(); - result = prime * result + bySetPos.hashCode(); - result = prime * result + byWeekNo.hashCode(); - result = prime * result + byYearDay.hashCode(); - result = prime * result + ((count == null) ? 0 : count.hashCode()); - result = prime * result + xrules.hashCode(); - result = prime * result + ((frequency == null) ? 0 : frequency.hashCode()); - result = prime * result + ((interval == null) ? 0 : interval.hashCode()); - result = prime * result + ((until == null) ? 0 : until.hashCode()); - result = prime * result + ((workweekStarts == null) ? 0 : workweekStarts.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - Recurrence other = (Recurrence) obj; - if (!byDay.equals(other.byDay)) return false; - if (!byHour.equals(other.byHour)) return false; - if (!byMinute.equals(other.byMinute)) return false; - if (!byMonth.equals(other.byMonth)) return false; - if (!byMonthDay.equals(other.byMonthDay)) return false; - if (!bySecond.equals(other.bySecond)) return false; - if (!bySetPos.equals(other.bySetPos)) return false; - if (!byWeekNo.equals(other.byWeekNo)) return false; - if (!byYearDay.equals(other.byYearDay)) return false; - if (count == null) { - if (other.count != null) return false; - } else if (!count.equals(other.count)) return false; - if (!xrules.equals(other.xrules)) return false; - if (frequency != other.frequency) return false; - if (interval == null) { - if (other.interval != null) return false; - } else if (!interval.equals(other.interval)) return false; - if (until == null) { - if (other.until != null) return false; - } else if (!until.equals(other.until)) return false; - if (workweekStarts != other.workweekStarts) return false; - return true; - } - - /** - * Constructs {@link Recurrence} objects. - * @author Michael Angstadt - */ - public static class Builder { - private Frequency frequency; - private Integer interval; - private Integer count; - private ICalDate until; - private List bySecond; - private List byMinute; - private List byHour; - private List byDay; - private List byMonthDay; - private List byYearDay; - private List byWeekNo; - private List byMonth; - private List bySetPos; - private DayOfWeek workweekStarts; - private ListMultimap xrules; - - /** - * Constructs a new builder. - * @param frequency the recurrence frequency - */ - public Builder(Frequency frequency) { - this.frequency = frequency; - bySecond = new ArrayList(0); - byMinute = new ArrayList(0); - byHour = new ArrayList(0); - byDay = new ArrayList(0); - byMonthDay = new ArrayList(0); - byYearDay = new ArrayList(0); - byWeekNo = new ArrayList(0); - byMonth = new ArrayList(0); - bySetPos = new ArrayList(0); - xrules = new ListMultimap(0); - } - - /** - * Constructs a new builder - * @param recur the recurrence object to copy from - */ - public Builder(Recurrence recur) { - frequency = recur.frequency; - interval = recur.interval; - count = recur.count; - until = recur.until; - bySecond = new ArrayList(recur.bySecond); - byMinute = new ArrayList(recur.byMinute); - byHour = new ArrayList(recur.byHour); - byDay = new ArrayList(recur.byDay); - byMonthDay = new ArrayList(recur.byMonthDay); - byYearDay = new ArrayList(recur.byYearDay); - byWeekNo = new ArrayList(recur.byWeekNo); - byMonth = new ArrayList(recur.byMonth); - bySetPos = new ArrayList(recur.bySetPos); - workweekStarts = recur.workweekStarts; - - Map> map = new HashMap>(recur.xrules); - xrules = new ListMultimap(map); - } - - /** - * Sets the frequency - * @param frequency the frequency - * @return this - */ - public Builder frequency(Frequency frequency) { - this.frequency = frequency; - return this; - } - - /** - * Sets the date that the recurrence stops. Note that the UNTIL and - * COUNT fields cannot both be defined within the same rule. - * @param until the date - * @return this - */ - public Builder until(ICalDate until) { - this.until = (until == null) ? null : new ICalDate(until); - return this; - } - - /** - * Sets the date that the recurrence stops. Note that the UNTIL and - * COUNT fields cannot both be defined within the same rule. - * @param until the date (time component will be included) - * @return this - */ - public Builder until(Date until) { - return until(until, true); - } - - /** - * Sets the date that the recurrence stops. Note that the UNTIL and - * COUNT fields cannot both be defined within the same rule. - * @param until the date - * @param hasTime true to include the time component, false if it's - * strictly a date - * @return this - */ - public Builder until(Date until, boolean hasTime) { - this.until = new ICalDate(until, hasTime); - return this; - } - - /** - * Gets the number of times the rule will be repeated. Note that the - * UNTIL and COUNT fields cannot both be defined within the same rule. - * @param count the number of times to repeat the rule - * @return this - */ - public Builder count(Integer count) { - this.count = count; - return this; - } - - /** - * Gets how often the rule repeats, in relation to the frequency. - * @param interval the repetition interval - * @return this - */ - public Builder interval(Integer interval) { - this.interval = interval; - return this; - } - - /** - * Adds one or more BYSECOND rule parts. - * @param seconds the seconds to add - * @return this - */ - public Builder bySecond(Integer... seconds) { - return bySecond(Arrays.asList(seconds)); - } - - /** - * Adds one or more BYSECOND rule parts. - * @param seconds the seconds to add - * @return this - */ - public Builder bySecond(Collection seconds) { - bySecond.addAll(seconds); - return this; - } - - /** - * Adds one or more BYMINUTE rule parts. - * @param minutes the minutes to add - * @return this - */ - public Builder byMinute(Integer... minutes) { - return byMinute(Arrays.asList(minutes)); - } - - /** - * Adds one or more BYMINUTE rule parts. - * @param minutes the minutes to add - * @return this - */ - public Builder byMinute(Collection minutes) { - byMinute.addAll(minutes); - return this; - } - - /** - * Adds one or more BYHOUR rule parts. - * @param hours the hours to add - * @return this - */ - public Builder byHour(Integer... hours) { - return byHour(Arrays.asList(hours)); - } - - /** - * Adds one or more BYHOUR rule parts. - * @param hours the hours to add - * @return this - */ - public Builder byHour(Collection hours) { - this.byHour.addAll(hours); - return this; - } - - /** - * Adds one or more BYMONTHDAY rule parts. - * @param monthDays the month days to add - * @return this - */ - public Builder byMonthDay(Integer... monthDays) { - return byMonthDay(Arrays.asList(monthDays)); - } - - /** - * Adds one or more BYMONTHDAY rule parts. - * @param monthDays the month days to add - * @return this - */ - public Builder byMonthDay(Collection monthDays) { - byMonthDay.addAll(monthDays); - return this; - } - - /** - * Adds one or more BYYEARDAY rule parts. - * @param yearDays the year days to add - * @return this - */ - public Builder byYearDay(Integer... yearDays) { - return byYearDay(Arrays.asList(yearDays)); - } - - /** - * Adds one or more BYYEARDAY rule parts. - * @param yearDays the year days to add - * @return this - */ - public Builder byYearDay(Collection yearDays) { - byYearDay.addAll(yearDays); - return this; - } - - /** - * Adds one or more BYWEEKNO rule parts. - * @param weekNumbers the week numbers to add - * @return this - */ - public Builder byWeekNo(Integer... weekNumbers) { - return byWeekNo(Arrays.asList(weekNumbers)); - } - - /** - * Adds one or more BYWEEKNO rule parts. - * @param weekNumbers the week numbers to add - * @return this - */ - public Builder byWeekNo(Collection weekNumbers) { - byWeekNo.addAll(weekNumbers); - return this; - } - - /** - * Adds one or more BYMONTH rule parts. - * @param months the months to add - * @return this - */ - public Builder byMonth(Integer... months) { - return byMonth(Arrays.asList(months)); - } - - /** - * Adds one or more BYMONTH rule parts. - * @param months the months to add - * @return this - */ - public Builder byMonth(Collection months) { - byMonth.addAll(months); - return this; - } - - /** - * Adds one or more BYSETPOS rule parts. - * @param positions the values to add - * @return this - */ - public Builder bySetPos(Integer... positions) { - return bySetPos(Arrays.asList(positions)); - } - - /** - * Adds one or more BYSETPOS rule parts. - * @param positions the values to add - * @return this - */ - public Builder bySetPos(Collection positions) { - bySetPos.addAll(positions); - return this; - } - - /** - * Adds one or more BYDAY rule parts. - * @param days the days to add - * @return this - */ - public Builder byDay(DayOfWeek... days) { - return byDay(Arrays.asList(days)); - } - - /** - * Adds one or more BYDAY rule parts. - * @param days the days to add - * @return this - */ - public Builder byDay(Collection days) { - for (DayOfWeek day : days) { - byDay(null, day); - } - return this; - } - - /** - * Adds a BYDAY rule part. - * @param num the numeric component - * @param day the day to add - * @return this - */ - public Builder byDay(Integer num, DayOfWeek day) { - byDay.add(new ByDay(num, day)); - return this; - } - - /** - * Sets the day that the work week starts. - * @param day the day - * @return this - */ - public Builder workweekStarts(DayOfWeek day) { - workweekStarts = day; - return this; - } - - /** - * Adds a non-standard rule part. - * @param name the name - * @param value the value or null to remove the rule part - * @return this - */ - public Builder xrule(String name, String value) { - name = name.toUpperCase(); - - if (value == null) { - xrules.removeAll(name); - } else { - xrules.put(name, value); - } - - return this; - } - - /** - * Builds the final {@link Recurrence} object. - * @return the object - */ - public Recurrence build() { - return new Recurrence(this); - } - } -} diff --git a/app/src/main/java/biweekly/util/StringUtils.java b/app/src/main/java/biweekly/util/StringUtils.java deleted file mode 100644 index 194af331b0..0000000000 --- a/app/src/main/java/biweekly/util/StringUtils.java +++ /dev/null @@ -1,163 +0,0 @@ -package biweekly.util; - -import java.util.Collection; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Helper class for dealing with strings. - * @author Michael Angstadt - */ -public final class StringUtils { - /** - * The local computer's newline character sequence. - */ - public static final String NEWLINE = System.getProperty("line.separator"); - - /** - *

- * Returns a substring of the given string that comes after the given - * prefix. Prefix matching is case-insensitive. - *

- *

- * Example: - *

- * - *
-	 * String result = StringUtils.afterPrefixIgnoreCase("MAILTO:email@example.com", "mailto:");
-	 * assertEquals("email@example.com", result);
-	 * 
-	 * result = StringUtils.afterPrefixIgnoreCase("http://www.google.com", "mailto:");
-	 * assertNull(result);
-	 * 
- * - * @param string the string - * @param prefix the prefix - * @return the string or null if the prefix was not found - */ - public static String afterPrefixIgnoreCase(String string, String prefix) { - if (string.length() < prefix.length()) { - return null; - } - - for (int i = 0; i < prefix.length(); i++) { - char a = Character.toUpperCase(prefix.charAt(i)); - char b = Character.toUpperCase(string.charAt(i)); - if (a != b) { - return null; - } - } - - return string.substring(prefix.length()); - } - - /** - * Creates a string consisting of "count" occurrences of char "c". - * @param c the character to repeat - * @param count the number of times to repeat the character - * @param sb the character sequence to append the characters to - */ - public static void repeat(char c, int count, StringBuilder sb) { - for (int i = 0; i < count; i++) { - sb.append(c); - } - } - - /** - * Joins a collection of values into a delimited list. - * @param collection the collection of values - * @param delimiter the delimiter (e.g. ",") - * @param the value class - * @return the final string - */ - public static String join(Collection collection, String delimiter) { - StringBuilder sb = new StringBuilder(); - join(collection, delimiter, sb); - return sb.toString(); - } - - /** - * Joins a collection of values into a delimited list. - * @param collection the collection of values - * @param delimiter the delimiter (e.g. ",") - * @param sb the string builder to append onto - * @param the value class - */ - public static void join(Collection collection, String delimiter, StringBuilder sb) { - join(collection, delimiter, sb, new JoinCallback() { - public void handle(StringBuilder sb, T value) { - sb.append(value); - } - }); - } - - /** - * Joins a collection of values into a delimited list. - * @param collection the collection of values - * @param delimiter the delimiter (e.g. ",") - * @param join callback function to call on every element in the collection - * @param the value class - * @return the final string - */ - public static String join(Collection collection, String delimiter, JoinCallback join) { - StringBuilder sb = new StringBuilder(); - join(collection, delimiter, sb, join); - return sb.toString(); - } - - /** - * Joins a collection of values into a delimited list. - * @param collection the collection of values - * @param delimiter the delimiter (e.g. ",") - * @param sb the string builder to append onto - * @param join callback function to call on every element in the collection - * @param the value class - */ - public static void join(Collection collection, String delimiter, StringBuilder sb, JoinCallback join) { - boolean first = true; - for (T element : collection) { - if (!first) { - sb.append(delimiter); - } - - join.handle(sb, element); - first = false; - } - } - - /** - * Callback interface used with various {@code StringUtils.join()} methods. - * @author Michael Angstadt - * @param the value class - */ - public interface JoinCallback { - void handle(StringBuilder sb, T value); - } - - private StringUtils() { - //hide - } -} diff --git a/app/src/main/java/biweekly/util/UtcOffset.java b/app/src/main/java/biweekly/util/UtcOffset.java deleted file mode 100644 index 9098f0deb3..0000000000 --- a/app/src/main/java/biweekly/util/UtcOffset.java +++ /dev/null @@ -1,183 +0,0 @@ -package biweekly.util; - -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import biweekly.Messages; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a UTC offset. - * @author Michael Angstadt - */ -public final class UtcOffset { - private final long millis; - - /** - * @param positive true if the offset is positive, false if it is negative - * @param hour the hour component of the offset (the sign of this integer is - * ignored) - * @param minute the minute component of the offset (the sign of this - * integer is ignored) - */ - public UtcOffset(boolean positive, int hour, int minute) { - //Note: The (hour, minute) constructor was removed because it could not handle timezones such as "-0030" - int sign = positive ? 1 : -1; - hour = Math.abs(hour); - minute = Math.abs(minute); - - millis = sign * (hoursToMillis(hour) + minutesToMillis(minute)); - } - - /** - * @param millis the offset in milliseconds - */ - public UtcOffset(long millis) { - this.millis = millis; - } - - /** - * Parses a UTC offset from a string. - * @param text the text to parse (e.g. "-0500") - * @return the parsed UTC offset - * @throws IllegalArgumentException if the text cannot be parsed - */ - public static UtcOffset parse(String text) { - Pattern timeZoneRegex = Pattern.compile("^([-\\+])?(\\d{1,2})(:?(\\d{2}))?(:?(\\d{2}))?$"); - Matcher m = timeZoneRegex.matcher(text); - - if (!m.find()) { - throw Messages.INSTANCE.getIllegalArgumentException(21, text); - } - - String signStr = m.group(1); - boolean positive = !"-".equals(signStr); - - String hourStr = m.group(2); - int hourOffset = Integer.parseInt(hourStr); - - String minuteStr = m.group(4); - int minuteOffset = (minuteStr == null) ? 0 : Integer.parseInt(minuteStr); - - return new UtcOffset(positive, hourOffset, minuteOffset); - } - - /** - * Creates a UTC offset from a {@link TimeZone} object. - * @param timezone the timezone - * @return the UTC offset - */ - public static UtcOffset parse(TimeZone timezone) { - long offset = timezone.getOffset(System.currentTimeMillis()); - return new UtcOffset(offset); - } - - /** - * Gets the offset in milliseconds. - * @return the offset in milliseconds - */ - public long getMillis() { - return millis; - } - - /** - * Converts this offset to its ISO string representation using "basic" - * format. - * @return the ISO string representation (e.g. "-0500") - */ - @Override - public String toString() { - return toString(false); - } - - /** - * Converts this offset to its ISO string representation. - * @param extended true to use extended format (e.g. "-05:00"), false to use - * basic format (e.g. "-0500") - * @return the ISO string representation - */ - public String toString(boolean extended) { - StringBuilder sb = new StringBuilder(); - - boolean positive = (millis >= 0); - long hour = Math.abs(millisToHours(millis)); - long minute = Math.abs(millisToMinutes(millis)); - - sb.append(positive ? '+' : '-'); - - if (hour < 10) { - sb.append('0'); - } - sb.append(hour); - - if (extended) { - sb.append(':'); - } - - if (minute < 10) { - sb.append('0'); - } - sb.append(minute); - - return sb.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (int) (millis ^ (millis >>> 32)); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - UtcOffset other = (UtcOffset) obj; - if (millis != other.millis) return false; - return true; - } - - private static long hoursToMillis(long hours) { - return hours * 60 * 60 * 1000; - } - - private static long minutesToMillis(long minutes) { - return minutes * 60 * 1000; - } - - private static long millisToHours(long millis) { - return millis / 1000 / 60 / 60; - } - - private static long millisToMinutes(long millis) { - return (millis / 1000 / 60) % 60; - } -} diff --git a/app/src/main/java/biweekly/util/Utf8Reader.java b/app/src/main/java/biweekly/util/Utf8Reader.java deleted file mode 100644 index 3f1fd84a00..0000000000 --- a/app/src/main/java/biweekly/util/Utf8Reader.java +++ /dev/null @@ -1,57 +0,0 @@ -package biweekly.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.Charset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Reads characters that are encoded in UTF-8. - * @author Michael Angstadt - */ -public class Utf8Reader extends InputStreamReader { - /** - * Creates a new UTF-8 reader. - * @param in the input stream to read from - */ - public Utf8Reader(InputStream in) { - super(in, Charset.forName("UTF-8")); - } - - /** - * Creates a new UTF-8 reader. - * @param file the file to read from - * @throws FileNotFoundException if the file does not exist or cannot be - * opened - */ - public Utf8Reader(File file) throws FileNotFoundException { - this(new FileInputStream(file)); - } -} diff --git a/app/src/main/java/biweekly/util/Utf8Writer.java b/app/src/main/java/biweekly/util/Utf8Writer.java deleted file mode 100644 index a93cfdb100..0000000000 --- a/app/src/main/java/biweekly/util/Utf8Writer.java +++ /dev/null @@ -1,67 +0,0 @@ -package biweekly.util; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Writes characters that are UTF-8 encoded. - * @author Michael Angstadt - */ -public class Utf8Writer extends OutputStreamWriter { - /** - * Creates a new UTF-8 writer. - * @param out the output stream to write to - */ - public Utf8Writer(OutputStream out) { - super(out, Charset.forName("UTF-8")); - } - - /** - * Creates a new UTF-8 writer. - * @param file the file to write to - * @throws FileNotFoundException if the file cannot be written to - */ - public Utf8Writer(File file) throws FileNotFoundException { - this(file, false); - } - - /** - * Creates a new UTF-8 writer. - * @param file the file to write to - * @param append true to append to the file, false to overwrite it (this - * parameter has no effect if the file does not exist) - * @throws FileNotFoundException if the file cannot be written to - */ - public Utf8Writer(File file, boolean append) throws FileNotFoundException { - this(new FileOutputStream(file, append)); - } -} diff --git a/app/src/main/java/biweekly/util/VersionNumber.java b/app/src/main/java/biweekly/util/VersionNumber.java deleted file mode 100644 index e454f6cf19..0000000000 --- a/app/src/main/java/biweekly/util/VersionNumber.java +++ /dev/null @@ -1,103 +0,0 @@ -package biweekly.util; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Represents a software version number (e.g. "1.8.14"). - * @author Michael Angstadt - */ -public class VersionNumber implements Comparable { - private final List parts; - - /** - * Creates a new version number. - * @param version the version string (e.g. "1.8.14") - * @throws IllegalArgumentException if the version string is invalid - */ - public VersionNumber(String version) { - parts = new ArrayList(); - - int start = 0; - for (int i = 0; i < version.length(); i++) { - char c = version.charAt(i); - if (c == '.') { - addNumber(version, start, i); - start = i + 1; - } - } - addNumber(version, start, version.length()); - } - - private void addNumber(String version, int fromIndex, int toIndex) { - String numberStr = version.substring(fromIndex, toIndex); - Integer number = Integer.valueOf(numberStr); - parts.add(number); - } - - public int compareTo(VersionNumber that) { - Iterator it = parts.iterator(); - Iterator it2 = that.parts.iterator(); - while (it.hasNext() || it2.hasNext()) { - int number = it.hasNext() ? it.next() : 0; - int number2 = it2.hasNext() ? it2.next() : 0; - - if (number < number2) { - return -1; - } - if (number > number2) { - return 1; - } - } - return 0; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + parts.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - VersionNumber other = (VersionNumber) obj; - if (!parts.equals(other.parts)) return false; - return true; - } - - @Override - public String toString() { - return StringUtils.join(parts, "."); - } -} diff --git a/app/src/main/java/biweekly/util/XmlUtils.java b/app/src/main/java/biweekly/util/XmlUtils.java deleted file mode 100644 index 9f79fa41b2..0000000000 --- a/app/src/main/java/biweekly/util/XmlUtils.java +++ /dev/null @@ -1,332 +0,0 @@ -package biweekly.util; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.XMLConstants; -import javax.xml.namespace.QName; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The views and conclusions contained in the software and documentation are those - of the authors and should not be interpreted as representing official policies, - either expressed or implied, of the FreeBSD Project. - */ - -/** - * Generic XML utility methods. - * @author Michael Angstadt - */ -public final class XmlUtils { - /** - * Creates a new XML document. - * @return the XML document - */ - public static Document createDocument() { - try { - DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); - fact.setNamespaceAware(true); - DocumentBuilder db = fact.newDocumentBuilder(); - return db.newDocument(); - } catch (ParserConfigurationException e) { - //will probably never be thrown because we're not doing anything fancy with the configuration - throw new RuntimeException(e); - } - } - - /** - * Parses an XML string into a DOM. - * @param xml the XML string - * @return the parsed DOM - * @throws SAXException if the string is not valid XML - */ - public static Document toDocument(String xml) throws SAXException { - try { - return toDocument(new StringReader(xml)); - } catch (IOException e) { - //reading from string - throw new RuntimeException(e); - } - } - - /** - * Parses an XML document from a file. - * @param file the file - * @return the parsed DOM - * @throws SAXException if the XML is not valid - * @throws IOException if there is a problem reading from the file - */ - public static Document toDocument(File file) throws SAXException, IOException { - InputStream in = new BufferedInputStream(new FileInputStream(file)); - try { - return XmlUtils.toDocument(in); - } finally { - in.close(); - } - } - - /** - * Parses an XML document from an input stream. - * @param in the input stream - * @return the parsed DOM - * @throws SAXException if the XML is not valid - * @throws IOException if there is a problem reading from the input stream - */ - public static Document toDocument(InputStream in) throws SAXException, IOException { - return toDocument(new InputSource(in)); - } - - /** - *

- * Parses an XML document from a reader. - *

- *

- * Note that use of this method is discouraged. It ignores the character - * encoding that is defined within the XML document itself, and should only - * be used if the encoding is undefined or if the encoding needs to be - * ignored for whatever reason. The {@link #toDocument(InputStream)} method - * should be used instead, since it takes the XML document's character - * encoding into account when parsing. - *

- * @param reader the reader - * @return the parsed DOM - * @throws SAXException if the XML is not valid - * @throws IOException if there is a problem reading from the reader - * @see http://stackoverflow.com/q/3482494/13379 - */ - public static Document toDocument(Reader reader) throws SAXException, IOException { - return toDocument(new InputSource(reader)); - } - - private static Document toDocument(InputSource in) throws SAXException, IOException { - throw new RuntimeException("Removed"); - } - - /** - * Configures a {@link DocumentBuilderFactory} to protect it against XML - * External Entity attacks. - * - * @param factory the factory - * @see - * XXE Cheat Sheet - */ - public static void applyXXEProtection(DocumentBuilderFactory factory) { - Map features = new HashMap(); - features.put("http://apache.org/xml/features/disallow-doctype-decl", true); - features.put("http://xml.org/sax/features/external-general-entities", false); - features.put("http://xml.org/sax/features/external-parameter-entities", false); - features.put("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - - for (Map.Entry entry : features.entrySet()) { - String feature = entry.getKey(); - Boolean value = entry.getValue(); - try { - factory.setFeature(feature, value); - } catch (ParserConfigurationException e) { - //feature is not supported by the local XML engine, skip it - } - } - - factory.setXIncludeAware(false); - factory.setExpandEntityReferences(false); - } - - /** - * Configures a {@link TransformerFactory} to protect it against XML - * External Entity attacks. - * - * @param factory the factory - * @see - * XXE Cheat Sheet - */ - public static void applyXXEProtection(TransformerFactory factory) { - //@formatter:off - String[] attributes = { - //XMLConstants.ACCESS_EXTERNAL_DTD (Java 7 only) - "http://javax.xml.XMLConstants/property/accessExternalDTD", - - //XMLConstants.ACCESS_EXTERNAL_STYLESHEET (Java 7 only) - "http://javax.xml.XMLConstants/property/accessExternalStylesheet" - }; - //@formatter:on - - for (String attribute : attributes) { - try { - factory.setAttribute(attribute, ""); - } catch (IllegalArgumentException e) { - //attribute is not supported by the local XML engine, skip it - } - } - } - - /** - * Converts an XML node to a string. - * @param node the XML node - * @return the string - */ - public static String toString(Node node) { - return toString(node, new HashMap()); - } - - /** - * Converts an XML node to a string. - * @param node the XML node - * @param prettyPrint true to pretty print, false not to - * @return the string - */ - public static String toString(Node node, boolean prettyPrint) { - Map properties = new HashMap(); - if (prettyPrint) { - properties.put(OutputKeys.INDENT, "yes"); - properties.put("{http://xml.apache.org/xslt}indent-amount", "2"); - } - return toString(node, properties); - } - - /** - * Converts an XML node to a string. - * @param node the XML node - * @param outputProperties the output properties - * @return the string - */ - public static String toString(Node node, Map outputProperties) { - try { - StringWriter writer = new StringWriter(); - toWriter(node, writer, outputProperties); - return writer.toString(); - } catch (TransformerException e) { - //should never be thrown because we're writing to string - throw new RuntimeException(e); - } - } - - /** - * Writes an XML node to a writer. - * @param node the XML node - * @param writer the writer - * @throws TransformerException if there's a problem writing to the writer - */ - public static void toWriter(Node node, Writer writer) throws TransformerException { - toWriter(node, writer, new HashMap()); - } - - /** - * Writes an XML node to a writer. - * @param node the XML node - * @param writer the writer - * @param outputProperties the output properties - * @throws TransformerException if there's a problem writing to the writer - */ - public static void toWriter(Node node, Writer writer, Map outputProperties) throws TransformerException { - throw new RuntimeException("Removed"); - } - - /** - * Gets all the elements out of a {@link NodeList}. - * @param nodeList the node list - * @return the elements - */ - public static List toElementList(NodeList nodeList) { - List elements = new ArrayList(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - if (node instanceof Element) { - elements.add((Element) node); - } - } - return elements; - } - - /** - * Gets the first child element of an element. - * @param parent the parent element - * @return the first child element or null if there are no child elements - */ - public static Element getFirstChildElement(Element parent) { - return getFirstChildElement((Node) parent); - } - - /** - * Gets the first child element of a node. - * @param parent the node - * @return the first child element or null if there are no child elements - */ - private static Element getFirstChildElement(Node parent) { - NodeList nodeList = parent.getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - if (node instanceof Element) { - return (Element) node; - } - } - return null; - } - - /** - * Determines if a node has a particular qualified name. - * @param node the node - * @param qname the qualified name - * @return true if the node has the given qualified name, false if not - */ - public static boolean hasQName(Node node, QName qname) { - return qname.getNamespaceURI().equals(node.getNamespaceURI()) && qname.getLocalPart().equals(node.getLocalName()); - } - - private XmlUtils() { - //hide - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIterable.java b/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIterable.java deleted file mode 100644 index 7e8abb5f34..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIterable.java +++ /dev/null @@ -1,51 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.compat.javautil; - -import java.util.Date; - -/** - * Iterates over a series of {@link Date} objects in ascending order. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public interface DateIterable extends Iterable { - DateIterator iterator(); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIterator.java b/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIterator.java deleted file mode 100644 index 0af62ca201..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIterator.java +++ /dev/null @@ -1,56 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.compat.javautil; - -import java.util.Date; -import java.util.Iterator; - -/** - * Iterates over a series of {@link Date} objects in ascending order. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public interface DateIterator extends Iterator { - /** - * Skips all dates in the series that come before the given date. - * @param newStartUtc the date to advance to (in UTC) - */ - void advanceTo(Date newStartUtc); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIteratorFactory.java b/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIteratorFactory.java deleted file mode 100644 index 095796413d..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/compat/javautil/DateIteratorFactory.java +++ /dev/null @@ -1,169 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.compat.javautil; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -import biweekly.util.com.google.ical.iter.RecurrenceIterable; -import biweekly.util.com.google.ical.iter.RecurrenceIterator; -import biweekly.util.com.google.ical.iter.RecurrenceIteratorFactory; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateTimeValueImpl; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - * A factory for converting RRULEs and RDATEs into - * Iterator<Date> and Iterable<Date>. - * @see RecurrenceIteratorFactory - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public class DateIteratorFactory { - /** - * Creates a date iterator from a recurrence iterator. - * @param rit the recurrence iterator - * @return the date iterator - */ - public static DateIterator createDateIterator(RecurrenceIterator rit) { - return new RecurrenceIteratorWrapper(rit); - } - - /** - * Creates a date iterable from a recurrence iterable. - * @param rit the recurrence iterable - * @return the date iterable - */ - public static DateIterable createDateIterable(RecurrenceIterable rit) { - return new RecurrenceIterableWrapper(rit); - } - - private static final class RecurrenceIterableWrapper implements DateIterable { - private final RecurrenceIterable it; - - public RecurrenceIterableWrapper(RecurrenceIterable it) { - this.it = it; - } - - public DateIterator iterator() { - return new RecurrenceIteratorWrapper(it.iterator()); - } - } - - private static final class RecurrenceIteratorWrapper implements DateIterator { - private final RecurrenceIterator it; - private final Calendar utcCalendar = new GregorianCalendar(TimeUtils.utcTimezone()); - - public RecurrenceIteratorWrapper(RecurrenceIterator it) { - this.it = it; - } - - public boolean hasNext() { - return it.hasNext(); - } - - public Date next() { - return toDate(it.next()); - } - - public void advanceTo(Date d) { - it.advanceTo(toDateValue(d)); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - /** - * Converts a {@link DateValue} object into a Java {@link Date} object. - * @param dateValue the date value object (assumed to be in UTC time) - * @return the Java date object - */ - private Date toDate(DateValue dateValue) { - TimeValue time = TimeUtils.timeOf(dateValue); - utcCalendar.clear(); - //@formatter:off - utcCalendar.set( - dateValue.year(), - dateValue.month() - 1, //java.util's dates are zero-indexed - dateValue.day(), - time.hour(), - time.minute(), - time.second() - ); - //@formatter:on - return utcCalendar.getTime(); - } - - /** - * Converts a Java {@link Date} object into a {@link DateValue} object. - * The {@link DateValue} object will be in UTC time. - * @param date the Java date object - * @return the date value object (in UTC time) - */ - private DateValue toDateValue(Date date) { - utcCalendar.setTime(date); - - int year = utcCalendar.get(Calendar.YEAR); - int month = utcCalendar.get(Calendar.MONTH) + 1; //java.util's dates are zero-indexed - int day = utcCalendar.get(Calendar.DAY_OF_MONTH); - int hour = utcCalendar.get(Calendar.HOUR_OF_DAY); - int minute = utcCalendar.get(Calendar.MINUTE); - int second = utcCalendar.get(Calendar.SECOND); - - /* - * We need to treat midnight as a date value so that passing in - * dateValueToDate() will not advance past any - * occurrences of some-date-value in the iterator. - */ - if ((hour | minute | second) == 0) { - return new DateValueImpl(year, month, day); - } - return new DateTimeValueImpl(year, month, day, hour, minute, second); - } - } - - private DateIteratorFactory() { - // uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/CompoundIteratorImpl.java b/app/src/main/java/biweekly/util/com/google/ical/iter/CompoundIteratorImpl.java deleted file mode 100644 index 47de263c83..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/CompoundIteratorImpl.java +++ /dev/null @@ -1,289 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.Collection; -import java.util.Comparator; -import java.util.NoSuchElementException; -import java.util.PriorityQueue; - -import biweekly.util.com.google.ical.values.DateValue; - -/** - * A recurrence iterator that combines multiple recurrence iterators into one. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class CompoundIteratorImpl implements RecurrenceIterator { - /** - * A queue that keeps the earliest dates at the head. - */ - private final PriorityQueue queue; - - private HeapElement pending; - - /** - * The number of inclusions on the queue. We keep track of this so that we - * don't have to drain the exclusions to conclude that the series is - * exhausted. - */ - private int nInclusionsRemaining; - - /** - * Creates an iterator that will generate only dates that are generated by - * inclusions and will not generate any dates that are generated by - * exclusions. - * @param inclusions iterators whose elements should be included unless - * explicitly excluded - * @param exclusions iterators whose elements should not be included - */ - CompoundIteratorImpl(Collection inclusions, Collection exclusions) { - queue = new PriorityQueue(inclusions.size() + exclusions.size(), HeapElement.CMP); - for (RecurrenceIterator it : inclusions) { - HeapElement el = new HeapElement(true, it); - if (el.shift()) { - queue.add(el); - ++nInclusionsRemaining; - } - } - for (RecurrenceIterator it : exclusions) { - HeapElement el = new HeapElement(false, it); - if (el.shift()) { - queue.add(el); - } - } - } - - public boolean hasNext() { - requirePending(); - return pending != null; - } - - public DateValue next() { - requirePending(); - if (pending == null) { - throw new NoSuchElementException(); - } - DateValue head = pending.head(); - reattach(pending); - pending = null; - return head; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public void advanceTo(DateValue newStart) { - long newStartCmp = DateValueComparison.comparable(newStart); - if (pending != null) { - if (pending.comparable() >= newStartCmp) { - return; - } - pending.advanceTo(newStart); - reattach(pending); - pending = null; - } - - /* - * Pull each element off the stack in turn, and advance it. Once we - * reach one we don't need to advance, we're done. - */ - while (nInclusionsRemaining != 0 && !queue.isEmpty() && queue.peek().comparable() < newStartCmp) { - HeapElement el = queue.poll(); - el.advanceTo(newStart); - reattach(el); - } - } - - /** - * If the given element's iterator has more data, then push back onto the - * heap. - * @param el the element to push back into the heap. - */ - private void reattach(HeapElement el) { - if (el.shift()) { - queue.add(el); - } else if (el.inclusion) { - /* - * If we have no live inclusions, then the rest are exclusions which - * we can safely discard. - */ - if (--nInclusionsRemaining == 0) { - queue.clear(); - } - } - } - - /** - * Makes sure that pending contains the next inclusive {@link HeapElement} - * that doesn't match any exclusion, and remove any duplicates of it. - */ - private void requirePending() { - if (pending != null) { - return; - } - - long exclusionComparable = Long.MIN_VALUE; - while (nInclusionsRemaining != 0 && !queue.isEmpty()) { - //find a candidate that is not excluded - HeapElement inclusion = null; - do { - HeapElement candidate = queue.poll(); - if (candidate.inclusion) { - if (exclusionComparable != candidate.comparable()) { - inclusion = candidate; - break; - } - } else { - exclusionComparable = candidate.comparable(); - } - reattach(candidate); - if (nInclusionsRemaining == 0) { - return; - } - } while (!queue.isEmpty()); - if (inclusion == null) { - return; - } - long inclusionComparable = inclusion.comparable(); - - /* - * Check for any following exclusions and for duplicates. We could - * change the sort order so that exclusions always preceded - * inclusions, but that would be less efficient and would make the - * ordering different than the comparable value. - */ - boolean excluded = exclusionComparable == inclusionComparable; - while (!queue.isEmpty() && queue.peek().comparable() == inclusionComparable) { - HeapElement match = queue.poll(); - excluded |= !match.inclusion; - reattach(match); - if (nInclusionsRemaining == 0) { - return; - } - } - if (!excluded) { - pending = inclusion; - return; - } - reattach(inclusion); - } - } -} - -final class HeapElement { - /** - * Should iterators items be included in the series or should they nullify - * any matched items included by other series? - */ - final boolean inclusion; - - private final RecurrenceIterator it; - - /** - * The {@link DateValueComparison#comparable} for {@link #head}. - */ - private long comparable; - - /** - * The last value removed from the iterator (in UTC). - */ - private DateValue head; - - HeapElement(boolean inclusion, RecurrenceIterator it) { - this.inclusion = inclusion; - this.it = it; - } - - /** - * Gets the last value removed from the iterator. - */ - DateValue head() { - return head; - } - - /** - * Gets the comparable value of the head. A given HeapElement may be - * compared to many others as it bubbles towards the heap's root, so we - * cache this for each HeapElement. - * @return the comparable value of the head - */ - long comparable() { - return comparable; - } - - /** - * Discards the current element and move to the next. - * @return true if there is a next element, false if not - */ - boolean shift() { - if (!it.hasNext()) { - return false; - } - head = it.next(); - comparable = DateValueComparison.comparable(head); - return true; - } - - /** - * Advances the underlying iterator to the given date value. - * @param newStartUtc the date to advance to (in UTC) - * @see RecurrenceIterator#advanceTo - */ - void advanceTo(DateValue newStartUtc) { - it.advanceTo(newStartUtc); - } - - @Override - public String toString() { - return "[" + head.toString() + ", " + (inclusion ? "inclusion" : "exclusion") + "]"; - } - - /** - * Compares two heap elements by comparing their heads. - */ - static final Comparator CMP = new Comparator() { - public int compare(HeapElement a, HeapElement b) { - long ac = a.comparable(), bc = b.comparable(); - return ac < bc ? -1 : ac == bc ? 0 : 1; - } - }; -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/Conditions.java b/app/src/main/java/biweekly/util/com/google/ical/iter/Conditions.java deleted file mode 100644 index dafb764dbb..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/Conditions.java +++ /dev/null @@ -1,97 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import biweekly.util.com.google.ical.util.Predicate; -import biweekly.util.com.google.ical.values.DateValue; - -/** - * Factory for predicates used to test whether a recurrence is over. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class Conditions { - /** - * Constructs a condition that fails after counting a certain number of - * dates. - * @param count the number of dates to count before the condition fails - * @return the condition - */ - static Predicate countCondition(final int count) { - return new Predicate() { - private static final long serialVersionUID = -3770774958208833665L; - int count_ = count; - - public boolean apply(DateValue value) { - return --count_ >= 0; - } - - @Override - public String toString() { - return "CountCondition:" + count_; - } - }; - } - - /** - * Constructs a condition that passes all dates that are less than or equal - * to the given date. - * @param until the date - * @return the condition - */ - static Predicate untilCondition(final DateValue until) { - return new Predicate() { - private static final long serialVersionUID = -130394842437801858L; - - public boolean apply(DateValue date) { - return date.compareTo(until) <= 0; - } - - @Override - public String toString() { - return "UntilCondition:" + until; - } - }; - } - - private Conditions() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/DateValueComparison.java b/app/src/main/java/biweekly/util/com/google/ical/iter/DateValueComparison.java deleted file mode 100644 index c61da30aae..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/DateValueComparison.java +++ /dev/null @@ -1,128 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - *

- * Contains {@link DateValue} comparison methods. - *

- *

- * When we're pulling dates off the priority order, we need them to come off in - * a consistent order, so we need a total ordering on date values. - *

- *

- * This means that a DateValue with no time must not be equal to a DateTimeValue - * at midnight. Since it obviously doesn't make sense for a DateValue to be - * after a DateTimeValue the same day at 23:59:59, we put the DateValue before 0 - * hours of the same day. - *

- *

- * If we didn't have a total ordering, then it would be harder to correctly - * handle the example below because we'd have two EXDATEs that are equal - * according to the comparison, but only the first should match. - *

- * - *
- *   RDATE:20060607
- *   EXDATE:20060607
- *   EXDATE:20060607T000000Z
- * 
- *

- * In the next example, the problem is worse because we may pull a candidate - * RDATE off the priority queue and then not know whether to consume the EXDATE - * or not. - *

- * - *
- *   RDATE:20060607
- *   RDATE:20060607T000000Z
- *   EXDATE:20060607
- * 
- *

- * Absent a total ordering, the following case could only be solved with - * lookahead and ugly logic. - *

- * - *
- *   RDATE:20060607
- *   RDATE:20060607T000000Z
- *   EXDATE:20060607
- *   EXDATE:20060607T000000Z
- * 
- *

- * The conversion to GMT is also an implementation detail, so it's not clear - * which timezone we should consider midnight in, and a total ordering allows us - * to avoid timezone conversions during iteration. - *

- * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class DateValueComparison { - /** - * Reduces a date to a value that can be easily compared to others, consistent - * with {@link DateValueImpl#compareTo}. - * @param date the date - * @return the value to use for comparisons - */ - static long comparable(DateValue date) { - long comp = (((((long) date.year()) << 4) + date.month()) << 5) + date.day(); - if (date instanceof TimeValue) { - TimeValue time = (TimeValue) date; - - /* - * We add 1 to comparable for timed values to make sure that timed events - * are distinct from all-day events, in keeping with DateValue.compareTo. - * - * It would be odd if an all day exclusion matched a midnight event on the - * same day, but not one at another time of day. - */ - return (((((comp << 5) + time.hour()) << 6) + time.minute()) << 6) + time.second() + 1; - } - return comp << 17; - } - - private DateValueComparison() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/Filters.java b/app/src/main/java/biweekly/util/com/google/ical/iter/Filters.java deleted file mode 100644 index 8f7869418e..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/Filters.java +++ /dev/null @@ -1,290 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import biweekly.util.ByDay; -import biweekly.util.DayOfWeek; -import biweekly.util.com.google.ical.util.DTBuilder; -import biweekly.util.com.google.ical.util.Predicate; -import biweekly.util.com.google.ical.util.Predicates; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - *

- * Factory for creating predicates used to filter out dates produced by a - * generator that do not pass some secondary criterion. For example, the - * recurrence rule below should generate every Friday the 13th: - *

- * - *
- * FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13
- * 
- *

- * It is implemented as a generator that generates the 13th of every month (a - * {@code byMonthDay} generator), and then the results of that are filtered by a - * {@code byDayFilter} that tests whether the date falls on Friday. - *

- *

- * A filter returns true to indicate the item is included in the recurrence. - *

- * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -class Filters { - /** - * Constructs a day filter based on a BYDAY rule. - * @param days the BYDAY values - * @param weeksInYear true if the week numbers are meant to be weeks in the - * current year, false if they are meant to be weeks in the current month - * @param weekStart the day of the week that the week starts on - * @return the filter - */ - static Predicate byDayFilter(final ByDay[] days, final boolean weeksInYear, final DayOfWeek weekStart) { - return new Predicate() { - private static final long serialVersionUID = 1636822853835207274L; - - public boolean apply(DateValue date) { - DayOfWeek dow = TimeUtils.dayOfWeek(date); - int nDays; - DayOfWeek firstDayOfWeek; - - //where does date appear in the year or month? - //in [0, lengthOfMonthOrYear - 1] - int instance; - if (weeksInYear) { - nDays = TimeUtils.yearLength(date.year()); - firstDayOfWeek = TimeUtils.firstDayOfWeekInMonth(date.year(), 1); - instance = TimeUtils.dayOfYear(date.year(), date.month(), date.day()); - } else { - nDays = TimeUtils.monthLength(date.year(), date.month()); - firstDayOfWeek = TimeUtils.firstDayOfWeekInMonth(date.year(), date.month()); - instance = date.day() - 1; - } - - //which week of the year or month does this date fall on? - //one-indexed - int dateWeekNo = instance / 7; - if (weekStart.getCalendarConstant() <= dow.getCalendarConstant()) { - dateWeekNo += 1; - } - - /* - * TODO(msamuel): According to section 4.3.10: - * - * Week number one of the calendar year is the first week which - * contains at least four (4) days in that calendar year. This - * rule part is only valid for YEARLY rules. - * - * That's mentioned under the BYWEEKNO rule, and there's no - * mention of it in the earlier discussion of the BYDAY rule. - * Does it apply to yearly week numbers calculated for BYDAY - * rules in a FREQ=YEARLY rule? - */ - - for (int i = days.length - 1; i >= 0; i--) { - ByDay day = days[i]; - - if (day.getDay() == dow) { - Integer weekNo = day.getNum(); - if (weekNo == null || weekNo == 0) { - return true; - } - - if (weekNo < 0) { - weekNo = Util.invertWeekdayNum(day, firstDayOfWeek, nDays); - } - - if (dateWeekNo == weekNo) { - return true; - } - } - } - return false; - } - }; - } - - /** - * Constructs a day filter based on a BYDAY rule. - * @param monthDays days of the month (values must be in range [-31,31]) - * @return the filter - */ - static Predicate byMonthDayFilter(final int[] monthDays) { - return new Predicate() { - private static final long serialVersionUID = -1618039447294490037L; - - public boolean apply(DateValue date) { - int nDays = TimeUtils.monthLength(date.year(), date.month()); - for (int i = monthDays.length - 1; i >= 0; i--) { - int day = monthDays[i]; - if (day < 0) { - day += nDays + 1; - } - if (day == date.day()) { - return true; - } - } - return false; - } - }; - } - - /** - * Constructs a filter that accepts only every X week starting from the week - * containing the given date. - * @param interval the interval (for example, 3 for "every third week"; must - * be > 0) - * @param weekStart the day of the week that the week starts on - * @param dtStart the filter will start at the week that contains this date - * @return the filter - */ - static Predicate weekIntervalFilter(final int interval, final DayOfWeek weekStart, final DateValue dtStart) { - return new Predicate() { - private static final long serialVersionUID = 7059994888520369846L; - //the latest day with day of week weekStart on or before dtStart - DateValue wkStart; - { - DTBuilder wkStartB = new DTBuilder(dtStart); - wkStartB.day -= (7 + TimeUtils.dayOfWeek(dtStart).getCalendarConstant() - weekStart.getCalendarConstant()) % 7; - wkStart = wkStartB.toDate(); - } - - public boolean apply(DateValue date) { - int daysBetween = TimeUtils.daysBetween(date, wkStart); - if (daysBetween < 0) { - //date must be before dtStart. Shouldn't occur in practice. - daysBetween += (interval * 7 * (1 + daysBetween / (-7 * interval))); - } - int off = (daysBetween / 7) % interval; - return off == 0; - } - }; - } - - private static final int LOW_24_BITS = ~(-1 << 24); - private static final long LOW_60_BITS = ~(-1L << 60); - - /** - * Constructs an hour filter based on a BYHOUR rule. - * @param hours hours of the day (values must be in range [0,23]) - * @return the filter - */ - static Predicate byHourFilter(int[] hours) { - int hoursByBit = 0; - for (int hour : hours) { - hoursByBit |= 1 << hour; - } - if ((hoursByBit & LOW_24_BITS) == LOW_24_BITS) { - return Predicates.alwaysTrue(); - } - final int bitField = hoursByBit; - return new Predicate() { - private static final long serialVersionUID = -6284974028385246889L; - - public boolean apply(DateValue date) { - if (!(date instanceof TimeValue)) { - return false; - } - TimeValue tv = (TimeValue) date; - return (bitField & (1 << tv.hour())) != 0; - } - }; - } - - /** - * Constructs a minute filter based on a BYMINUTE rule. - * @param minutes minutes of the hour (values must be in range [0,59]) - * @return the filter - */ - static Predicate byMinuteFilter(int[] minutes) { - long minutesByBit = 0; - for (int minute : minutes) { - minutesByBit |= 1L << minute; - } - if ((minutesByBit & LOW_60_BITS) == LOW_60_BITS) { - return Predicates.alwaysTrue(); - } - final long bitField = minutesByBit; - return new Predicate() { - private static final long serialVersionUID = 5028303473420393470L; - - public boolean apply(DateValue date) { - if (!(date instanceof TimeValue)) { - return false; - } - TimeValue tv = (TimeValue) date; - return (bitField & (1L << tv.minute())) != 0; - } - }; - } - - /** - * Constructs a second filter based on a BYMINUTE rule. - * @param seconds seconds of the minute (values must be in rage [0,59]) - * @return the filter - */ - static Predicate bySecondFilter(int[] seconds) { - long secondsByBit = 0; - for (int second : seconds) { - secondsByBit |= 1L << second; - } - if ((secondsByBit & LOW_60_BITS) == LOW_60_BITS) { - return Predicates.alwaysTrue(); - } - final long bitField = secondsByBit; - return new Predicate() { - private static final long serialVersionUID = 4109739845053177924L; - - public boolean apply(DateValue date) { - if (!(date instanceof TimeValue)) { - return false; - } - TimeValue tv = (TimeValue) date; - return (bitField & (1L << tv.second())) != 0; - } - }; - } - - private Filters() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/Generator.java b/app/src/main/java/biweekly/util/com/google/ical/iter/Generator.java deleted file mode 100644 index 62d01d61c4..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/Generator.java +++ /dev/null @@ -1,116 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import biweekly.util.com.google.ical.util.DTBuilder; - -/** - *

- * A stateful operation that can be successively invoked to generate the next - * part of a date in a series. - *

- *

- * Each field generator takes as input the larger fields, modifies its field, - * and leaves the other fields unchanged. For example, a year generator will - * update {@link DTBuilder#year}, leaving the smaller fields unchanged. And a - * month generator will update {@link DTBuilder#month}, taking its cue from - * {@link DTBuilder#year}, also leaving the smaller fields unchanged. - *

- * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -abstract class Generator { - /** - *

- * Generates the next part of a date in a series. - *

- *

- * If a generator is exhausted, generating a new value of a larger field may - * allow it to continue. For example, a month generator that runs out of - * months at 12, may start over at 1 if called with a {@link DTBuilder} with - * a different year. - *

- * @param bldr used for both input and output, modified in place - * @return true iff there are more instances of the generator's field to - * generate - * @throws IteratorShortCircuitingException when an iterator reaches a - * threshold past which it cannot generate any more dates. This indicates - * that the entire iteration process should end. - */ - abstract boolean generate(DTBuilder bldr) throws IteratorShortCircuitingException; - - /** - *

- * Thrown when an iteration process should be ended completely due to an - * artificial system limit. This allows us to make a distinction between - * normal exhaustion of iteration, and an artificial limit that may fall in - * a set, and so affect subsequent evaluation of BYSETPOS rules. - *

- *

- * Since this class is meant to be thrown as a flow control construct to - * indicate an artificial limit has been reached (as opposed to an - * exceptional condition), and since its clients have no need of the - * stacktrace, we use a singleton to avoid forcing the JVM to unoptimize and - * decompile the {@link RecurrenceIterator}'s inner loop. - *

- */ - @SuppressWarnings("serial") - static class IteratorShortCircuitingException extends Exception { - private IteratorShortCircuitingException() { - super(); - setStackTrace(new StackTraceElement[0]); - } - - private static final IteratorShortCircuitingException INSTANCE = new IteratorShortCircuitingException(); - - static IteratorShortCircuitingException instance() { - return INSTANCE; - } - } - - static { - /* - * Suffer the stack trace generation on class load of Generator, which - * will happen before any of the recurrence stuff could possibly have - * been JIT compiled. - */ - IteratorShortCircuitingException.instance(); - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/Generators.java b/app/src/main/java/biweekly/util/com/google/ical/iter/Generators.java deleted file mode 100644 index 5fe4ef1725..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/Generators.java +++ /dev/null @@ -1,1061 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.Arrays; - -import biweekly.util.ByDay; -import biweekly.util.DayOfWeek; -import biweekly.util.com.google.ical.util.DTBuilder; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - * Factory for field generators. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class Generators { - /** - *

- * The maximum number of years generated between instances. See - * {@link ThrottledGenerator} for a description of the problem this solves. - *

- *

- * Note: This counts the maximum number of years generated, so for - * FREQ=YEARLY;INTERVAL=4 the generator would try 100 - * individual years over a span of 400 years before giving up and concluding - * that the rule generates no usable dates. - *

- */ - private static final int MAX_YEARS_BETWEEN_INSTANCES = 100; - - /** - * Constructs a generator that generates years successively counting from - * the first year passed in. - * @param interval number of years to advance each step - * @param dtStart the start date - * @return the year in dtStart the first time called and interval + last - * return value on subsequent calls - */ - static ThrottledGenerator serialYearGenerator(final int interval, final DateValue dtStart) { - return new ThrottledGenerator() { - //the last year seen - int year = dtStart.year() - interval; - - int throttle = MAX_YEARS_BETWEEN_INSTANCES; - - @Override - boolean generate(DTBuilder builder) throws IteratorShortCircuitingException { - /* - * Make sure things halt even if the RRULE is bad. For example, - * the following rules should halt: - * - * FREQ=YEARLY;BYMONTHDAY=30;BYMONTH=2 - */ - if (--throttle < 0) { - throw IteratorShortCircuitingException.instance(); - } - year += interval; - builder.year = year; - return true; - } - - @Override - void workDone() { - this.throttle = MAX_YEARS_BETWEEN_INSTANCES; - } - - @Override - public String toString() { - return "serialYearGenerator:" + interval; - } - }; - } - - /** - * Constructs a generator that generates months in the given builder's year - * successively counting from the first month passed in. - * @param interval number of months to advance each step - * @param dtStart the start date - * @return the month in dtStart the first time called and interval + last - * return value on subsequent calls - */ - static Generator serialMonthGenerator(final int interval, final DateValue dtStart) { - return new Generator() { - int year = dtStart.year(); - int month = dtStart.month() - interval; - { - while (month < 1) { - month += 12; - --year; - } - } - - @Override - boolean generate(DTBuilder builder) { - int nmonth; - if (year != builder.year) { - int monthsBetween = (builder.year - year) * 12 - (month - 1); - nmonth = ((interval - (monthsBetween % interval)) % interval) + 1; - if (nmonth > 12) { - /* - * Don't update year so that the difference calculation - * above is correct when this function is reentered with - * a different year - */ - return false; - } - year = builder.year; - } else { - nmonth = month + interval; - if (nmonth > 12) { - return false; - } - } - month = builder.month = nmonth; - return true; - } - - @Override - public String toString() { - return "serialMonthGenerator:" + interval; - } - }; - } - - /** - * Constructs a generator that generates every day in the current month that - * is an integer multiple of interval days from dtStart. - * @param interval number of days to advance each step - * @param dtStart the start date - * @return the day in dtStart the first time called and interval + last - * return value on subsequent calls - */ - static Generator serialDayGenerator(final int interval, final DateValue dtStart) { - return new Generator() { - int year, month, date; - /** ndays in the last month encountered */ - int nDays; - - { - //step back one interval - DateValue dtStartMinus1; - { - DTBuilder builder = new DTBuilder(dtStart); - builder.day -= interval; - dtStartMinus1 = builder.toDate(); - } - year = dtStartMinus1.year(); - month = dtStartMinus1.month(); - date = dtStartMinus1.day(); - nDays = TimeUtils.monthLength(year, month); - } - - @Override - boolean generate(DTBuilder builder) { - int ndate; - if (year == builder.year && month == builder.month) { - ndate = date + interval; - if (ndate > nDays) { - return false; - } - } else { - nDays = TimeUtils.monthLength(builder.year, builder.month); - if (interval != 1) { - /* - * Calculate the number of days between the first of the - * new month and the old date and extend it to make it - * an integer multiple of interval. - */ - int daysBetween = TimeUtils.daysBetween(new DateValueImpl(builder.year, builder.month, 1), new DateValueImpl(year, month, date)); - ndate = ((interval - (daysBetween % interval)) % interval) + 1; - if (ndate > nDays) { - /* - * Need to return early without updating year or - * month so that the next time we enter with a - * different month, the daysBetween call above - * compares against the proper last date. - */ - return false; - } - } else { - ndate = 1; - } - year = builder.year; - month = builder.month; - } - date = builder.day = ndate; - return true; - } - - @Override - public String toString() { - return "serialDayGenerator:" + interval; - } - }; - } - - /** - * Constructs a generator that generates hours in the given date's day - * successively counting from the first hour passed in. - * @param interval number of hours to advance each step - * @param dtStart the start date - * @return the hour in dtStart the first time called and interval + last - * return value on subsequent calls - */ - static Generator serialHourGenerator(final int interval, final DateValue dtStart) { - final TimeValue dtStartTime = TimeUtils.timeOf(dtStart); - return new Generator() { - int hour = dtStartTime.hour() - interval; - int day = dtStart.day(); - int month = dtStart.month(); - int year = dtStart.year(); - - @Override - boolean generate(DTBuilder builder) { - int nhour; - if (day != builder.day || month != builder.month || year != builder.year) { - int hoursBetween = daysBetween(builder, year, month, day) * 24 - hour; - nhour = ((interval - (hoursBetween % interval)) % interval); - if (nhour > 23) { - /* - * Don't update day so that the difference calculation - * above is correct when this function is reentered with - * a different day. - */ - return false; - } - day = builder.day; - month = builder.month; - year = builder.year; - } else { - nhour = hour + interval; - if (nhour > 23) { - return false; - } - } - hour = builder.hour = nhour; - return true; - } - - @Override - public String toString() { - return "serialHourGenerator:" + interval; - } - }; - } - - /** - * Constructs a generator that generates minutes in the given date's hour - * successively counting from the first minute passed in. - * @param interval number of minutes to advance each step - * @param dtStart the date - * @return the minute in dtStart the first time called and interval + last - * return value on subsequent calls - */ - static Generator serialMinuteGenerator(final int interval, final DateValue dtStart) { - final TimeValue dtStartTime = TimeUtils.timeOf(dtStart); - return new Generator() { - int minute = dtStartTime.minute() - interval; - int hour = dtStartTime.hour(); - int day = dtStart.day(); - int month = dtStart.month(); - int year = dtStart.year(); - - @Override - boolean generate(DTBuilder builder) { - int nminute; - if (hour != builder.hour || day != builder.day || month != builder.month || year != builder.year) { - int minutesBetween = (daysBetween(builder, year, month, day) * 24 + builder.hour - hour) * 60 - minute; - nminute = ((interval - (minutesBetween % interval)) % interval); - if (nminute > 59) { - /* - * Don't update day so that the difference calculation - * above is correct when this function is reentered with - * a different day. - */ - return false; - } - hour = builder.hour; - day = builder.day; - month = builder.month; - year = builder.year; - } else { - nminute = minute + interval; - if (nminute > 59) { - return false; - } - } - minute = builder.minute = nminute; - return true; - } - - @Override - public String toString() { - return "serialMinuteGenerator:" + interval; - } - }; - } - - /** - * Constructs a generator that generates seconds in the given date's minute - * successively counting from the first second passed in. - * @param interval number of seconds to advance each step - * @param dtStart the date - * @return the second in dtStart the first time called and interval + last - * return value on subsequent calls - */ - static Generator serialSecondGenerator(final int interval, final DateValue dtStart) { - final TimeValue dtStartTime = TimeUtils.timeOf(dtStart); - return new Generator() { - int second = dtStartTime.second() - interval; - int minute = dtStartTime.minute(); - int hour = dtStartTime.hour(); - int day = dtStart.day(); - int month = dtStart.month(); - int year = dtStart.year(); - - @Override - boolean generate(DTBuilder builder) { - int nsecond; - if (minute != builder.minute || hour != builder.hour || day != builder.day || month != builder.month || year != builder.year) { - int secondsBetween = ((daysBetween(builder, year, month, day) * 24 + builder.hour - hour) * 60 + builder.minute - minute) * 60 - second; - nsecond = ((interval - (secondsBetween % interval)) % interval); - if (nsecond > 59) { - /* - * Don't update day so that the difference calculation - * above is correct when this function is reentered with - * a different day. - */ - return false; - } - minute = builder.minute; - hour = builder.hour; - day = builder.day; - month = builder.month; - year = builder.year; - } else { - nsecond = second + interval; - if (nsecond > 59) { - return false; - } - } - second = builder.second = nsecond; - return true; - } - - @Override - public String toString() { - return "serialSecondGenerator:" + interval; - } - }; - } - - /** - * Constructs a generator that yields the specified years in increasing - * order. - * @param years the years - * @param dtStart the start date - * @return the generator - */ - static Generator byYearGenerator(int[] years, final DateValue dtStart) { - final int[] uyears = Util.uniquify(years); - - // index into years - return new Generator() { - int i; - { - while (i < uyears.length && dtStart.year() > uyears[i]) { - ++i; - } - } - - @Override - boolean generate(DTBuilder builder) { - if (i >= uyears.length) { - return false; - } - builder.year = uyears[i++]; - return true; - } - - @Override - public String toString() { - return "byYearGenerator"; - } - }; - } - - /** - * Constructs a generator that yields the specified months in increasing - * order for each year. - * @param months the month values (each value must be in range [1,12]) - * @param dtStart the start date - * @return the generator - */ - static Generator byMonthGenerator(int[] months, final DateValue dtStart) { - final int[] umonths = Util.uniquify(months); - - return new Generator() { - int i; - int year = dtStart.year(); - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year) { - i = 0; - year = builder.year; - } - if (i >= umonths.length) { - return false; - } - builder.month = umonths[i++]; - return true; - } - - @Override - public String toString() { - return "byMonthGenerator:" + Arrays.toString(umonths); - } - }; - } - - /** - * Constructs a generator that yields the specified hours in increasing - * order for each day. - * @param hours the hour values (each value must be in range [0,23]) - * @param dtStart the start date - * @return the generator - */ - static Generator byHourGenerator(int[] hours, final DateValue dtStart) { - final TimeValue dtStartTime = TimeUtils.timeOf(dtStart); - final int[] uhours = (hours.length == 0) ? new int[] { dtStartTime.hour() } : Util.uniquify(hours); - - if (uhours.length == 1) { - final int hour = uhours[0]; - - return new SingleValueGenerator() { - int year; - int month; - int day; - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month || day != builder.day) { - year = builder.year; - month = builder.month; - day = builder.day; - builder.hour = hour; - return true; - } - return false; - } - - @Override - int getValue() { - return hour; - } - - @Override - public String toString() { - return "byHourGenerator:" + hour; - } - }; - } - - return new Generator() { - int i; - int year = dtStart.year(); - int month = dtStart.month(); - int day = dtStart.day(); - { - int hour = dtStartTime.hour(); - while (i < uhours.length && uhours[i] < hour) { - ++i; - } - } - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month || day != builder.day) { - i = 0; - year = builder.year; - month = builder.month; - day = builder.day; - } - if (i >= uhours.length) { - return false; - } - builder.hour = uhours[i++]; - return true; - } - - @Override - public String toString() { - return "byHourGenerator:" + Arrays.toString(uhours); - } - }; - } - - /** - * Constructs a generator that yields the specified minutes in increasing - * order for each hour. - * @param minutes the minute values (each value must be in range [0,59]) - * @param dtStart the start date - * @return the generator - */ - static Generator byMinuteGenerator(int[] minutes, final DateValue dtStart) { - final TimeValue dtStartTime = TimeUtils.timeOf(dtStart); - final int[] uminutes = (minutes.length == 0) ? new int[] { dtStartTime.minute() } : Util.uniquify(minutes); - - if (uminutes.length == 1) { - final int minute = uminutes[0]; - - return new SingleValueGenerator() { - int year; - int month; - int day; - int hour; - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month || day != builder.day || hour != builder.hour) { - year = builder.year; - month = builder.month; - day = builder.day; - hour = builder.hour; - builder.minute = minute; - return true; - } - return false; - } - - @Override - int getValue() { - return minute; - } - - @Override - public String toString() { - return "byMinuteGenerator:" + minute; - } - }; - } - - return new Generator() { - int i; - int year = dtStart.year(); - int month = dtStart.month(); - int day = dtStart.day(); - int hour = dtStartTime.hour(); - { - int minute = dtStartTime.minute(); - while (i < uminutes.length && uminutes[i] < minute) { - ++i; - } - } - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month || day != builder.day || hour != builder.hour) { - i = 0; - year = builder.year; - month = builder.month; - day = builder.day; - hour = builder.hour; - } - if (i >= uminutes.length) { - return false; - } - builder.minute = uminutes[i++]; - return true; - } - - @Override - public String toString() { - return "byMinuteGenerator:" + Arrays.toString(uminutes); - } - }; - } - - /** - * Constructs a generator that yields the specified seconds in increasing - * order for each minute. - * @param seconds the second values (each value must be in range [0,59]) - * @param dtStart the start date - * @return the generator - */ - static Generator bySecondGenerator(int[] seconds, final DateValue dtStart) { - final TimeValue dtStartTime = TimeUtils.timeOf(dtStart); - final int[] useconds = (seconds.length == 0) ? new int[] { dtStartTime.second() } : Util.uniquify(seconds); - - if (useconds.length == 1) { - final int second = useconds[0]; - - return new SingleValueGenerator() { - int year; - int month; - int day; - int hour; - int minute; - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month || day != builder.day || hour != builder.hour || minute != builder.minute) { - year = builder.year; - month = builder.month; - day = builder.day; - hour = builder.hour; - minute = builder.minute; - builder.second = second; - return true; - } - return false; - } - - @Override - int getValue() { - return second; - } - - @Override - public String toString() { - return "bySecondGenerator:" + second; - } - }; - } - - return new Generator() { - int i; - int year = dtStart.year(); - int month = dtStart.month(); - int day = dtStart.day(); - int hour = dtStartTime.hour(); - int minute = dtStartTime.minute(); - { - int second = dtStartTime.second(); - while (i < useconds.length && useconds[i] < second) { - ++i; - } - } - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month || day != builder.day || hour != builder.hour || minute != builder.minute) { - i = 0; - year = builder.year; - month = builder.month; - day = builder.day; - hour = builder.hour; - minute = builder.minute; - } - if (i >= useconds.length) { - return false; - } - builder.second = useconds[i++]; - return true; - } - - @Override - public String toString() { - return "bySecondGenerator:" + Arrays.toString(useconds); - } - }; - } - - /** - * Constructs a generator that yields the specified dates (possibly relative - * to end of month) in increasing order for each month seen. - * @param dates the date values (each value must be range [-31,31]) - * @param dtStart the start date - * @return the generator - */ - static Generator byMonthDayGenerator(int[] dates, final DateValue dtStart) { - final int[] udates = Util.uniquify(dates); - - return new Generator() { - int year = dtStart.year(); - int month = dtStart.month(); - /** list of generated dates for the current month */ - int[] posDates; - /** index of next date to return */ - int i = 0; - - { - convertDatesToAbsolute(); - } - - private void convertDatesToAbsolute() { - IntSet posDates = new IntSet(); - int nDays = TimeUtils.monthLength(year, month); - for (int j = 0; j < udates.length; ++j) { - int date = udates[j]; - if (date < 0) { - date += nDays + 1; - } - if (date >= 1 && date <= nDays) { - posDates.add(date); - } - } - this.posDates = posDates.toIntArray(); - } - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month) { - year = builder.year; - month = builder.month; - - convertDatesToAbsolute(); - - i = 0; - } - if (i >= posDates.length) { - return false; - } - builder.day = posDates[i++]; - return true; - } - - @Override - public String toString() { - return "byMonthDayGenerator"; - } - }; - } - - /** - * Constructs a day generator based on a BYDAY rule. - * @param days list of week/number pairs (e.g. SU,3MO means every Sunday and - * the 3rd Monday) - * @param weeksInYear true if the week numbers are meant to be weeks in the - * current year, false if they are meant to be weeks in the current month - * @param dtStart the start date - * @return the generator - */ - static Generator byDayGenerator(ByDay[] days, final boolean weeksInYear, final DateValue dtStart) { - final ByDay[] udays = days.clone(); - - return new Generator() { - int year = dtStart.year(); - int month = dtStart.month(); - /** list of generated dates for the current month */ - int[] dates; - /** index of next date to return */ - int i = 0; - - { - generateDates(); - int day = dtStart.day(); - while (i < dates.length && dates[i] < day) { - ++i; - } - } - - void generateDates() { - int nDays; - DayOfWeek dow0; - int nDaysInMonth = TimeUtils.monthLength(year, month); - //index of the first day of the month in the month or year - int d0; - - if (weeksInYear) { - nDays = TimeUtils.yearLength(year); - dow0 = TimeUtils.firstDayOfWeekInMonth(year, 1); - d0 = TimeUtils.dayOfYear(year, month, 1); - } else { - nDays = nDaysInMonth; - dow0 = TimeUtils.firstDayOfWeekInMonth(year, month); - d0 = 0; - } - - /* - * An index not greater than the first week of the month in the - * month or year. - */ - int w0 = d0 / 7; - - /* - * Iterate through days and resolve each [week, day of week] - * pair to a day of the month. - */ - IntSet udates = new IntSet(); - for (ByDay day : udays) { - if (day.getNum() != null && day.getNum() != 0) { - int date = Util.dayNumToDate(dow0, nDays, day.getNum(), day.getDay(), d0, nDaysInMonth); - if (date != 0) { - udates.add(date); - } - } else { - int wn = w0 + 6; - for (int w = w0; w <= wn; ++w) { - int date = Util.dayNumToDate(dow0, nDays, w, day.getDay(), d0, nDaysInMonth); - if (date != 0) { - udates.add(date); - } - } - } - } - dates = udates.toIntArray(); - } - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month) { - year = builder.year; - month = builder.month; - - generateDates(); - //start at the beginning of the month - i = 0; - } - if (i >= dates.length) { - return false; - } - builder.day = dates[i++]; - return true; - } - - @Override - public String toString() { - return "byDayGenerator:" + Arrays.toString(udays) + " by " + (weeksInYear ? "year" : "week"); - } - }; - } - - /** - * Constructs a generator that yields each day in the current month that - * falls in one of the given weeks of the year. - * @param weekNumbers the week numbers (each value must be in range - * [-53,53]) - * @param weekStart the day of the week that the week starts on - * @param dtStart the start date - * @return the generator - */ - static Generator byWeekNoGenerator(int[] weekNumbers, final DayOfWeek weekStart, final DateValue dtStart) { - final int[] uWeekNumbers = Util.uniquify(weekNumbers); - - return new Generator() { - int year = dtStart.year(); - int month = dtStart.month(); - /** number of weeks in the last year seen */ - int weeksInYear; - /** dates generated anew for each month seen */ - int[] dates; - /** index into dates */ - int i = 0; - - /** - * day of the year of the start of week 1 of the current year. Since - * week 1 may start on the previous year, this may be negative. - */ - int doyOfStartOfWeek1; - - { - checkYear(); - checkMonth(); - } - - void checkYear() { - //if the first day of January is weekStart, then there are 7 - //if the first day of January is weekStart + 1, then there are 6 - //if the first day of January is weekStart + 6, then there is 1 - DayOfWeek dowJan1 = TimeUtils.firstDayOfWeekInMonth(year, 1); - int nDaysInFirstWeek = 7 - ((7 + dowJan1.getCalendarConstant() - weekStart.getCalendarConstant()) % 7); - - //number of days not in any week - int nOrphanedDays = 0; - - /* - * According to RFC 2445: - * - * Week number one of the calendar year is the first week which - * contains at least four (4) days in that calendar year. - */ - if (nDaysInFirstWeek < 4) { - nOrphanedDays = nDaysInFirstWeek; - nDaysInFirstWeek = 7; - } - - /* - * Calculate the day of year (possibly negative) of the start of - * the first week in the year. This day must be of weekStart. - */ - doyOfStartOfWeek1 = nDaysInFirstWeek - 7 + nOrphanedDays; - - weeksInYear = (TimeUtils.yearLength(year) - nOrphanedDays + 6) / 7; - } - - void checkMonth() { - //the day of the year of the 1st day in the month - int doyOfMonth1 = TimeUtils.dayOfYear(year, month, 1); - - //the week of the year of the 1st day of the month. approximate. - int weekOfMonth = ((doyOfMonth1 - doyOfStartOfWeek1) / 7) + 1; - - //the number of days in the month - int nDays = TimeUtils.monthLength(year, month); - - //generate the dates in the month - IntSet udates = new IntSet(); - for (int weekNo : uWeekNumbers) { - if (weekNo < 0) { - weekNo += weeksInYear + 1; - } - if (weekNo >= weekOfMonth - 1 && weekNo <= weekOfMonth + 6) { - for (int d = 0; d < 7; ++d) { - int date = ((weekNo - 1) * 7 + d + doyOfStartOfWeek1 - doyOfMonth1) + 1; - if (date >= 1 && date <= nDays) { - udates.add(date); - } - } - } - } - dates = udates.toIntArray(); - } - - @Override - boolean generate(DTBuilder builder) { - /* - * This is a bit odd, since we're generating days within the - * given weeks of the year within the month/year from builder. - */ - if (year != builder.year || month != builder.month) { - if (year != builder.year) { - year = builder.year; - checkYear(); - } - month = builder.month; - checkMonth(); - - i = 0; - } - - if (i >= dates.length) { - return false; - } - builder.day = dates[i++]; - return true; - } - - @Override - public String toString() { - return "byWeekNoGenerator"; - } - }; - } - - /** - * Constructs a day generator that generates dates in the current month that - * fall on one of the given days of the year. - * @param yearDays the days of the year (values must be in range [-366,366]) - * @param dtStart the start date - * @return the generator - */ - static Generator byYearDayGenerator(int[] yearDays, final DateValue dtStart) { - final int[] uYearDays = Util.uniquify(yearDays); - - return new Generator() { - int year = dtStart.year(); - int month = dtStart.month(); - int[] dates; - int i = 0; - - { - checkMonth(); - } - - void checkMonth() { - //now, calculate the first week of the month - int doyOfMonth1 = TimeUtils.dayOfYear(year, month, 1); - int nDays = TimeUtils.monthLength(year, month); - int nYearDays = TimeUtils.yearLength(year); - IntSet udates = new IntSet(); - for (int yearDay : uYearDays) { - if (yearDay < 0) { - yearDay += nYearDays + 1; - } - int date = yearDay - doyOfMonth1; - if (date >= 1 && date <= nDays) { - udates.add(date); - } - } - dates = udates.toIntArray(); - } - - @Override - boolean generate(DTBuilder builder) { - if (year != builder.year || month != builder.month) { - year = builder.year; - month = builder.month; - - checkMonth(); - - i = 0; - } - if (i >= dates.length) { - return false; - } - builder.day = dates[i++]; - return true; - } - - @Override - public String toString() { - return "byYearDayGenerator"; - } - }; - } - - private static int daysBetween(DTBuilder builder, int year, int month, int day) { - if (year == builder.year && month == builder.month) { - return builder.day - day; - } else { - return TimeUtils.daysBetween(builder.year, builder.month, builder.day, year, month, day); - } - } - - private Generators() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/InstanceGenerators.java b/app/src/main/java/biweekly/util/com/google/ical/iter/InstanceGenerators.java deleted file mode 100644 index 1cfc90a8e0..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/InstanceGenerators.java +++ /dev/null @@ -1,356 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.ArrayList; -import java.util.List; - -import biweekly.util.DayOfWeek; -import biweekly.util.Frequency; -import biweekly.util.com.google.ical.util.DTBuilder; -import biweekly.util.com.google.ical.util.Predicate; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - * Factory for generators that operate on groups of generators to generate full - * dates. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -class InstanceGenerators { - /** - * A collector that yields each date in the period without doing any set - * collecting. - */ - static Generator serialInstanceGenerator(final Predicate filter, final Generator yearGenerator, final Generator monthGenerator, final Generator dayGenerator, final Generator hourGenerator, final Generator minuteGenerator, final Generator secondGenerator) { - if (skipSubDayGenerators(hourGenerator, minuteGenerator, secondGenerator)) { - //fast case for generators that are not more frequent than daily - return new Generator() { - @Override - public boolean generate(DTBuilder builder) throws IteratorShortCircuitingException { - //cascade through periods to compute the next date - do { - //until we run out of days in the current month - while (!dayGenerator.generate(builder)) { - //until we run out of months in the current year - while (!monthGenerator.generate(builder)) { - //if there are more years available fetch one - if (!yearGenerator.generate(builder)) { - //otherwise the recurrence is exhausted - return false; - } - } - } - //apply filters to generated dates - } while (!filter.apply(builder.toDateTime())); - - return true; - } - }; - } else { - return new Generator() { - @Override - public boolean generate(DTBuilder builder) throws IteratorShortCircuitingException { - //cascade through periods to compute the next date - do { - //until we run out of seconds in the current minute - while (!secondGenerator.generate(builder)) { - //until we run out of minutes in the current hour - while (!minuteGenerator.generate(builder)) { - //until we run out of hours in the current day - while (!hourGenerator.generate(builder)) { - //until we run out of days in the current month - while (!dayGenerator.generate(builder)) { - //until we run out of months in the current year - while (!monthGenerator.generate(builder)) { - //if there are more years available fetch one - if (!yearGenerator.generate(builder)) { - //otherwise the recurrence is exhausted - return false; - } - } - } - } - } - } - //apply filters to generated dates - } while (!filter.apply(builder.toDateTime())); - //TODO: maybe group the filters into different kinds so we don't - //apply filters that only affect days to every second. - - return true; - } - }; - } - } - - static Generator bySetPosInstanceGenerator(int[] setPos, final Frequency freq, final DayOfWeek wkst, final Predicate filter, final Generator yearGenerator, final Generator monthGenerator, final Generator dayGenerator, final Generator hourGenerator, final Generator minuteGenerator, final Generator secondGenerator) { - final int[] uSetPos = Util.uniquify(setPos); - - final Generator serialInstanceGenerator = serialInstanceGenerator(filter, yearGenerator, monthGenerator, dayGenerator, hourGenerator, minuteGenerator, secondGenerator); - - //TODO(msamuel): does this work? - final int maxPos = uSetPos[uSetPos.length - 1]; - final boolean allPositive = uSetPos[0] > 0; - - return new Generator() { - DateValue pushback = null; - - /** - * Is this the first instance we generate? We need to know so that - * we don't clobber dtStart. - */ - boolean first = true; - - /** - * Do we need to halt iteration once the current set has been used? - */ - boolean done = false; - - /** - * The elements in the current set, filtered by set pos. - */ - List candidates; - - /** - * Index into candidates. The number of elements in candidates - * already consumed. - */ - int i; - - @Override - public boolean generate(DTBuilder builder) throws IteratorShortCircuitingException { - while (candidates == null || i >= candidates.size()) { - if (done) { - return false; - } - - /* - * (1) Make sure that builder is appropriately initialized - * so that we only generate instances in the next set. - */ - DateValue d0 = null; - if (pushback != null) { - d0 = pushback; - builder.year = d0.year(); - builder.month = d0.month(); - builder.day = d0.day(); - pushback = null; - } else if (!first) { - /* - * We need to skip ahead to the next item since we - * didn't exhaust the last period. - */ - switch (freq) { - case YEARLY: - if (!yearGenerator.generate(builder)) { - return false; - } - // $FALL-THROUGH$ - case MONTHLY: - while (!monthGenerator.generate(builder)) { - if (!yearGenerator.generate(builder)) { - return false; - } - } - break; - case WEEKLY: - //consume because just incrementing date doesn't do anything - DateValue nextWeek = Util.nextWeekStart(builder.toDateTime(), wkst); - do { - if (!serialInstanceGenerator.generate(builder)) { - return false; - } - } while (builder.compareTo(nextWeek) < 0); - d0 = builder.toDateTime(); - break; - default: - break; - } - } else { - first = false; - } - - /* - * (2) Build a set of the dates in the year/month/week that - * match the other rule. - */ - List dates = new ArrayList(); - if (d0 != null) { - dates.add(d0); - } - - /* - * Optimization: if min(bySetPos) > 0 then we already have - * absolute positions, so we don't need to generate all of - * the instances for the period. This speeds up things like - * the first weekday of the year: - * - * RRULE:FREQ=YEARLY;BYDAY=MO,TU,WE,TH,FR,BYSETPOS=1 - * - * That would otherwise generate 260+ instances per one - * emitted. - * - * TODO(msamuel): this may be premature. If needed, We could - * improve more generally by inferring a BYMONTH generator - * based on distribution of set positions within the year. - */ - int limit = allPositive ? maxPos : Integer.MAX_VALUE; - - while (limit > dates.size()) { - if (!serialInstanceGenerator.generate(builder)) { - /* - * If we can't generate any, then make sure we - * return false once the instances we have generated - * are exhausted. If this is returning false due to - * some artificial limit, such as the 100 year limit - * in serialYearGenerator, then we exit via an - * exception because otherwise we would pick the - * wrong elements for some uSetPoses that contain - * negative elements. - */ - done = true; - break; - } - DateValue d = builder.toDateTime(); - boolean contained; - if (d0 == null) { - d0 = d; - contained = true; - } else { - switch (freq) { - case WEEKLY: - int nb = TimeUtils.daysBetween(d, d0); - /* - * Two dates (d, d0) are in the same week if - * there isn't a whole week in between them and - * the later day is later in the week than the - * earlier day. - */ - //@formatter:off - contained = - nb < 7 && - ((7 + TimeUtils.dayOfWeek(d).getCalendarConstant() - - wkst.getCalendarConstant()) % 7) > - ((7 + TimeUtils.dayOfWeek(d0).getCalendarConstant() - - wkst.getCalendarConstant()) % 7); - //@formatter:on - break; - case MONTHLY: - contained = d0.month() == d.month() && d0.year() == d.year(); - break; - case YEARLY: - contained = d0.year() == d.year(); - break; - default: - done = true; - return false; - } - } - if (contained) { - dates.add(d); - } else { - //reached end of the set - pushback = d; //save d so we can use it later - break; - } - } - - /* - * (3) Resolve the positions to absolute positions and order - * them. - */ - int[] absSetPos; - if (allPositive) { - absSetPos = uSetPos; - } else { - IntSet uAbsSetPos = new IntSet(); - for (int p : uSetPos) { - if (p < 0) { - p = dates.size() + p + 1; - } - uAbsSetPos.add(p); - } - absSetPos = uAbsSetPos.toIntArray(); - } - - candidates = new ArrayList(); - for (int p : absSetPos) { - if (p >= 1 && p <= dates.size()) { // p is 1-indexed - candidates.add(dates.get(p - 1)); - } - } - i = 0; - if (candidates.isEmpty()) { - //none in this region, so keep looking - candidates = null; - continue; - } - } - - /* - * (5) Emit a date. It will be checked against the end condition - * and dtStart elsewhere. - */ - DateValue d = candidates.get(i++); - builder.year = d.year(); - builder.month = d.month(); - builder.day = d.day(); - if (d instanceof TimeValue) { - TimeValue t = (TimeValue) d; - builder.hour = t.hour(); - builder.minute = t.minute(); - builder.second = t.second(); - } - return true; - } - }; - } - - static boolean skipSubDayGenerators(Generator hourGenerator, Generator minuteGenerator, Generator secondGenerator) { - return secondGenerator instanceof SingleValueGenerator && minuteGenerator instanceof SingleValueGenerator && hourGenerator instanceof SingleValueGenerator; - } - - private InstanceGenerators() { - // uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/IntSet.java b/app/src/main/java/biweekly/util/com/google/ical/iter/IntSet.java deleted file mode 100644 index e3759b14d6..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/IntSet.java +++ /dev/null @@ -1,133 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.BitSet; - -/** - * A set of integers in a small range. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class IntSet { - private final BitSet ints = new BitSet(); - - /** - * Adds an integer to the set. - * @param n the integer to add - */ - void add(int n) { - ints.set(encode(n)); - } - - /** - * Determines if an integer is contained within the set. - * @param n the integer to look for - * @return true if it's in the set, false if not - */ - boolean contains(int n) { - return ints.get(encode(n)); - } - - /** - * Gets the number of integers in the set. - * @return the number of integers - */ - int size() { - return ints.cardinality(); - } - - /** - * Converts this set to a new integer array that is sorted in ascending - * order. - * @return the array (sorted in ascending order) - */ - int[] toIntArray() { - int[] out = new int[size()]; - int a = 0, b = out.length; - for (int i = -1; (i = ints.nextSetBit(i + 1)) >= 0;) { - int n = decode(i); - if (n < 0) { - out[a++] = n; - } else { - out[--b] = n; - } - } - - //if it contains -3, -1, 0, 1, 2, 4 - //then out will be -1, -3, 4, 2, 1, 0 - reverse(out, 0, a); - reverse(out, a, out.length); - - return out; - } - - /** - * Encodes an integer so it can be inserted into the set. - * @param n the integer to insert - * @return the encoded value to insert into the set - */ - private static int encode(int n) { - return n < 0 ? ((-n << 1) + 1) : (n << 1); - } - - /** - * Decodes an integer from the set. - * @param i the integer to decode - * @return the decoded integer - */ - private static int decode(int i) { - return (i >>> 1) * (-(i & 1) | 1); - } - - /** - * Reverses an array. - * @param array the array - * @param start the index to start at - * @param end the index to end at - */ - private static void reverse(int[] array, int start, int end) { - for (int i = start, j = end; i < --j; ++i) { - int t = array[i]; - array[i] = array[j]; - array[j] = t; - } - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/RDateIteratorImpl.java b/app/src/main/java/biweekly/util/com/google/ical/iter/RDateIteratorImpl.java deleted file mode 100644 index 30523db6f7..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/RDateIteratorImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.Arrays; -import java.util.NoSuchElementException; - -import biweekly.util.com.google.ical.values.DateValue; - -/** - * A recurrence iterator that iterates over an array of dates. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class RDateIteratorImpl implements RecurrenceIterator { - private final DateValue[] datesUtc; - private int i; - - /** - * Creates a new recurrence iterator. - * @param datesUtc the dates to iterate over (assumes they are all in UTC) - */ - RDateIteratorImpl(DateValue[] datesUtc) { - datesUtc = datesUtc.clone(); - Arrays.sort(datesUtc); - this.datesUtc = removeDuplicates(datesUtc); - } - - public boolean hasNext() { - return i < datesUtc.length; - } - - public DateValue next() { - if (i >= datesUtc.length) { - throw new NoSuchElementException(); - } - return datesUtc[i++]; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public void advanceTo(DateValue newStartUtc) { - long startCmp = DateValueComparison.comparable(newStartUtc); - while (i < datesUtc.length && startCmp > DateValueComparison.comparable(datesUtc[i])) { - ++i; - } - } - - /** - * Removes duplicates from a list of date values. - * @param dates the date values (must be sorted in ascending order) - * @return a new array if any elements were removed or the original array if - * no elements were removed - */ - private static DateValue[] removeDuplicates(DateValue[] dates) { - int k = 0; - for (int i = 1; i < dates.length; ++i) { - if (!dates[i].equals(dates[k])) { - dates[++k] = dates[i]; - } - } - - if (++k < dates.length) { - DateValue[] uniqueDates = new DateValue[k]; - System.arraycopy(dates, 0, uniqueDates, 0, k); - return uniqueDates; - } - return dates; - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/RRuleIteratorImpl.java b/app/src/main/java/biweekly/util/com/google/ical/iter/RRuleIteratorImpl.java deleted file mode 100644 index 6387061311..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/RRuleIteratorImpl.java +++ /dev/null @@ -1,354 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.TimeZone; - -import biweekly.util.com.google.ical.util.DTBuilder; -import biweekly.util.com.google.ical.util.Predicate; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - * Iterates over dates in an RRULE or EXRULE series. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -final class RRuleIteratorImpl implements RecurrenceIterator { - /** - * Determines when the recurrence ends. The condition is applied - * after the date is converted to UTC. - */ - private final Predicate condition; - - /** - * Applies the various period generators to generate an entire date. This - * may involve generating a set of dates and discarding all but those that - * match the BYSETPOS rule. - */ - private final Generator instanceGenerator; - - /** - * Populates the builder's year field. Returns false if there aren't more - * years available. - */ - private final ThrottledGenerator yearGenerator; - - /** - * Populates the builder's month field. Returns false if there aren't more - * months available in the builder's year. - */ - private final Generator monthGenerator; - - /** - * A date that has been computed but not yet yielded to the user. - */ - private DateValue pendingUtc; - - /** - * Used to build successive dates. At the start of the building process, - * this contains the last date generated. Different periods are successively - * inserted into it. - */ - private DTBuilder builder; - - /** - * True iff the recurrence has been exhausted. - */ - private boolean done; - - /** - * The start date of the recurrence. - */ - private final DateValue dtStart; - - /** - * False iff shortcutting advance would break the semantics of the - * iteration. This may happen when, for example, the end condition requires - * that it see every item. - */ - private final boolean canShortcutAdvance; - - /** - * The timezone that resultant dates should be converted from. All - * date fields, parameters, and local variables in this class are in this - * timezone, unless they carry the UTC suffix. - */ - private final TimeZone tzid; - - /** - * Creates the iterator. - * @param dtStart the start date of the recurrence - * @param tzid the timezone that resultant dates should be converted from - * @param condition determines when the recurrence ends - * @param instanceGenerator applies the various period generators to - * generate an entire date - * @param yearGenerator populates each date's year field - * @param monthGenerator populates each date's month field - * @param dayGenerator populates each date's day field - * @param hourGenerator populates each date's hour field - * @param minuteGenerator populates each date's minute field - * @param secondGenerator populates each date's second field - * @param canShortcutAdvance false iff shortcutting advance would break the - * semantics of the iteration, true if not - */ - RRuleIteratorImpl(DateValue dtStart, TimeZone tzid, Predicate condition, Generator instanceGenerator, ThrottledGenerator yearGenerator, Generator monthGenerator, Generator dayGenerator, Generator hourGenerator, Generator minuteGenerator, Generator secondGenerator, boolean canShortcutAdvance) { - - this.condition = condition; - this.instanceGenerator = instanceGenerator; - this.yearGenerator = yearGenerator; - this.monthGenerator = monthGenerator; - this.dtStart = dtStart; - this.tzid = tzid; - this.canShortcutAdvance = canShortcutAdvance; - - int initWorkLimit = 1000; - - /* - * Initialize the builder and skip over any extraneous start instances. - */ - builder = new DTBuilder(dtStart); - - /* - * Apply the generators from largest field to smallest so we can start - * by applying the smallest field iterator when asked to generate a - * date. - */ - try { - Generator[] toInitialize; - if (InstanceGenerators.skipSubDayGenerators(hourGenerator, minuteGenerator, secondGenerator)) { - toInitialize = new Generator[] { yearGenerator, monthGenerator }; - builder.hour = ((SingleValueGenerator) hourGenerator).getValue(); - builder.minute = ((SingleValueGenerator) minuteGenerator).getValue(); - builder.second = ((SingleValueGenerator) secondGenerator).getValue(); - } else { - toInitialize = new Generator[] { yearGenerator, monthGenerator, dayGenerator, hourGenerator, minuteGenerator, }; - } - for (int i = 0; i != toInitialize.length;) { - if (toInitialize[i].generate(builder)) { - ++i; - } else { - if (--i < 0) { //no years left - done = true; - break; - } - } - - if (--initWorkLimit == 0) { - done = true; - break; - } - } - } catch (Generator.IteratorShortCircuitingException ex) { - done = true; - } - - while (!done) { - pendingUtc = generateInstance(); - if (pendingUtc == null) { - done = true; - break; - } - - if (pendingUtc.compareTo(TimeUtils.toUtc(dtStart, tzid)) >= 0) { - /* - * We only apply the condition to the ones past dtStart to avoid - * counting useless instances. - */ - if (!condition.apply(pendingUtc)) { - done = true; - pendingUtc = null; - } - break; - } - - if (--initWorkLimit == 0) { - done = true; - break; - } - } - } - - public boolean hasNext() { - if (pendingUtc == null) { - fetchNext(); - } - return pendingUtc != null; - } - - public DateValue next() { - if (pendingUtc == null) { - fetchNext(); - } - DateValue next = pendingUtc; - pendingUtc = null; - return next; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public void advanceTo(DateValue dateUtc) { - /* - * Don't throw away a future pending date since the iterators will not - * generate it again. - */ - if (pendingUtc != null && dateUtc.compareTo(pendingUtc) <= 0) { - return; - } - - DateValue dateLocal = TimeUtils.fromUtc(dateUtc, tzid); - - //short-circuit if we're already past dateUtc - if (dateLocal.compareTo(builder.toDate()) <= 0) { - return; - } - - pendingUtc = null; - - try { - if (canShortcutAdvance) { - //skip years before date.year - if (builder.year < dateLocal.year()) { - do { - if (!yearGenerator.generate(builder)) { - done = true; - return; - } - } while (builder.year < dateLocal.year()); - while (!monthGenerator.generate(builder)) { - if (!yearGenerator.generate(builder)) { - done = true; - return; - } - } - } - - if (builder.month < dateLocal.month()) { - builder.day = 1; - } - - //skip months before date.year/date.month - while (builder.year == dateLocal.year() && builder.month < dateLocal.month()) { - while (!monthGenerator.generate(builder)) { - //if there are more years available fetch one - if (!yearGenerator.generate(builder)) { - //otherwise the recurrence is exhausted - done = true; - return; - } - } - } - } - - //consume any remaining instances - while (!done) { - DateValue dUtc = generateInstance(); - if (dUtc == null) { - done = true; - return; - } - - if (!condition.apply(dUtc)) { - done = true; - return; - } - - if (dUtc.compareTo(dateUtc) >= 0) { - pendingUtc = dUtc; - break; - } - } - } catch (Generator.IteratorShortCircuitingException ex) { - done = true; - } - } - - /** calculates and stored the next date in this recurrence. */ - private void fetchNext() { - if (pendingUtc != null || done) { - return; - } - - DateValue dUtc = generateInstance(); - - //check the exit condition - if (dUtc == null || !condition.apply(dUtc)) { - done = true; - return; - } - - pendingUtc = dUtc; - yearGenerator.workDone(); - } - - private static final DateValue MIN_DATE = new DateValueImpl(Integer.MIN_VALUE, 1, 1); - - /** - * Make sure the iterator is monotonically increasing. The local time is - * guaranteed to be monotonic, but because of daylight savings shifts, the - * time in UTC may not be. - */ - private DateValue lastUtc_ = MIN_DATE; - - /** - * Generates a date. - * @return a date value in UTC or null if a date value could not be - * generated - */ - private DateValue generateInstance() { - try { - do { - if (!instanceGenerator.generate(builder)) { - return null; - } - DateValue dUtc = dtStart instanceof TimeValue ? TimeUtils.toUtc(builder.toDateTime(), tzid) : builder.toDate(); - if (dUtc.compareTo(lastUtc_) > 0) { - return dUtc; - } - } while (true); - } catch (Generator.IteratorShortCircuitingException ex) { - return null; - } - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIterable.java b/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIterable.java deleted file mode 100644 index b42dfa6bc1..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIterable.java +++ /dev/null @@ -1,51 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import biweekly.util.com.google.ical.values.DateValue; - -/** - * Iterates over a series of dates in a recurrence rule in ascending order. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public interface RecurrenceIterable extends Iterable { - RecurrenceIterator iterator(); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIterator.java b/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIterator.java deleted file mode 100644 index 7b92f10de2..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIterator.java +++ /dev/null @@ -1,79 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.Iterator; - -import biweekly.util.com.google.ical.values.DateValue; - -/** - * Iterates over a series of dates in a recurrence rule in ascending order. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public interface RecurrenceIterator extends Iterator { - /** - * Determines if there are more dates in the series. - * @return true if there are more dates, false if not - */ - boolean hasNext(); - - /** - * Returns the next date in the series. If {@link #hasNext()} returns - * {@code false}, then this method's behavior is undefined. - * @return the next date (in UTC; will be strictly later than any date - * previously returned by this iterator) - */ - DateValue next(); - - /** - * Skips all dates in the series that come before the given date, so that - * the next call to {@link #next} will return a date on or after the given - * date (assuming the recurrence includes such a date). - * @param newStartUtc the date to advance to (in UTC) - */ - void advanceTo(DateValue newStartUtc); - - /** - * Implementors of this interface are not expected to implement this method. - * @throws UnsupportedOperationException always - */ - void remove(); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIteratorFactory.java b/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIteratorFactory.java deleted file mode 100644 index d13c09739c..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/RecurrenceIteratorFactory.java +++ /dev/null @@ -1,569 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.TimeZone; - -import biweekly.util.ByDay; -import biweekly.util.DayOfWeek; -import biweekly.util.Frequency; -import biweekly.util.Google2445Utils; -import biweekly.util.ICalDate; -import biweekly.util.Recurrence; -import biweekly.util.com.google.ical.util.Predicate; -import biweekly.util.com.google.ical.util.Predicates; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateTimeValue; -import biweekly.util.com.google.ical.values.DateTimeValueImpl; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - *

- * Calculates the occurrences of an individual RRULE definition or groups of - * RRULEs, RDATEs, EXRULEs, and EXDATEs. - *

- *

- * Glossary - *

- *
    - *
  • Period - year|month|day|...
  • - *
  • Day of the week - an int in [0,6]
  • - *
  • Day of the year - zero indexed in [0,365]
  • - *
  • Day of the month - 1 indexed in [1,31]
  • - *
  • Month - 1 indexed integer in [1,12]
  • - *
- *

- * Abstractions - *

- *
    - *
  • Generator - a function corresponding to an RRULE part that takes a date - * and returns a later (year or month or day depending on its period) within the - * next larger period. A generator ignores all periods in its input smaller than - * its period.
  • - *
  • Filter - a function that returns true iff the given date matches the - * subrule.
  • - *
  • Condition - returns true if the given date is past the end of the - * recurrence.
  • - *
- *

- * All the functions that represent rule parts are stateful. - *

- * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public class RecurrenceIteratorFactory { - /** - * Creates a recurrence iterator from an RDATE or EXDATE list. - * @param dates the list of dates - * @return the iterator - */ - public static RecurrenceIterator createRecurrenceIterator(Collection dates) { - DateValue[] datesArray = dates.toArray(new DateValue[0]); - return new RDateIteratorImpl(datesArray); - } - - /** - * Creates a recurrence iterable from an RRULE. - * @param rrule the recurrence rule - * @param dtStart the start date of the series - * @param tzid the timezone that the start date is in, as well as the - * timezone to iterate in - * @return the iterable - */ - public static RecurrenceIterable createRecurrenceIterable(final Recurrence rrule, final DateValue dtStart, final TimeZone tzid) { - return new RecurrenceIterable() { - public RecurrenceIterator iterator() { - return createRecurrenceIterator(rrule, dtStart, tzid); - } - }; - } - - /** - * Creates a recurrence iterator from an RRULE. - * @param rrule the recurrence rule - * @param dtStart the start date of the series - * @param tzid the timezone that the start date is in, as well as the - * timezone to iterate in - * @return the iterator - */ - public static RecurrenceIterator createRecurrenceIterator(Recurrence rrule, DateValue dtStart, TimeZone tzid) { - Frequency freq = rrule.getFrequency(); - - /* - * If the given RRULE is malformed and does not have a frequency - * specified, default to "yearly". - */ - if (freq == null) { - freq = Frequency.YEARLY; - } - - DayOfWeek wkst = rrule.getWorkweekStarts(); - - ICalDate until = rrule.getUntil(); - int count = toInt(rrule.getCount()); - int interval = toInt(rrule.getInterval()); - ByDay[] byDay = rrule.getByDay().toArray(new ByDay[0]); - int[] byMonth = toIntArray(rrule.getByMonth()); - int[] byMonthDay = toIntArray(rrule.getByMonthDay()); - int[] byWeekNo = toIntArray(rrule.getByWeekNo()); - int[] byYearDay = toIntArray(rrule.getByYearDay()); - int[] bySetPos = toIntArray(rrule.getBySetPos()); - int[] byHour = toIntArray(rrule.getByHour()); - int[] byMinute = toIntArray(rrule.getByMinute()); - int[] bySecond = toIntArray(rrule.getBySecond()); - boolean canShortcutAdvance = true; - - if (interval <= 0) { - interval = 1; - } - - if (wkst == null) { - wkst = DayOfWeek.MONDAY; - } - - //optimize out BYSETPOS where possible - if (bySetPos.length > 0) { - switch (freq) { - case HOURLY: - if (byHour.length > 0 && byMinute.length <= 1 && bySecond.length <= 1) { - byHour = filterBySetPos(byHour, bySetPos); - } - - /* - * Handling bySetPos for rules that are more frequent than daily - * tends to lead to large amounts of processor being used before - * other work limiting features can kick in since there many - * seconds between dtStart and where the year limit kicks in. - * There are no known use cases for the use of bySetPos with - * hourly minutely and secondly rules so we just ignore it. - */ - bySetPos = NO_INTS; - break; - case MINUTELY: - if (byMinute.length > 0 && bySecond.length <= 1) { - byMinute = filterBySetPos(byMinute, bySetPos); - } - //see bySetPos handling comment above - bySetPos = NO_INTS; - break; - case SECONDLY: - if (bySecond.length > 0) { - bySecond = filterBySetPos(bySecond, bySetPos); - } - //see bySetPos handling comment above - bySetPos = NO_INTS; - break; - default: - } - - canShortcutAdvance = false; - } - - DateValue start = dtStart; - if (bySetPos.length > 0) { - /* - * Roll back until the beginning of the period to make sure that any - * positive indices are indexed properly. The actual iterator - * implementation is responsible for anything < dtStart. - */ - switch (freq) { - case YEARLY: - if (dtStart instanceof TimeValue) { - TimeValue tv = (TimeValue) dtStart; - start = new DateTimeValueImpl(start.year(), 1, 1, tv.hour(), tv.minute(), tv.second()); - } else { - start = new DateValueImpl(start.year(), 1, 1); - } - break; - case MONTHLY: - if (dtStart instanceof TimeValue) { - TimeValue tv = (TimeValue) dtStart; - start = new DateTimeValueImpl(start.year(), start.month(), 1, tv.hour(), tv.minute(), tv.second()); - } else { - start = new DateValueImpl(start.year(), start.month(), 1); - } - break; - case WEEKLY: - int d = (7 + wkst.ordinal() - TimeUtils.dayOfWeek(dtStart).getCalendarConstant()) % 7; - start = TimeUtils.add(dtStart, new DateValueImpl(0, 0, -d)); - break; - default: - break; - } - } - - /* - * Recurrences are implemented as a sequence of periodic generators. - * First a year is generated, and then months, and within months, days. - */ - ThrottledGenerator yearGenerator = Generators.serialYearGenerator(freq == Frequency.YEARLY ? interval : 1, dtStart); - Generator monthGenerator = null; - Generator dayGenerator = null; - Generator secondGenerator = null; - Generator minuteGenerator = null; - Generator hourGenerator = null; - - /* - * When multiple generators are specified for a period, they act as a - * union operator. We could have multiple generators (say, for day) and - * then run each and merge the results, but some generators are more - * efficient than others. So to avoid generating 53 Sundays and throwing - * away all but 1 for RRULE:FREQ=YEARLY;BYDAY=TU;BYWEEKNO=1, we - * reimplement some of the more prolific generators as filters. - */ - // TODO(msamuel): don't need a list here - List> filters = new ArrayList>(); - - switch (freq) { - case SECONDLY: - if (bySecond.length == 0 || interval != 1) { - secondGenerator = Generators.serialSecondGenerator(interval, dtStart); - if (bySecond.length > 0) { - filters.add(Filters.bySecondFilter(bySecond)); - } - } - break; - case MINUTELY: - if (byMinute.length == 0 || interval != 1) { - minuteGenerator = Generators.serialMinuteGenerator(interval, dtStart); - if (byMinute.length > 0) { - filters.add(Filters.byMinuteFilter(byMinute)); - } - } - break; - case HOURLY: - if (byHour.length == 0 || interval != 1) { - hourGenerator = Generators.serialHourGenerator(interval, dtStart); - if (byHour.length > 0) { - filters.add(Filters.byHourFilter(bySecond)); - } - } - break; - case DAILY: - break; - case WEEKLY: - /* - * Week is not considered a period because a week may span multiple - * months and/or years. There are no week generators, so a filter is - * used to make sure that FREQ=WEEKLY;INTERVAL=2 only generates - * dates within the proper week. - */ - if (byDay.length > 0) { - dayGenerator = Generators.byDayGenerator(byDay, false, start); - byDay = NO_DAYS; - if (interval > 1) { - filters.add(Filters.weekIntervalFilter(interval, wkst, dtStart)); - } - } else { - dayGenerator = Generators.serialDayGenerator(interval * 7, dtStart); - } - break; - case YEARLY: - if (byYearDay.length > 0) { - /* - * The BYYEARDAY rule part specifies a COMMA separated list of - * days of the year. Valid values are 1 to 366 or -366 to -1. - * For example, -1 represents the last day of the year (December - * 31st) and -306 represents the 306th to the last day of the - * year (March 1st). - */ - dayGenerator = Generators.byYearDayGenerator(byYearDay, start); - break; - } - // $FALL-THROUGH$ - case MONTHLY: - if (byMonthDay.length > 0) { - /* - * The BYMONTHDAY rule part specifies a COMMA separated list of - * days of the month. Valid values are 1 to 31 or -31 to -1. For - * example, -10 represents the tenth to the last day of the - * month. - */ - dayGenerator = Generators.byMonthDayGenerator(byMonthDay, start); - byMonthDay = NO_INTS; - } else if (byWeekNo.length > 0 && Frequency.YEARLY == freq) { - /* - * The BYWEEKNO rule part specifies a COMMA separated list of - * ordinals specifying weeks of the year. This rule part is only - * valid for YEARLY rules. - */ - dayGenerator = Generators.byWeekNoGenerator(byWeekNo, wkst, start); - byWeekNo = NO_INTS; - } else if (byDay.length > 0) { - /* - * Each BYDAY value can also be preceded by a positive (n) or - * negative (-n) integer. If present, this indicates the nth - * occurrence of the specific day within the MONTHLY or YEARLY - * RRULE. For example, within a MONTHLY rule, +1MO (or simply - * 1MO) represents the first Monday within the month, whereas - * -1MO represents the last Monday of the month. If an integer - * modifier is not present, it means all days of this type - * within the specified frequency. For example, within a MONTHLY - * rule, MO represents all Mondays within the month. - */ - dayGenerator = Generators.byDayGenerator(byDay, Frequency.YEARLY == freq && byMonth.length == 0, start); - byDay = NO_DAYS; - } else { - if (Frequency.YEARLY == freq) { - monthGenerator = Generators.byMonthGenerator(new int[] { dtStart.month() }, start); - } - dayGenerator = Generators.byMonthDayGenerator(new int[] { dtStart.day() }, start); - } - break; - } - - if (secondGenerator == null) { - secondGenerator = Generators.bySecondGenerator(bySecond, start); - } - if (minuteGenerator == null) { - if (byMinute.length == 0 && freq.compareTo(Frequency.MINUTELY) < 0) { - minuteGenerator = Generators.serialMinuteGenerator(1, dtStart); - } else { - minuteGenerator = Generators.byMinuteGenerator(byMinute, start); - } - } - if (hourGenerator == null) { - if (byHour.length == 0 && freq.compareTo(Frequency.HOURLY) < 0) { - hourGenerator = Generators.serialHourGenerator(1, dtStart); - } else { - hourGenerator = Generators.byHourGenerator(byHour, start); - } - } - - if (dayGenerator == null) { - boolean dailyOrMoreOften = freq.compareTo(Frequency.DAILY) <= 0; - if (byMonthDay.length > 0) { - dayGenerator = Generators.byMonthDayGenerator(byMonthDay, start); - byMonthDay = NO_INTS; - } else if (byDay.length > 0) { - dayGenerator = Generators.byDayGenerator(byDay, Frequency.YEARLY == freq, start); - byDay = NO_DAYS; - } else if (dailyOrMoreOften) { - dayGenerator = Generators.serialDayGenerator(Frequency.DAILY == freq ? interval : 1, dtStart); - } else { - dayGenerator = Generators.byMonthDayGenerator(new int[] { dtStart.day() }, start); - } - } - - if (byDay.length > 0) { - filters.add(Filters.byDayFilter(byDay, Frequency.YEARLY == freq, wkst)); - byDay = NO_DAYS; - } - - if (byMonthDay.length > 0) { - filters.add(Filters.byMonthDayFilter(byMonthDay)); - } - - //generator inference common to all periods - if (byMonth.length > 0) { - monthGenerator = Generators.byMonthGenerator(byMonth, start); - } else if (monthGenerator == null) { - monthGenerator = Generators.serialMonthGenerator(freq == Frequency.MONTHLY ? interval : 1, dtStart); - } - - /* - * The condition tells the iterator when to halt. The condition is - * exclusive, so the date that triggers it will not be included. - */ - Predicate condition; - if (count != 0) { - condition = Conditions.countCondition(count); - - /* - * We can't shortcut because the countCondition must see every - * generated instance. - * - * TODO(msamuel): If count is large, we might try predicting the end - * date so that we can convert the COUNT condition to an UNTIL - * condition. - */ - canShortcutAdvance = false; - } else if (until != null) { - DateValue untilUtc; - if (until.hasTime()) { - TimeZone utc = TimeZone.getTimeZone("UTC"); - untilUtc = Google2445Utils.convert(until, utc); - } else { - //treat the ICalDate object as a timezone-less, calendar date - Calendar c = Calendar.getInstance(); - c.setTime(until); - untilUtc = new DateValueImpl( //@formatter:off - c.get(Calendar.YEAR), - c.get(Calendar.MONTH) + 1, - c.get(Calendar.DAY_OF_MONTH) - ); //@formatter:on - } - - if ((untilUtc instanceof TimeValue) != (dtStart instanceof TimeValue)) { - // TODO(msamuel): warn - if (dtStart instanceof TimeValue) { - untilUtc = TimeUtils.dayStart(untilUtc); - } else { - untilUtc = TimeUtils.toDateValue(untilUtc); - } - } - condition = Conditions.untilCondition(untilUtc); - } else { - condition = Predicates.alwaysTrue(); - } - - //combine filters into a single function - Predicate filter; - switch (filters.size()) { - case 0: - filter = Predicates. alwaysTrue(); - break; - case 1: - filter = filters.get(0); - break; - default: - filter = Predicates.and(filters); - break; - } - - Generator instanceGenerator; - if (bySetPos.length > 0) { - instanceGenerator = InstanceGenerators.bySetPosInstanceGenerator(bySetPos, freq, wkst, filter, yearGenerator, monthGenerator, dayGenerator, hourGenerator, minuteGenerator, secondGenerator); - } else { - instanceGenerator = InstanceGenerators.serialInstanceGenerator(filter, yearGenerator, monthGenerator, dayGenerator, hourGenerator, minuteGenerator, secondGenerator); - } - - return new RRuleIteratorImpl(dtStart, tzid, condition, instanceGenerator, yearGenerator, monthGenerator, dayGenerator, hourGenerator, minuteGenerator, secondGenerator, canShortcutAdvance); - } - - /** - * Generates a recurrence iterator that iterates over the union of the given - * recurrence iterators. - * @param first the first recurrence iterator - * @param rest the other recurrence iterators - * @return the union iterator - */ - public static RecurrenceIterator join(RecurrenceIterator first, RecurrenceIterator... rest) { - List all = new ArrayList(); - all.add(first); - all.addAll(Arrays.asList(rest)); - return new CompoundIteratorImpl(all, Collections. emptyList()); - } - - /** - *

- * Generates a recurrence iterator that iterates over all the dates in a - * {@link RecurrenceIterator}, excluding those dates found in another - * {@link RecurrenceIterator}. - *

- *

- * Exclusions trump inclusions, and {@link DateValue dates} and - * {@link DateTimeValue date-times} never match one another. - *

- * @param included the dates to include - * @param excluded the dates to exclude - * @return the resultant iterator - */ - public static RecurrenceIterator except(RecurrenceIterator included, RecurrenceIterator excluded) { - return new CompoundIteratorImpl(Collections.singleton(included), Collections.singleton(excluded)); - } - - /** - *

- * Creates an optimized version of an array based on the given BYSETPOS - * array. - *

- *

- * For example, given the array BYMONTH=2,3,4,5 and a BYSETPOS - * of BYSETPOS=1,-1, this method will return - * BYMONTH=2,5. - *

- * @param members the array to optimize - * @param bySetPos the BYSETPOS array - * @return the optimized array - */ - private static int[] filterBySetPos(int[] members, int[] bySetPos) { - members = Util.uniquify(members); - IntSet iset = new IntSet(); - for (int pos : bySetPos) { - if (pos == 0) { - continue; - } - if (pos < 0) { - pos += members.length; - } else { - --pos; // Zero-index. - } - if (pos >= 0 && pos < members.length) { - iset.add(members[pos]); - } - } - return iset.toIntArray(); - } - - /** - * Converts an {@link Integer} list to an int array. Null values are - * converted to zero. - * @param list the {@link Integer} list - * @return the int array - */ - private static int[] toIntArray(List list) { - int[] array = new int[list.size()]; - int i = 0; - for (Integer intObj : list) { - array[i++] = toInt(intObj); - } - return array; - } - - private static int toInt(Integer integer) { - return (integer == null) ? 0 : integer; - } - - private static final int[] NO_INTS = new int[0]; - private static final ByDay[] NO_DAYS = new ByDay[0]; - - private RecurrenceIteratorFactory() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/SingleValueGenerator.java b/app/src/main/java/biweekly/util/com/google/ical/iter/SingleValueGenerator.java deleted file mode 100644 index 94c16d3c3f..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/SingleValueGenerator.java +++ /dev/null @@ -1,61 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -/** - *

- * A marker for {@link Generator}s that generate exactly one value per outer - * cycle. - *

- *

- * For example, {@code BYHOUR=3} generates exactly one hour per day and - * {@code BYMONTHDAY=12} generates exactly one day per month, but - * {@code BYHOUR=3,6} does not. Nor does {@code BYMONTHDAY=31}. - *

- * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -abstract class SingleValueGenerator extends Generator { - /** - * Gets the single value that this generator generates. - * @return the value - */ - abstract int getValue(); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/ThrottledGenerator.java b/app/src/main/java/biweekly/util/com/google/ical/iter/ThrottledGenerator.java deleted file mode 100644 index 70c33f0f1c..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/ThrottledGenerator.java +++ /dev/null @@ -1,67 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -/** - *

- * A generator that may stop generating values after some point (for example, if - * its output is never productive). - *

- *

- * This is used to stop rules like the one below from hanging an iterator. - *

- * - *
- * RRULE:FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=30
- * 
- *

- * If a rule does prove productive though, it can be alerted to the fact by the - * {@link #workDone} method, so that any throttle can be reset. - *

- * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -abstract class ThrottledGenerator extends Generator { - /** - * Called to reset any throttle after work is done. This must be called in - * the outermost loop of any iterator. - */ - abstract void workDone(); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/iter/Util.java b/app/src/main/java/biweekly/util/com/google/ical/iter/Util.java deleted file mode 100644 index f27d7a883e..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/iter/Util.java +++ /dev/null @@ -1,163 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.iter; - -import biweekly.util.ByDay; -import biweekly.util.DayOfWeek; -import biweekly.util.com.google.ical.util.DTBuilder; -import biweekly.util.com.google.ical.util.TimeUtils; -import biweekly.util.com.google.ical.values.DateValue; - -/** - * A dumping ground for utility functions that don't fit anywhere else. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -class Util { - /** - *

- * Advances the given date to next date that falls on the given weekday. If - * the given date already falls on the given weekday, then the same date is - * returned. - *

- *

- * For example, if the date is a Thursday, and the week start is Monday, - * this method will return a date value that is set to the next Monday (4 - * days in the future). - *

- * @param date the date - * @param weekday the day of the week that the week starts on - * @return the resultant date - */ - static DateValue nextWeekStart(DateValue date, DayOfWeek weekday) { - DTBuilder builder = new DTBuilder(date); - builder.day += (7 - ((7 + (TimeUtils.dayOfWeek(date).getCalendarConstant() - weekday.getCalendarConstant())) % 7)) % 7; - return builder.toDate(); - } - - /** - * Returns a sorted copy of an integer array with duplicate values removed. - * @param ints the integer array - * @return the sorted copy with duplicates removed - */ - static int[] uniquify(int[] ints) { - IntSet iset = new IntSet(); - for (int i : ints) { - iset.add(i); - } - return iset.toIntArray(); - } - - /** - * Given a weekday number, such as {@code -1SU}, this method calculates the - * day of the month that it falls on. The weekday number may be refer to a - * week in the current month in some contexts, or a week in the current year - * in other contexts. - * @param dow0 the day of week of the first day in the current year/month - * @param nDays the number of days in the current year/month (must be one of - * the following values [28,29,30,31,365,366]) - * @param weekNum the weekday number (for example, the -1 in {@code -1SU}) - * @param dow the day of the week (for example, the SU in {@code -1SU}) - * @param d0 the number of days between the first day of the current - * year/month and the current month - * @param nDaysInMonth the number of days in the current month - * @return the day of the month, or 0 if no such day exists - */ - static int dayNumToDate(DayOfWeek dow0, int nDays, int weekNum, DayOfWeek dow, int d0, int nDaysInMonth) { - //if dow is wednesday, then this is the date of the first wednesday - int firstDateOfGivenDow = 1 + ((7 + dow.getCalendarConstant() - dow0.getCalendarConstant()) % 7); - - int date; - if (weekNum > 0) { - date = ((weekNum - 1) * 7) + firstDateOfGivenDow - d0; - } else { //count weeks from end of month - //calculate last day of the given dow - //since nDays <= 366, this should be > nDays - int lastDateOfGivenDow = firstDateOfGivenDow + (7 * 54); - lastDateOfGivenDow -= 7 * ((lastDateOfGivenDow - nDays + 6) / 7); - date = lastDateOfGivenDow + 7 * (weekNum + 1) - d0; - } - return (date <= 0 || date > nDaysInMonth) ? 0 : date; - } - - /** - *

- * Converts a relative week number (such as {@code -1SU}) to an absolute - * week number. - *

- *

- * For example, the week number {@code -1SU} refers to the last Sunday of - * either the month or year (depending on how this method was called). So if - * there are 5 Sundays in the given period, then given a week number of - * {@code -1SU}, this method would return 5. Similarly, {@code -2SU} would - * return 4. - *

- * @param weekdayNum the weekday number (must be a negative value, such as - * {@code -1SU}) - * @param dow0 the day of the week of the first day of the week or month - * @param nDays the number of days in the month or year - * @return the absolute week number - */ - static int invertWeekdayNum(ByDay weekdayNum, DayOfWeek dow0, int nDays) { - //how many are there of that week? - return countInPeriod(weekdayNum.getDay(), dow0, nDays) + weekdayNum.getNum() + 1; - } - - /** - * Counts the number of occurrences of a weekday in a given period. - * @param dow the weekday - * @param dow0 the weekday of the first day of the period - * @param nDays the number of days in the period - */ - static int countInPeriod(DayOfWeek dow, DayOfWeek dow0, int nDays) { - //two cases: - // (1a) dow >= dow0: count === (nDays - (dow - dow0)) / 7 - // (1b) dow < dow0: count === (nDays - (7 - dow0 - dow)) / 7 - if (dow.getCalendarConstant() >= dow0.getCalendarConstant()) { - return 1 + ((nDays - (dow.getCalendarConstant() - dow0.getCalendarConstant()) - 1) / 7); - } else { - return 1 + ((nDays - (7 - (dow0.getCalendarConstant() - dow.getCalendarConstant())) - 1) / 7); - } - } - - private Util() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/util/DTBuilder.java b/app/src/main/java/biweekly/util/com/google/ical/util/DTBuilder.java deleted file mode 100644 index b2d119e185..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/util/DTBuilder.java +++ /dev/null @@ -1,264 +0,0 @@ -// 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. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.util; - -import biweekly.util.com.google.ical.values.DateTimeValue; -import biweekly.util.com.google.ical.values.DateTimeValueImpl; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - * A mutable buffer used to build {@link DateValue}s and {@link DateTimeValue}s. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public class DTBuilder { - /** - * The year. - */ - public int year; - - /** - * The month. This value is one-indexed, so "1" represents January. - */ - public int month; - - /** - * The day of the month. - */ - public int day; - - /** - * The hour. - */ - public int hour; - - /** - * The minute. - */ - public int minute; - - /** - * The second. - */ - public int second; - - /** - * Creates a new date builder. - * @param year the initial year - * @param month the initial month (this value is one-indexed, so "1" - * represents January) - * @param day the initial day - * @param hour the initial hour - * @param minute the initial minute - * @param second the initial second - */ - public DTBuilder(int year, int month, int day, int hour, int minute, int second) { - this.year = year; - this.month = month; - this.day = day; - this.hour = hour; - this.minute = minute; - this.second = second; - } - - /** - * Creates a new date builder. This constructor sets the time components to - * zero. - * @param year the initial year - * @param month the initial month (this value is one-indexed, so "1" - * represents January) - * @param day the initial day - */ - public DTBuilder(int year, int month, int day) { - this(year, month, day, 0, 0, 0); - } - - /** - * Creates a new date builder, initializing it to the given date value. - * @param date the date value to initialize the builder with - */ - public DTBuilder(DateValue date) { - this.year = date.year(); - this.month = date.month(); - this.day = date.day(); - if (date instanceof TimeValue) { - TimeValue tv = (TimeValue) date; - this.hour = tv.hour(); - this.minute = tv.minute(); - this.second = tv.second(); - } - } - - /** - * Produces a normalized date-time value, using zero for the time fields if - * none were provided. - * @return the date-time value - */ - public DateTimeValue toDateTime() { - normalize(); - return new DateTimeValueImpl(year, month, day, hour, minute, second); - } - - /** - * Produces a normalized date value. - * @return the date value - */ - public DateValue toDate() { - normalize(); - return new DateValueImpl(year, month, day); - } - - /** - *

- * Compares the value of this builder to a given {@link DateValue}. Note - * that this method's behavior is undefined unless {@link #normalize} is - * called first. - *

- *

- * If you're not sure whether it's appropriate to use this method, use - * toDateValue().compareTo(dv) instead. - *

- * @param date the date value to compare against - * @return a negative value if this date builder is less than the given date - * value, a positive value if this date builder is greater than the given - * date value, or zero if they are equal - */ - public int compareTo(DateValue date) { - long dvComparable = (((((long) date.year()) << 4) + date.month()) << 5) + date.day(); - long dtbComparable = ((((long) year << 4) + month << 5)) + day; - if (date instanceof TimeValue) { - TimeValue tv = (TimeValue) date; - dvComparable = (((((dvComparable << 5) + tv.hour()) << 6) + tv.minute()) << 6) + tv.second(); - dtbComparable = (((((dtbComparable << 5) + hour) << 6) + minute) << 6) + second; - } - long delta = dtbComparable - dvComparable; - return delta < 0 ? -1 : delta == 0 ? 0 : 1; - } - - /** - * Makes sure that the fields are in the proper ranges (for example, - * converts 32 January to 1 February, and 25:00:00 to 1:00:00 of the next - * day). - */ - public void normalize() { - normalizeTime(); - normalizeDate(); - } - - @Override - public String toString() { - return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof DTBuilder)) { - return false; - } - DTBuilder that = (DTBuilder) o; - return this.year == that.year && this.month == that.month && this.day == that.day && this.hour == that.hour && this.minute == that.minute && this.second == that.second; - } - - @Override - public int hashCode() { - return ((((((((year << 4) + month << 5) + day) << 5) + hour) << 6) + minute) << 6) + second; - } - - /** - * Makes sure that the time fields are in the proper ranges (for example, - * converts 25:00:00 to 1:00:00 of the next day). - */ - private void normalizeTime() { - int addMinutes = ((second < 0) ? (second - 59) : second) / 60; - second -= addMinutes * 60; - minute += addMinutes; - int addHours = ((minute < 0) ? (minute - 59) : minute) / 60; - minute -= addHours * 60; - hour += addHours; - int addDays = ((hour < 0) ? (hour - 23) : hour) / 24; - hour -= addDays * 24; - day += addDays; - } - - /** - * Makes sure that the date fields are in the proper ranges (for example, - * converts 32 January to 1 February). - */ - private void normalizeDate() { - while (day <= 0) { - int days = TimeUtils.yearLength(month > 2 ? year : year - 1); - day += days; - --year; - } - - if (month <= 0) { - int years = month / 12 - 1; - year += years; - month -= 12 * years; - } else if (month > 12) { - int years = (month - 1) / 12; - year += years; - month -= 12 * years; - } - - while (true) { - if (month == 1) { - int yearLength = TimeUtils.yearLength(year); - if (day > yearLength) { - ++year; - day -= yearLength; - } - } - - int monthLength = TimeUtils.monthLength(year, month); - if (day <= monthLength) { - break; - } - - day -= monthLength; - if (++month > 12) { - month -= 12; - ++year; - } - } - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/util/Predicate.java b/app/src/main/java/biweekly/util/com/google/ical/util/Predicate.java deleted file mode 100644 index 98b9a35dc7..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/util/Predicate.java +++ /dev/null @@ -1,45 +0,0 @@ -// CopyrightGoogle Inc. All rights reserved. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.util; - -import java.io.Serializable; - -/** - * A function with a boolean return value. Useful for filtering. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - * @param the input type - */ -public interface Predicate extends Serializable { - /** - * Applies this predicate to the given object. - * @param input the input - * @return the value of this predicate when applied to the input - */ - boolean apply(T input); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/util/Predicates.java b/app/src/main/java/biweekly/util/com/google/ical/util/Predicates.java deleted file mode 100644 index 0c83a5fa2c..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/util/Predicates.java +++ /dev/null @@ -1,231 +0,0 @@ -// CopyrightGoogle Inc. All rights reserved. - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.util; - -import java.util.Collection; - -/** - * Static methods for creating the standard set of {@link Predicate} objects. - * @author mikesamuel+svn@gmail.com (Mike Samuel) - * @author Michael Angstadt - */ -public class Predicates { - private static final Predicate ALWAYS_TRUE = new AlwaysTruePredicate(); - private static final Predicate ALWAYS_FALSE = new AlwaysFalsePredicate(); - - /** - * Returns a predicate that always evaluates to true. - * @param the input type - * @return the predicate - */ - @SuppressWarnings("unchecked") - public static Predicate alwaysTrue() { - return (Predicate) ALWAYS_TRUE; - } - - /** - * Returns a predicate that always evaluates to false. - * @param the input type - * @return the predicate - */ - @SuppressWarnings("unchecked") - public static Predicate alwaysFalse() { - return (Predicate) ALWAYS_FALSE; - } - - /** - * Returns a predicate that evaluates to true iff the given predicate - * evaluates to false. - * @param predicate the predicate to evaluate - * @param the input type - * @return the resultant predicate - */ - public static Predicate not(Predicate predicate) { - return new NotPredicate(predicate); - } - - /** - * Returns a predicate that evaluates to true iff each of its components - * evaluates to true. The components are evaluated in order, and evaluation - * will be "short-circuited" as soon as the answer is determined. - * @param components the predicates to evaluate - * @param the input type - * @return the resultant predicate - */ - public static Predicate and(Predicate... components) { - components = components.clone(); - int n = components.length; - for (int i = 0; i < n; ++i) { - Predicate p = components[i]; - if (p == ALWAYS_FALSE) { - return alwaysFalse(); - } - if (p == ALWAYS_TRUE) { - components[i] = components[n - 1]; - --i; - --n; - } - } - if (n == 0) { - return alwaysTrue(); - } - if (n != components.length) { - @SuppressWarnings("unchecked") - Predicate[] newComponents = new Predicate[n]; - System.arraycopy(newComponents, 0, components, 0, n); - components = newComponents; - } - return new AndPredicate(components); - } - - /** - * Returns a predicate that evaluates to true iff each of its components - * evaluates to true. The components are evaluated in order, and evaluation - * will be "short-circuited" as soon as the answer is determined. - * @param components the predicates to evaluate - * @param the input type - * @return the resultant predicate - */ - @SuppressWarnings("unchecked") - public static Predicate and(Collection> components) { - return and(components.toArray(new Predicate[0])); - } - - /** - * Returns a predicate that evaluates to true iff any one of its components - * evaluates to true. The components are evaluated in order, and evaluation - * will be "short-circuited" as soon as the answer is determined. - * @param components the predicates to evaluate - * @param the input type - * @return the resultant predicate - */ - public static Predicate or(Predicate... components) { - components = components.clone(); - int n = components.length; - for (int i = 0; i < n; ++i) { - Predicate p = components[i]; - if (p == ALWAYS_TRUE) { - return alwaysTrue(); - } - if (p == ALWAYS_FALSE) { - components[i] = components[n - 1]; - --i; - --n; - } - } - if (n == 0) { - return alwaysFalse(); - } - if (n != components.length) { - @SuppressWarnings("unchecked") - Predicate[] newComponents = new Predicate[n]; - System.arraycopy(newComponents, 0, components, 0, n); - components = newComponents; - } - return new OrPredicate(components); - } - - private static class AlwaysTruePredicate implements Predicate { - private static final long serialVersionUID = 8759914710239461322L; - - public boolean apply(T t) { - return true; - } - - @Override - public String toString() { - return "true"; - } - } - - private static class AlwaysFalsePredicate implements Predicate { - private static final long serialVersionUID = -565481022115659695L; - - public boolean apply(T t) { - return false; - } - - @Override - public String toString() { - return "false"; - } - } - - private static class NotPredicate implements Predicate { - private static final long serialVersionUID = -5113445916422049953L; - private final Predicate predicate; - - private NotPredicate(Predicate predicate) { - this.predicate = predicate; - } - - public boolean apply(T t) { - return !predicate.apply(t); - } - } - - private static class AndPredicate implements Predicate { - private static final long serialVersionUID = 1022358602593297546L; - private final Predicate[] components; - - private AndPredicate(Predicate... components) { - this.components = components; - } - - public boolean apply(T t) { - for (Predicate predicate : components) { - if (!predicate.apply(t)) { - return false; - } - } - return true; - } - } - - private static class OrPredicate implements Predicate { - private static final long serialVersionUID = -7942366790698074803L; - private final Predicate[] components; - - private OrPredicate(Predicate... components) { - this.components = components; - } - - public boolean apply(T t) { - for (Predicate predicate : components) { - if (predicate.apply(t)) { - return true; - } - } - return false; - } - } - - private Predicates() { - //uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/util/TimeUtils.java b/app/src/main/java/biweekly/util/com/google/ical/util/TimeUtils.java deleted file mode 100644 index 8581d8b02e..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/util/TimeUtils.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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. - * All Rights Reserved. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.util; - -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.SimpleTimeZone; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import biweekly.util.DayOfWeek; -import biweekly.util.com.google.ical.values.DateTimeValue; -import biweekly.util.com.google.ical.values.DateTimeValueImpl; -import biweekly.util.com.google.ical.values.DateValue; -import biweekly.util.com.google.ical.values.DateValueImpl; -import biweekly.util.com.google.ical.values.TimeValue; - -/** - * Utility methods for working with times and dates. - * @author Neal Gafter - * @author Michael Angstadt - */ -public class TimeUtils { - private static TimeZone ZULU = new SimpleTimeZone(0, "Etc/GMT"); - - /** - * Gets the UTC timezone. - * @return the UTC timezone - */ - public static TimeZone utcTimezone() { - return ZULU; - } - - /** - * Get a "time_t" in milliseconds given a number of seconds since the - * Dershowitz/Reingold epoch relative to a given timezone. - * @param epochSecs the number of seconds since the Dershowitz/Reingold - * epoch relative to the given timezone - * @param zone timezone against which epochSecs applies - * @return the number of milliseconds since 00:00:00 Jan 1, 1970 GMT - */ - private static long timetMillisFromEpochSecs(long epochSecs, TimeZone zone) { - DateTimeValue date = timeFromSecsSinceEpoch(epochSecs); - Calendar cal = new GregorianCalendar(zone); - cal.clear(); - cal.set(date.year(), date.month() - 1, date.day(), date.hour(), date.minute(), date.second()); - return cal.getTimeInMillis(); - } - - private static DateTimeValue convert(DateTimeValue time, TimeZone zone, int sense) { - if (zone == null || zone.hasSameRules(ZULU) || time.year() == 0) { - return time; - } - - TimeZone epochTz, dateTimeValueTz; - if (sense > 0) { - //time is in UTC; convert to time in zone provided - epochTz = ZULU; - dateTimeValueTz = zone; - } else { - //time is in local time; convert to UTC - epochTz = zone; - dateTimeValueTz = ZULU; - } - - long epochSeconds = secsSinceEpoch(time); - long timetMillis = timetMillisFromEpochSecs(epochSeconds, epochTz); - return toDateTimeValue(timetMillis, dateTimeValueTz); - } - - /** - * Converts a {@link DateValue} from UTC to another timezone. - * @param date the date value (in UTC) - * @param zone the timezone to convert to - * @return the converted date value - */ - public static DateValue fromUtc(DateValue date, TimeZone zone) { - return (date instanceof DateTimeValue) ? fromUtc((DateTimeValue) date, zone) : date; - } - - /** - * Converts a {@link DateTimeValue} from UTC to another timezone. - * @param date the date-time value (in UTC) - * @param zone the timezone to convert to - * @return the converted date-time value - */ - public static DateTimeValue fromUtc(DateTimeValue date, TimeZone zone) { - return convert(date, zone, +1); - } - - /** - * Converts a {@link DateValue} to UTC. - * @param date the date value - * @param zone the timezone the date value is in - * @return the converted date value - */ - public static DateValue toUtc(DateValue date, TimeZone zone) { - return (date instanceof TimeValue) ? convert((DateTimeValue) date, zone, -1) : date; - } - - /** - * Adds a duration to a date. - * @param date the date - * @param duration the duration to add to the date - * @return the result - */ - public static DateValue add(DateValue date, DateValue duration) { - DTBuilder db = new DTBuilder(date); - db.year += duration.year(); - db.month += duration.month(); - db.day += duration.day(); - if (duration instanceof TimeValue) { - TimeValue tdur = (TimeValue) duration; - db.hour += tdur.hour(); - db.minute += tdur.minute(); - db.second += tdur.second(); - return db.toDateTime(); - } - return (date instanceof TimeValue) ? db.toDateTime() : db.toDate(); - } - - /** - * Calculates the number of days between two dates. - * @param date1 the first date - * @param date2 the second date - * @return the number of days - */ - public static int daysBetween(DateValue date1, DateValue date2) { - return fixedFromGregorian(date1) - fixedFromGregorian(date2); - } - - /** - * Calculates the number of days between two dates. - * @param year1 the year of the first date - * @param month1 the month of the first date - * @param day1 the day of the first date - * @param year2 the year of the second date - * @param month2 the month of the second date - * @param day2 the day of the second date - * @return the number of days - */ - public static int daysBetween(int year1, int month1, int day1, int year2, int month2, int day2) { - return fixedFromGregorian(year1, month1, day1) - fixedFromGregorian(year2, month2, day2); - } - - /** - *

- * Calculates the number of days since the epoch. - *

- *

- * This is the imaginary beginning of year zero in a hypothetical backward - * extension of the Gregorian calendar through time. See - * "Calendrical Calculations" by Reingold and Dershowitz. - *

- * @param date the date to start from - * @return the number of days - */ - private static int fixedFromGregorian(DateValue date) { - return fixedFromGregorian(date.year(), date.month(), date.day()); - } - - /** - *

- * Calculates the number of days since the epoch. - *

- *

- * This is the imaginary beginning of year zero in a hypothetical backward - * extension of the Gregorian calendar through time. See - * "Calendrical Calculations" by Reingold and Dershowitz. - *

- * @param year the year of the date to start from - * @param month the month of the date to start from - * @param day the day of the date to start from - * @return the number of days - */ - public static int fixedFromGregorian(int year, int month, int day) { - int yearM1 = year - 1; - return 365 * yearM1 + yearM1 / 4 - yearM1 / 100 + yearM1 / 400 + (367 * month - 362) / 12 + (month <= 2 ? 0 : isLeapYear(year) ? -1 : -2) + day; - } - - /** - * Determines if a year is a leap year. - * @param year the year - * @return true if it's a leap year, false if not - */ - public static boolean isLeapYear(int year) { - return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); - } - - /** - * Determines how many days are in a year. - * @param year the year - * @return the number of days - */ - public static int yearLength(int year) { - return isLeapYear(year) ? 366 : 365; - } - - /** - * Calculates the number of days in a month. - * @param year the year - * @param month the month (in range [1,12]) - * @return the number of days - */ - public static int monthLength(int year, int month) { - switch (month) { - case 1: - case 3: - case 5: - case 7: - case 8: - case 10: - case 12: - return 31; - case 4: - case 6: - case 9: - case 11: - return 30; - case 2: - return isLeapYear(year) ? 29 : 28; - default: - throw new AssertionError(month); - } - } - - private static int[] MONTH_START_TO_DOY = new int[12]; - static { - for (int m = 1; m < 12; ++m) { - MONTH_START_TO_DOY[m] = MONTH_START_TO_DOY[m - 1] + monthLength(1970, m); - } - } - - /** - * Gets the day of the year for a given date. - * @param year the date's year - * @param month the date's month - * @param date the date's day - * @return the day of the year (in range [0-365]) - */ - public static int dayOfYear(int year, int month, int date) { - int leapAdjust = month > 2 && isLeapYear(year) ? 1 : 0; - return MONTH_START_TO_DOY[month - 1] + leapAdjust + date - 1; - } - - private static final DayOfWeek[] DAYS_OF_WEEK = DayOfWeek.values(); - - /** - * Gets the day of the week the given date falls on. - * @param date the date - * @return the day of the week - */ - public static DayOfWeek dayOfWeek(DateValue date) { - int dayIndex = fixedFromGregorian(date.year(), date.month(), date.day()) % 7; - if (dayIndex < 0) { - dayIndex += 7; - } - return DAYS_OF_WEEK[dayIndex]; - } - - /** - * Gets the day of the week of the first day in the given month. - * @param year the year - * @param month the month (1-12) - * @return the day of the week - */ - public static DayOfWeek firstDayOfWeekInMonth(int year, int month) { - int result = fixedFromGregorian(year, month, 1) % 7; - if (result < 0) { - result += 7; - } - return DAYS_OF_WEEK[result]; - } - - /** - * Computes the gregorian time from the number of seconds since the - * Proleptic Gregorian Epoch. See "Calendrical Calculations", Reingold and - * Dershowitz. - * @param secsSinceEpoch the number of seconds since the epoch - * @return the gregorian time - */ - public static DateTimeValue timeFromSecsSinceEpoch(long secsSinceEpoch) { - // TODO: should we handle -ve years? - int secsInDay = (int) (secsSinceEpoch % SECS_PER_DAY); - int daysSinceEpoch = (int) (secsSinceEpoch / SECS_PER_DAY); - int approx = (int) ((daysSinceEpoch + 10) * 400L / 146097); - int year = (daysSinceEpoch >= fixedFromGregorian(approx + 1, 1, 1)) ? approx + 1 : approx; - int jan1 = fixedFromGregorian(year, 1, 1); - int priorDays = daysSinceEpoch - jan1; - int march1 = fixedFromGregorian(year, 3, 1); - int correction = (daysSinceEpoch < march1) ? 0 : isLeapYear(year) ? 1 : 2; - int month = (12 * (priorDays + correction) + 373) / 367; - int month1 = fixedFromGregorian(year, month, 1); - int day = daysSinceEpoch - month1 + 1; - int second = secsInDay % 60; - int minutesInDay = secsInDay / 60; - int minute = minutesInDay % 60; - int hour = minutesInDay / 60; - if (!(hour >= 0 && hour < 24)) { - throw new AssertionError("Input was: " + secsSinceEpoch + "to make hour: " + hour); - } - return new DateTimeValueImpl(year, month, day, hour, minute, second); - } - - private static final long SECS_PER_DAY = 60L * 60 * 24; - - /** - * Computes the number of seconds from the Proleptic Gregorian epoch to the - * given time. See "Calendrical Calculations", Reingold and Dershowitz. - * @param date the date - * @return the number of seconds - */ - public static long secsSinceEpoch(DateValue date) { - long result = fixedFromGregorian(date) * SECS_PER_DAY; - if (date instanceof TimeValue) { - TimeValue time = (TimeValue) date; - result += time.second() + 60 * (time.minute() + 60 * time.hour()); - } - return result; - } - - /** - * Builds a date-time value that represents the start of the given day (all - * time components set to 0). - * @param date the day - * @return the date-time value - */ - public static DateTimeValue dayStart(DateValue date) { - return new DateTimeValueImpl(date.year(), date.month(), date.day(), 0, 0, 0); - } - - /** - * Converts the given date to a {@link DateValue} object if it is a - * {@link TimeValue} instance. If it is not a {@link TimeValue} instance, - * then the same date object is returned unchanged. - * @param date the date - * @return the date value - */ - public static DateValue toDateValue(DateValue date) { - return (date instanceof TimeValue) ? new DateValueImpl(date.year(), date.month(), date.day()) : date; - } - - private static final TimeZone BOGUS_TIMEZONE = TimeZone.getTimeZone("noSuchTimeZone"); - - private static final Pattern UTC_TZID = Pattern.compile("^GMT([+-]0(:00)?)?$|UTC|Zulu|Etc\\/GMT|Greenwich.*", Pattern.CASE_INSENSITIVE); - - /** - * Returns the timezone with the given name or null if no such timezone. - * @param tzString the timezone name (e.g. "America/New_York") - * @return the timezone or null if no such timezone exists - */ - public static TimeZone timeZoneForName(String tzString) { - TimeZone tz = TimeZone.getTimeZone(tzString); - if (!tz.hasSameRules(BOGUS_TIMEZONE)) { - return tz; - } - - /* - * See if the user really was asking for GMT because if - * TimeZone.getTimeZone can't recognize tzString, then that is what it - * will return. - */ - Matcher m = UTC_TZID.matcher(tzString); - return m.matches() ? TimeUtils.utcTimezone() : null; - } - - /** - * Builds a {@link DateTimeValue} object from the given data. - * @param millisFromEpoch the number of milliseconds from the epoch - * @param zone the timezone the number of milliseconds is in - * @return the {@link DateTimeValue} object - */ - public static DateTimeValue toDateTimeValue(long millisFromEpoch, TimeZone zone) { - GregorianCalendar c = new GregorianCalendar(zone); - c.clear(); - c.setTimeInMillis(millisFromEpoch); - //@formatter:off - return new DateTimeValueImpl ( - c.get(Calendar.YEAR), - c.get(Calendar.MONTH) + 1, - c.get(Calendar.DAY_OF_MONTH), - c.get(Calendar.HOUR_OF_DAY), - c.get(Calendar.MINUTE), - c.get(Calendar.SECOND) - ); - //@formatter:on - } - - private static final TimeValue MIDNIGHT = new TimeValue() { - public int hour() { - return 0; - } - - public int minute() { - return 0; - } - - public int second() { - return 0; - } - }; - - /** - * Gets the time component of a date value. - * @param date the date value - * @return the date value's time component or a time value representing - * midnight if the date value does not have a time component - */ - public static TimeValue timeOf(DateValue date) { - return (date instanceof TimeValue) ? (TimeValue) date : MIDNIGHT; - } - - private TimeUtils() { - // uninstantiable - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/values/DateTimeValue.java b/app/src/main/java/biweekly/util/com/google/ical/values/DateTimeValue.java deleted file mode 100644 index 6dd747b13d..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/values/DateTimeValue.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - * All Rights Reserved. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.values; - -/** - * An instant in time. - * @author Neal Gafter - * @author Michael Angstadt - */ -public interface DateTimeValue extends DateValue, TimeValue { - //simple union -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/values/DateTimeValueImpl.java b/app/src/main/java/biweekly/util/com/google/ical/values/DateTimeValueImpl.java deleted file mode 100644 index c73bd9593e..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/values/DateTimeValueImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - * All Rights Reserved. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.values; - -/** - * An instant in time. - * @author Neal Gafter - * @author Michael Angstadt - */ -public class DateTimeValueImpl extends DateValueImpl implements DateTimeValue { - private final int hour, minute, second; - - /** - * Creates a new date-time value. - * @param year the year - * @param month the month (1-12) - * @param day the day (1-31) - * @param hour the hour (0-24) - * @param minute the minute (0-59) - * @param second the second (0-59) - */ - public DateTimeValueImpl(int year, int month, int day, int hour, int minute, int second) { - super(year, month, day); - this.hour = hour; - this.minute = minute; - this.second = second; - } - - public int hour() { - return hour; - } - - public int minute() { - return minute; - } - - public int second() { - return second; - } - - @Override - public int hashCode() { - return super.hashCode() ^ ((hour << 12) + (minute << 6) + second); - } - - @Override - public String toString() { - return String.format("%sT%02d%02d%02d", super.toString(), hour, minute, second); - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/values/DateValue.java b/app/src/main/java/biweekly/util/com/google/ical/values/DateValue.java deleted file mode 100644 index a2315839d1..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/values/DateValue.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - * All Rights Reserved. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.values; - -/** - * A calendar date. - * @author Neal Gafter - * @author Michael Angstadt - */ -public interface DateValue extends Comparable { - /** - * Gets the Gregorian year (for example, 2004). - * @return the year - */ - int year(); - - /** - * Gets the Gregorian month (in the range 1-12). - * @return the month - */ - int month(); - - /** - * Gets the Gregorian day of the month (in the range 1-31). - * @return the day of the month - */ - int day(); -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/values/DateValueImpl.java b/app/src/main/java/biweekly/util/com/google/ical/values/DateValueImpl.java deleted file mode 100644 index dce6934236..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/values/DateValueImpl.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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. - * All Rights Reserved. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.values; - -/** - * A calendar date. - * @author Neal Gafter - * @author Michael Angstadt - */ -public class DateValueImpl implements DateValue { - private final int year, month, day; - - /** - * Creates a new date value. - * @param year the year - * @param month the month (1-12) - * @param day the day (1-31) - */ - public DateValueImpl(int year, int month, int day) { - this.year = year; - this.month = month; - this.day = day; - } - - public int year() { - return year; - } - - public int month() { - return month; - } - - public int day() { - return day; - } - - @Override - public String toString() { - return String.format("%04d%02d%02d", year, month, day); - } - - public final int compareTo(DateValue other) { - //@formatter:off - int n0 = day() + //5 bits - (month() << 5) + //4 bits - (year() << 9); - int n1 = other.day() + - (other.month() << 5) + - (other.year() << 9); - //@formatter:on - - if (n0 != n1) { - return n0 - n1; - } - - if (!(this instanceof TimeValue)) { - return (other instanceof TimeValue) ? -1 : 0; - } - - TimeValue self = (TimeValue) this; - if (!(other instanceof TimeValue)) { - return 1; - } - - TimeValue othr = (TimeValue) other; - //@formatter:off - int m0 = self.second() + //6 bits - (self.minute() << 6) + //6 bits - (self.hour() << 12); - int m1 = othr.second() + - (othr.minute() << 6) + - (othr.hour() << 12); - //@formatter:on - return m0 - m1; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof DateValue)) { - return false; - } - return compareTo((DateValue) o) == 0; - } - - @Override - public int hashCode() { - return (year() << 9) + (month() << 5) + day(); - } -} diff --git a/app/src/main/java/biweekly/util/com/google/ical/values/TimeValue.java b/app/src/main/java/biweekly/util/com/google/ical/values/TimeValue.java deleted file mode 100644 index d705df48e6..0000000000 --- a/app/src/main/java/biweekly/util/com/google/ical/values/TimeValue.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - * All Rights Reserved. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.com.google.ical.values; - -/** - * A time of day. - * @author Neal Gafter - * @author Michael Angstadt - */ -public interface TimeValue { - /** - * Gets the hour (in the range 0-24). - * @return the hour - */ - int hour(); - - /** - * Gets the minute (in the range 0-59). If the hour is 24, then this method - * should return zero. - * @return the minute - */ - int minute(); - - /** - * Gets the second (in the range 0 through 59). If the hour is 24, then this - * method should return zero. - * @return the second - */ - int second(); -} diff --git a/app/src/main/java/biweekly/util/org/apache/commons/codec/DecoderException.java b/app/src/main/java/biweekly/util/org/apache/commons/codec/DecoderException.java deleted file mode 100644 index 6cb03f423e..0000000000 --- a/app/src/main/java/biweekly/util/org/apache/commons/codec/DecoderException.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 biweekly.util.org.apache.commons.codec; - -/** - * Thrown when there is a failure condition during the decoding process. This exception is thrown when a {@link Decoder} - * encounters a decoding specific exception such as invalid data, or characters outside of the expected range. - * - * @version $Id: DecoderException.java 1619948 2014-08-22 22:53:55Z ggregory $ - */ -public class DecoderException extends Exception { - - /** - * Declares the Serial Version Uid. - * - * @see Always Declare Serial Version Uid - */ - private static final long serialVersionUID = 1L; - - /** - * Constructs a new exception with null as its detail message. The cause is not initialized, and may - * subsequently be initialized by a call to {@link #initCause}. - * - * @since 1.4 - */ - public DecoderException() { - super(); - } - - /** - * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently - * be initialized by a call to {@link #initCause}. - * - * @param message - * The detail message which is saved for later retrieval by the {@link #getMessage()} method. - */ - public DecoderException(final String message) { - super(message); - } - - /** - * Constructs a new exception with the specified detail message and cause. - *

- * Note that the detail message associated with cause is not automatically incorporated into this - * exception's detail message. - * - * @param message - * The detail message which is saved for later retrieval by the {@link #getMessage()} method. - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A null - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public DecoderException(final String message, final Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new exception with the specified cause and a detail message of (cause==null ? - * null : cause.toString()) (which typically contains the class and detail message of cause). - * This constructor is useful for exceptions that are little more than wrappers for other throwables. - * - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A null - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public DecoderException(final Throwable cause) { - super(cause); - } -} diff --git a/app/src/main/java/biweekly/util/org/apache/commons/codec/EncoderException.java b/app/src/main/java/biweekly/util/org/apache/commons/codec/EncoderException.java deleted file mode 100644 index 7b2b155479..0000000000 --- a/app/src/main/java/biweekly/util/org/apache/commons/codec/EncoderException.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 biweekly.util.org.apache.commons.codec; - -/** - * Thrown when there is a failure condition during the encoding process. This exception is thrown when an - * {@link Encoder} encounters a encoding specific exception such as invalid data, inability to calculate a checksum, - * characters outside of the expected range. - * - * @version $Id: EncoderException.java 1619948 2014-08-22 22:53:55Z ggregory $ - */ -public class EncoderException extends Exception { - - /** - * Declares the Serial Version Uid. - * - * @see Always Declare Serial Version Uid - */ - private static final long serialVersionUID = 1L; - - /** - * Constructs a new exception with null as its detail message. The cause is not initialized, and may - * subsequently be initialized by a call to {@link #initCause}. - * - * @since 1.4 - */ - public EncoderException() { - super(); - } - - /** - * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently - * be initialized by a call to {@link #initCause}. - * - * @param message - * a useful message relating to the encoder specific error. - */ - public EncoderException(final String message) { - super(message); - } - - /** - * Constructs a new exception with the specified detail message and cause. - * - *

- * Note that the detail message associated with cause is not automatically incorporated into this - * exception's detail message. - *

- * - * @param message - * The detail message which is saved for later retrieval by the {@link #getMessage()} method. - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A null - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public EncoderException(final String message, final Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new exception with the specified cause and a detail message of (cause==null ? - * null : cause.toString()) (which typically contains the class and detail message of cause). - * This constructor is useful for exceptions that are little more than wrappers for other throwables. - * - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A null - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public EncoderException(final Throwable cause) { - super(cause); - } -} diff --git a/app/src/main/java/biweekly/util/org/apache/commons/codec/binary/Base64.java b/app/src/main/java/biweekly/util/org/apache/commons/codec/binary/Base64.java deleted file mode 100644 index c79909f258..0000000000 --- a/app/src/main/java/biweekly/util/org/apache/commons/codec/binary/Base64.java +++ /dev/null @@ -1,815 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.org.apache.commons.codec.binary; - -import java.math.BigInteger; - -/** - * Provides Base64 encoding and decoding as defined by RFC 2045. - * - *

- * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose - * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. - *

- *

- * The class can be parameterized in the following manner with various constructors: - *

- *
    - *
  • URL-safe mode: Default off.
  • - *
  • Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of - * 4 in the encoded data. - *
  • Line separator: Default is CRLF ("\r\n")
  • - *
- *

- * The URL-safe parameter is only applied to encode operations. Decoding seamlessly handles both modes. - *

- *

- * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only - * encode/decode character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, - * UTF-8, etc). - *

- *

- * This class is thread-safe. - *

- *

- * biweekly integration note: Minor modifications were made to this class so that it could be - * incorporated into the biweekly code base. Defining the Apache Commons Codec library as a project dependency causes - * an issue with Android devices, which is why parts of its source code have been directly incorporated into the - * biweekly code base. - *

- * - * @see RFC 2045 - * @since 1.0 - * @version $Id: Base64.java 1635986 2014-11-01 16:27:52Z tn $ - */ -public class Base64 extends BaseNCodec { - - /** - * BASE32 characters are 6 bits in length. - * They are formed by taking a block of 3 octets to form a 24-bit string, - * which is converted into 4 BASE64 characters. - */ - private static final int BITS_PER_ENCODED_BYTE = 6; - private static final int BYTES_PER_UNENCODED_BLOCK = 3; - private static final int BYTES_PER_ENCODED_BLOCK = 4; - - /** - * Chunk separator per RFC 2045 section 2.1. - * - *

- * N.B. The next major release may break compatibility and make this field private. - *

- * - * @see RFC 2045 section 2.1 - */ - static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; - - /** - * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" - * equivalents as specified in Table 1 of RFC 2045. - * - * Thanks to "commons" project in ws.apache.org for this code. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - */ - private static final byte[] STANDARD_ENCODE_TABLE = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - - /** - * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / - * changed to - and _ to make the encoded Base64 results more URL-SAFE. - * This table is only used when the Base64's mode is set to URL-SAFE. - */ - private static final byte[] URL_SAFE_ENCODE_TABLE = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' - }; - - /** - * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified - * in Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 - * alphabet but fall within the bounds of the array are translated to -1. - * - * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both - * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit). - * - * Thanks to "commons" project in ws.apache.org for this code. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - */ - private static final byte[] DECODE_TABLE = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 - }; - - /** - * Base64 uses 6-bit fields. - */ - /** Mask used to extract 6 bits, used when encoding */ - private static final int MASK_6BITS = 0x3f; - - // The static final fields above are used for the original static byte[] methods on Base64. - // The private member fields below are used with the new streaming approach, which requires - // some state be preserved between calls of encode() and decode(). - - /** - * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able - * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch - * between the two modes. - */ - private final byte[] encodeTable; - - // Only one decode table currently; keep for consistency with Base32 code - private final byte[] decodeTable = DECODE_TABLE; - - /** - * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. - */ - private final byte[] lineSeparator; - - /** - * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. - * decodeSize = 3 + lineSeparator.length; - */ - private final int decodeSize; - - /** - * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. - * encodeSize = 4 + lineSeparator.length; - */ - private final int encodeSize; - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - *

- * When encoding the line length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE. - *

- * - *

- * When decoding all variants are supported. - *

- */ - public Base64() { - this(0); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode. - *

- * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. - *

- * - *

- * When decoding all variants are supported. - *

- * - * @param urlSafe - * if true, URL-safe encoding is used. In most cases this should be set to - * false. - * @since 1.4 - */ - public Base64(final boolean urlSafe) { - this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - *

- * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is - * STANDARD_ENCODE_TABLE. - *

- *

- * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. - *

- *

- * When decoding all variants are supported. - *

- * - * @param lineLength - * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of - * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when - * decoding. - * @since 1.4 - */ - public Base64(final int lineLength) { - this(lineLength, CHUNK_SEPARATOR); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - *

- * When encoding the line length and line separator are given in the constructor, and the encoding table is - * STANDARD_ENCODE_TABLE. - *

- *

- * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. - *

- *

- * When decoding all variants are supported. - *

- * - * @param lineLength - * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of - * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when - * decoding. - * @param lineSeparator - * Each line of encoded data will end with this sequence of bytes. - * @throws IllegalArgumentException - * Thrown when the provided lineSeparator included some base64 characters. - * @since 1.4 - */ - public Base64(final int lineLength, final byte[] lineSeparator) { - this(lineLength, lineSeparator, false); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - *

- * When encoding the line length and line separator are given in the constructor, and the encoding table is - * STANDARD_ENCODE_TABLE. - *

- *

- * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. - *

- *

- * When decoding all variants are supported. - *

- * - * @param lineLength - * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of - * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when - * decoding. - * @param lineSeparator - * Each line of encoded data will end with this sequence of bytes. - * @param urlSafe - * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode - * operations. Decoding seamlessly handles both modes. - * Note: no padding is added when using the URL-safe alphabet. - * @throws IllegalArgumentException - * The provided lineSeparator included some base64 characters. That's not going to work! - * @since 1.4 - */ - public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe) { - super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, - lineLength, - lineSeparator == null ? 0 : lineSeparator.length); - // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0 - // @see test case Base64Test.testConstructors() - if (lineSeparator != null) { - if (containsAlphabetOrPad(lineSeparator)) { - final String sep = newStringUtf8(lineSeparator); - throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]"); - } - if (lineLength > 0){ // null line-sep forces no chunking rather than throwing IAE - this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length; - this.lineSeparator = new byte[lineSeparator.length]; - System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); - } else { - this.encodeSize = BYTES_PER_ENCODED_BLOCK; - this.lineSeparator = null; - } - } else { - this.encodeSize = BYTES_PER_ENCODED_BLOCK; - this.lineSeparator = null; - } - this.decodeSize = this.encodeSize - 1; - this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE; - } - - /** - * Returns our current encode mode. True if we're URL-SAFE, false otherwise. - * - * @return true if we're in URL-SAFE mode, false otherwise. - * @since 1.4 - */ - public boolean isUrlSafe() { - return this.encodeTable == URL_SAFE_ENCODE_TABLE; - } - - /** - *

- * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with - * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, to flush last - * remaining bytes (if not multiple of 3). - *

- *

Note: no padding is added when encoding using the URL-safe alphabet.

- *

- * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - *

- * - * @param in - * byte[] array of binary data to base64 encode. - * @param inPos - * Position to start reading data from. - * @param inAvail - * Amount of bytes available from input for encoding. - * @param context - * the context to be used - */ - @Override - void encode(final byte[] in, int inPos, final int inAvail, final Context context) { - if (context.eof) { - return; - } - // inAvail < 0 is how we're informed of EOF in the underlying data we're - // encoding. - if (inAvail < 0) { - context.eof = true; - if (0 == context.modulus && lineLength == 0) { - return; // no leftovers to process and not using chunking - } - final byte[] buffer = ensureBufferSize(encodeSize, context); - final int savedPos = context.pos; - switch (context.modulus) { // 0-2 - case 0 : // nothing to do here - break; - case 1 : // 8 bits = 6 + 2 - // top 6 bits: - buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 2) & MASK_6BITS]; - // remaining 2: - buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 4) & MASK_6BITS]; - // URL-SAFE skips the padding to further reduce size. - if (encodeTable == STANDARD_ENCODE_TABLE) { - buffer[context.pos++] = pad; - buffer[context.pos++] = pad; - } - break; - - case 2 : // 16 bits = 6 + 6 + 4 - buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 10) & MASK_6BITS]; - buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 4) & MASK_6BITS]; - buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 2) & MASK_6BITS]; - // URL-SAFE skips the padding to further reduce size. - if (encodeTable == STANDARD_ENCODE_TABLE) { - buffer[context.pos++] = pad; - } - break; - default: - throw new IllegalStateException("Impossible modulus "+context.modulus); - } - context.currentLinePos += context.pos - savedPos; // keep track of current line position - // if currentPos == 0 we are at the start of a line, so don't add CRLF - if (lineLength > 0 && context.currentLinePos > 0) { - System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length); - context.pos += lineSeparator.length; - } - } else { - for (int i = 0; i < inAvail; i++) { - final byte[] buffer = ensureBufferSize(encodeSize, context); - context.modulus = (context.modulus+1) % BYTES_PER_UNENCODED_BLOCK; - int b = in[inPos++]; - if (b < 0) { - b += 256; - } - context.ibitWorkArea = (context.ibitWorkArea << 8) + b; // BITS_PER_BYTE - if (0 == context.modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract - buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 18) & MASK_6BITS]; - buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 12) & MASK_6BITS]; - buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 6) & MASK_6BITS]; - buffer[context.pos++] = encodeTable[context.ibitWorkArea & MASK_6BITS]; - context.currentLinePos += BYTES_PER_ENCODED_BLOCK; - if (lineLength > 0 && lineLength <= context.currentLinePos) { - System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length); - context.pos += lineSeparator.length; - context.currentLinePos = 0; - } - } - } - } - } - - /** - *

- * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once - * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" - * call is not necessary when decoding, but it doesn't hurt, either. - *

- *

- * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are - * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, - * garbage-out philosophy: it will not check the provided data for validity. - *

- *

- * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - *

- * - * @param in - * byte[] array of ascii data to base64 decode. - * @param inPos - * Position to start reading data from. - * @param inAvail - * Amount of bytes available from input for encoding. - * @param context - * the context to be used - */ - @Override - void decode(final byte[] in, int inPos, final int inAvail, final Context context) { - if (context.eof) { - return; - } - if (inAvail < 0) { - context.eof = true; - } - for (int i = 0; i < inAvail; i++) { - final byte[] buffer = ensureBufferSize(decodeSize, context); - final byte b = in[inPos++]; - if (b == pad) { - // We're done. - context.eof = true; - break; - } else { - if (b >= 0 && b < DECODE_TABLE.length) { - final int result = DECODE_TABLE[b]; - if (result >= 0) { - context.modulus = (context.modulus+1) % BYTES_PER_ENCODED_BLOCK; - context.ibitWorkArea = (context.ibitWorkArea << BITS_PER_ENCODED_BYTE) + result; - if (context.modulus == 0) { - buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 16) & MASK_8BITS); - buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS); - buffer[context.pos++] = (byte) (context.ibitWorkArea & MASK_8BITS); - } - } - } - } - } - - // Two forms of EOF as far as base64 decoder is concerned: actual - // EOF (-1) and first time '=' character is encountered in stream. - // This approach makes the '=' padding characters completely optional. - if (context.eof && context.modulus != 0) { - final byte[] buffer = ensureBufferSize(decodeSize, context); - - // We have some spare bits remaining - // Output all whole multiples of 8 bits and ignore the rest - switch (context.modulus) { -// case 0 : // impossible, as excluded above - case 1 : // 6 bits - ignore entirely - // TODO not currently tested; perhaps it is impossible? - break; - case 2 : // 12 bits = 8 + 4 - context.ibitWorkArea = context.ibitWorkArea >> 4; // dump the extra 4 bits - buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS); - break; - case 3 : // 18 bits = 8 + 8 + 2 - context.ibitWorkArea = context.ibitWorkArea >> 2; // dump 2 bits - buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS); - buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS); - break; - default: - throw new IllegalStateException("Impossible modulus "+context.modulus); - } - } - } - - /** - * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the - * method treats whitespace as valid. - * - * @param arrayOctet - * byte array to test - * @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; - * false, otherwise - * @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0. - */ - @Deprecated - public static boolean isArrayByteBase64(final byte[] arrayOctet) { - return isBase64(arrayOctet); - } - - /** - * Returns whether or not the octet is in the base 64 alphabet. - * - * @param octet - * The value to test - * @return true if the value is defined in the the base 64 alphabet, false otherwise. - * @since 1.4 - */ - public static boolean isBase64(final byte octet) { - return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1); - } - - /** - * Tests a given String to see if it contains only valid characters within the Base64 alphabet. Currently the - * method treats whitespace as valid. - * - * @param base64 - * String to test - * @return true if all characters in the String are valid characters in the Base64 alphabet or if - * the String is empty; false, otherwise - * @since 1.5 - */ - public static boolean isBase64(final String base64) { - return isBase64(getBytesUtf8(base64)); - } - - /** - * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the - * method treats whitespace as valid. - * - * @param arrayOctet - * byte array to test - * @return true if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; - * false, otherwise - * @since 1.5 - */ - public static boolean isBase64(final byte[] arrayOctet) { - for (int i = 0; i < arrayOctet.length; i++) { - if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { - return false; - } - } - return true; - } - - /** - * Encodes binary data using the base64 algorithm but does not chunk the output. - * - * @param binaryData - * binary data to encode - * @return byte[] containing Base64 characters in their UTF-8 representation. - */ - public static byte[] encodeBase64(final byte[] binaryData) { - return encodeBase64(binaryData, false); - } - - /** - * Encodes binary data using the base64 algorithm but does not chunk the output. - * - * NOTE: We changed the behaviour of this method from multi-line chunking (commons-codec-1.4) to - * single-line non-chunking (commons-codec-1.5). - * - * @param binaryData - * binary data to encode - * @return String containing Base64 characters. - * @since 1.4 (NOTE: 1.4 chunked the output, whereas 1.5 does not). - */ - public static String encodeBase64String(final byte[] binaryData) { - return newStringUtf8(encodeBase64(binaryData, false)); - } - - /** - * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The - * url-safe variation emits - and _ instead of + and / characters. - * Note: no padding is added. - * @param binaryData - * binary data to encode - * @return byte[] containing Base64 characters in their UTF-8 representation. - * @since 1.4 - */ - public static byte[] encodeBase64URLSafe(final byte[] binaryData) { - return encodeBase64(binaryData, false, true); - } - - /** - * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The - * url-safe variation emits - and _ instead of + and / characters. - * Note: no padding is added. - * @param binaryData - * binary data to encode - * @return String containing Base64 characters - * @since 1.4 - */ - public static String encodeBase64URLSafeString(final byte[] binaryData) { - return newStringUtf8(encodeBase64(binaryData, false, true)); - } - - /** - * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks - * - * @param binaryData - * binary data to encode - * @return Base64 characters chunked in 76 character blocks - */ - public static byte[] encodeBase64Chunked(final byte[] binaryData) { - return encodeBase64(binaryData, true); - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if true this encoder will chunk the base64 output into 76 character blocks - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} - */ - public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked) { - return encodeBase64(binaryData, isChunked, false); - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if true this encoder will chunk the base64 output into 76 character blocks - * @param urlSafe - * if true this encoder will emit - and _ instead of the usual + and / characters. - * Note: no padding is added when encoding using the URL-safe alphabet. - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} - * @since 1.4 - */ - public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) { - return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE); - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if true this encoder will chunk the base64 output into 76 character blocks - * @param urlSafe - * if true this encoder will emit - and _ instead of the usual + and / characters. - * Note: no padding is added when encoding using the URL-safe alphabet. - * @param maxResultSize - * The maximum result size to accept. - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than maxResultSize - * @since 1.4 - */ - public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, - final boolean urlSafe, final int maxResultSize) { - if (binaryData == null || binaryData.length == 0) { - return binaryData; - } - - // Create this so can use the super-class method - // Also ensures that the same roundings are performed by the ctor and the code - final Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe); - final long len = b64.getEncodedLength(binaryData); - if (len > maxResultSize) { - throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + - len + - ") than the specified maximum size of " + - maxResultSize); - } - - return b64.encode(binaryData); - } - - /** - * Decodes a Base64 String into octets. - *

- * Note: this method seamlessly handles data encoded in URL-safe or normal mode. - *

- * - * @param base64String - * String containing Base64 data - * @return Array containing decoded data. - * @since 1.4 - */ - public static byte[] decodeBase64(final String base64String) { - return new Base64().decode(base64String); - } - - /** - * Decodes Base64 data into octets. - *

- * Note: this method seamlessly handles data encoded in URL-safe or normal mode. - *

- * - * @param base64Data - * Byte array containing Base64 data - * @return Array containing decoded data. - */ - public static byte[] decodeBase64(final byte[] base64Data) { - return new Base64().decode(base64Data); - } - - // Implementation of the Encoder Interface - - // Implementation of integer encoding used for crypto - /** - * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature. - * - * @param pArray - * a byte array containing base64 character data - * @return A BigInteger - * @since 1.4 - */ - public static BigInteger decodeInteger(final byte[] pArray) { - return new BigInteger(1, decodeBase64(pArray)); - } - - /** - * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature. - * - * @param bigInt - * a BigInteger - * @return A byte array containing base64 character data - * @throws NullPointerException - * if null is passed in - * @since 1.4 - */ - public static byte[] encodeInteger(final BigInteger bigInt) { - if (bigInt == null) { - throw new NullPointerException("encodeInteger called with null parameter"); - } - return encodeBase64(toIntegerBytes(bigInt), false); - } - - /** - * Returns a byte-array representation of a BigInteger without sign bit. - * - * @param bigInt - * BigInteger to be converted - * @return a byte array representation of the BigInteger parameter - */ - static byte[] toIntegerBytes(final BigInteger bigInt) { - int bitlen = bigInt.bitLength(); - // round bitlen - bitlen = ((bitlen + 7) >> 3) << 3; - final byte[] bigBytes = bigInt.toByteArray(); - - if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { - return bigBytes; - } - // set up params for copying everything but sign bit - int startSrc = 0; - int len = bigBytes.length; - - // if bigInt is exactly byte-aligned, just skip signbit in copy - if ((bigInt.bitLength() % 8) == 0) { - startSrc = 1; - len--; - } - final int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec - final byte[] resizedBytes = new byte[bitlen / 8]; - System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); - return resizedBytes; - } - - /** - * Returns whether or not the octet is in the Base64 alphabet. - * - * @param octet - * The value to test - * @return true if the value is defined in the the Base64 alphabet false otherwise. - */ - @Override - protected boolean isInAlphabet(final byte octet) { - return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1; - } - -} diff --git a/app/src/main/java/biweekly/util/org/apache/commons/codec/binary/BaseNCodec.java b/app/src/main/java/biweekly/util/org/apache/commons/codec/binary/BaseNCodec.java deleted file mode 100644 index da4e2b6108..0000000000 --- a/app/src/main/java/biweekly/util/org/apache/commons/codec/binary/BaseNCodec.java +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -/* - Copyright (c) 2013-2023, Michael Angstadt - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package biweekly.util.org.apache.commons.codec.binary; - -import java.io.UnsupportedEncodingException; -import java.util.Arrays; - -import biweekly.util.org.apache.commons.codec.DecoderException; -import biweekly.util.org.apache.commons.codec.EncoderException; - -/** - * Abstract superclass for Base-N encoders and decoders. - * - *

- * This class is thread-safe. - *

- *

- * biweekly integration note: Minor modifications were made to this class so that it could be - * incorporated into the biweekly code base. Defining the Apache Commons Codec library as a project dependency causes - * an issue with Android devices, which is why parts of its source code have been directly incorporated into the - * biweekly code base. - *

- * - * @version $Id: BaseNCodec.java 1634404 2014-10-26 23:06:10Z ggregory $ - */ -public abstract class BaseNCodec { - - /** - * Holds thread context so classes can be thread-safe. - * - * This class is not itself thread-safe; each thread must allocate its own copy. - * - * @since 1.7 - */ - static class Context { - - /** - * Place holder for the bytes we're dealing with for our based logic. - * Bitwise operations store and extract the encoding or decoding from this variable. - */ - int ibitWorkArea; - - /** - * Place holder for the bytes we're dealing with for our based logic. - * Bitwise operations store and extract the encoding or decoding from this variable. - */ - long lbitWorkArea; - - /** - * Buffer for streaming. - */ - byte[] buffer; - - /** - * Position where next character should be written in the buffer. - */ - int pos; - - /** - * Position where next character should be read from the buffer. - */ - int readPos; - - /** - * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless, - * and must be thrown away. - */ - boolean eof; - - /** - * Variable tracks how many characters have been written to the current line. Only used when encoding. We use - * it to make sure each encoded line never goes beyond lineLength (if lineLength > 0). - */ - int currentLinePos; - - /** - * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding. This - * variable helps track that. - */ - int modulus; - - Context() { - } - - /** - * Returns a String useful for debugging (especially within a debugger.) - * - * @return a String useful for debugging. - */ - @SuppressWarnings("boxing") // OK to ignore boxing here - @Override - public String toString() { - return String.format("%s[buffer=%s, currentLinePos=%s, eof=%s, ibitWorkArea=%s, lbitWorkArea=%s, " + - "modulus=%s, pos=%s, readPos=%s]", this.getClass().getSimpleName(), Arrays.toString(buffer), - currentLinePos, eof, ibitWorkArea, lbitWorkArea, modulus, pos, readPos); - } - } - - /** - * EOF - * - * @since 1.7 - */ - static final int EOF = -1; - - /** - * MIME chunk size per RFC 2045 section 6.8. - * - *

- * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any - * equal signs. - *

- * - * @see RFC 2045 section 6.8 - */ - public static final int MIME_CHUNK_SIZE = 76; - - /** - * PEM chunk size per RFC 1421 section 4.3.2.4. - * - *

- * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any - * equal signs. - *

- * - * @see RFC 1421 section 4.3.2.4 - */ - public static final int PEM_CHUNK_SIZE = 64; - - private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2; - - /** - * Defines the default buffer size - currently {@value} - * - must be large enough for at least one encoded block+separator - */ - private static final int DEFAULT_BUFFER_SIZE = 8192; - - /** Mask used to extract 8 bits, used in decoding bytes */ - protected static final int MASK_8BITS = 0xff; - - /** - * Byte used to pad output. - */ - protected static final byte PAD_DEFAULT = '='; // Allow static access to default - - /** - * @deprecated Use {@link #pad}. Will be removed in 2.0. - */ - @Deprecated - protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later - - protected final byte pad; // instance variable just in case it needs to vary later - - /** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */ - private final int unencodedBlockSize; - - /** Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32 */ - private final int encodedBlockSize; - - /** - * Chunksize for encoding. Not used when decoding. - * A value of zero or less implies no chunking of the encoded data. - * Rounded down to nearest multiple of encodedBlockSize. - */ - protected final int lineLength; - - /** - * Size of chunk separator. Not used unless {@link #lineLength} > 0. - */ - private final int chunkSeparatorLength; - - /** - * Note lineLength is rounded down to the nearest multiple of {@link #encodedBlockSize} - * If chunkSeparatorLength is zero, then chunking is disabled. - * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) - * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) - * @param lineLength if > 0, use chunking with a length lineLength - * @param chunkSeparatorLength the chunk separator length, if relevant - */ - protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, - final int lineLength, final int chunkSeparatorLength) { - this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, PAD_DEFAULT); - } - - /** - * Note lineLength is rounded down to the nearest multiple of {@link #encodedBlockSize} - * If chunkSeparatorLength is zero, then chunking is disabled. - * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) - * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) - * @param lineLength if > 0, use chunking with a length lineLength - * @param chunkSeparatorLength the chunk separator length, if relevant - * @param pad byte used as padding byte. - */ - protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, - final int lineLength, final int chunkSeparatorLength, final byte pad) { - this.unencodedBlockSize = unencodedBlockSize; - this.encodedBlockSize = encodedBlockSize; - final boolean useChunking = lineLength > 0 && chunkSeparatorLength > 0; - this.lineLength = useChunking ? (lineLength / encodedBlockSize) * encodedBlockSize : 0; - this.chunkSeparatorLength = chunkSeparatorLength; - - this.pad = pad; - } - - /** - * Returns true if this object has buffered data for reading. - * - * @param context the context to be used - * @return true if there is data still available for reading. - */ - boolean hasData(final Context context) { // package protected for access from I/O streams - return context.buffer != null; - } - - /** - * Returns the amount of buffered data available for reading. - * - * @param context the context to be used - * @return The amount of buffered data available for reading. - */ - int available(final Context context) { // package protected for access from I/O streams - return context.buffer != null ? context.pos - context.readPos : 0; - } - - /** - * Get the default buffer size. Can be overridden. - * - * @return {@link #DEFAULT_BUFFER_SIZE} - */ - protected int getDefaultBufferSize() { - return DEFAULT_BUFFER_SIZE; - } - - /** - * Increases our buffer by the {@link #DEFAULT_BUFFER_RESIZE_FACTOR}. - * @param context the context to be used - */ - private byte[] resizeBuffer(final Context context) { - if (context.buffer == null) { - context.buffer = new byte[getDefaultBufferSize()]; - context.pos = 0; - context.readPos = 0; - } else { - final byte[] b = new byte[context.buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR]; - System.arraycopy(context.buffer, 0, b, 0, context.buffer.length); - context.buffer = b; - } - return context.buffer; - } - - /** - * Ensure that the buffer has room for size bytes - * - * @param size minimum spare space required - * @param context the context to be used - * @return the buffer - */ - protected byte[] ensureBufferSize(final int size, final Context context){ - if ((context.buffer == null) || (context.buffer.length < context.pos + size)){ - return resizeBuffer(context); - } - return context.buffer; - } - - /** - * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail - * bytes. Returns how many bytes were actually extracted. - *

- * Package protected for access from I/O streams. - * - * @param b - * byte[] array to extract the buffered data into. - * @param bPos - * position in byte[] array to start extraction at. - * @param bAvail - * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available). - * @param context - * the context to be used - * @return The number of bytes successfully extracted into the provided byte[] array. - */ - int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) { - if (context.buffer != null) { - final int len = Math.min(available(context), bAvail); - System.arraycopy(context.buffer, context.readPos, b, bPos, len); - context.readPos += len; - if (context.readPos >= context.pos) { - context.buffer = null; // so hasData() will return false, and this method can return -1 - } - return len; - } - return context.eof ? EOF : 0; - } - - /** - * Checks if a byte value is whitespace or not. - * Whitespace is taken to mean: space, tab, CR, LF - * @param byteToCheck - * the byte to check - * @return true if byte is whitespace, false otherwise - */ - protected static boolean isWhiteSpace(final byte byteToCheck) { - switch (byteToCheck) { - case ' ' : - case '\n' : - case '\r' : - case '\t' : - return true; - default : - return false; - } - } - - /** - * Encodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of - * the Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[]. - * - * @param obj - * Object to encode - * @return An object (of type byte[]) containing the Base-N encoded data which corresponds to the byte[] supplied. - * @throws EncoderException - * if the parameter supplied is not of type byte[] - */ - public Object encode(final Object obj) throws EncoderException { - if (!(obj instanceof byte[])) { - throw new EncoderException("Parameter supplied to Base-N encode is not a byte[]"); - } - return encode((byte[]) obj); - } - - /** - * Encodes a byte[] containing binary data, into a String containing characters in the Base-N alphabet. - * Uses UTF8 encoding. - * - * @param pArray - * a byte array containing binary data - * @return A String containing only Base-N character data - */ - public String encodeToString(final byte[] pArray) { - return newStringUtf8(encode(pArray)); - } - - /** - * Encodes a byte[] containing binary data, into a String containing characters in the appropriate alphabet. - * Uses UTF8 encoding. - * - * @param pArray a byte array containing binary data - * @return String containing only character data in the appropriate alphabet. - */ - public String encodeAsString(final byte[] pArray){ - return newStringUtf8(encode(pArray)); - } - - /** - * Decodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of - * the Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String. - * - * @param obj - * Object to decode - * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String - * supplied. - * @throws DecoderException - * if the parameter supplied is not of type byte[] - */ - public Object decode(final Object obj) throws DecoderException { - if (obj instanceof byte[]) { - return decode((byte[]) obj); - } else if (obj instanceof String) { - return decode((String) obj); - } else { - throw new DecoderException("Parameter supplied to Base-N decode is not a byte[] or a String"); - } - } - - /** - * Decodes a String containing characters in the Base-N alphabet. - * - * @param pArray - * A String containing Base-N character data - * @return a byte array containing binary data - */ - public byte[] decode(final String pArray) { - return decode(getBytesUtf8(pArray)); - } - - /** - * Decodes a byte[] containing characters in the Base-N alphabet. - * - * @param pArray - * A byte array containing Base-N character data - * @return a byte array containing binary data - */ - public byte[] decode(final byte[] pArray) { - if (pArray == null || pArray.length == 0) { - return pArray; - } - final Context context = new Context(); - decode(pArray, 0, pArray.length, context); - decode(pArray, 0, EOF, context); // Notify decoder of EOF. - final byte[] result = new byte[context.pos]; - readResults(result, 0, result.length, context); - return result; - } - - /** - * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet. - * - * @param pArray - * a byte array containing binary data - * @return A byte array containing only the basen alphabetic character data - */ - public byte[] encode(final byte[] pArray) { - if (pArray == null || pArray.length == 0) { - return pArray; - } - final Context context = new Context(); - encode(pArray, 0, pArray.length, context); - encode(pArray, 0, EOF, context); // Notify encoder of EOF. - final byte[] buf = new byte[context.pos - context.readPos]; - readResults(buf, 0, buf.length, context); - return buf; - } - - // package protected for access from I/O streams - abstract void encode(byte[] pArray, int i, int length, Context context); - - // package protected for access from I/O streams - abstract void decode(byte[] pArray, int i, int length, Context context); - - /** - * Returns whether or not the octet is in the current alphabet. - * Does not allow whitespace or pad. - * - * @param value The value to test - * - * @return true if the value is defined in the current alphabet, false otherwise. - */ - protected abstract boolean isInAlphabet(byte value); - - /** - * Tests a given byte array to see if it contains only valid characters within the alphabet. - * The method optionally treats whitespace and pad as valid. - * - * @param arrayOctet byte array to test - * @param allowWSPad if true, then whitespace and PAD are also allowed - * - * @return true if all bytes are valid characters in the alphabet or if the byte array is empty; - * false, otherwise - */ - public boolean isInAlphabet(final byte[] arrayOctet, final boolean allowWSPad) { - for (int i = 0; i < arrayOctet.length; i++) { - if (!isInAlphabet(arrayOctet[i]) && - (!allowWSPad || (arrayOctet[i] != pad) && !isWhiteSpace(arrayOctet[i]))) { - return false; - } - } - return true; - } - - /** - * Tests a given String to see if it contains only valid characters within the alphabet. - * The method treats whitespace and PAD as valid. - * - * @param basen String to test - * @return true if all characters in the String are valid characters in the alphabet or if - * the String is empty; false, otherwise - * @see #isInAlphabet(byte[], boolean) - */ - public boolean isInAlphabet(final String basen) { - return isInAlphabet(getBytesUtf8(basen), true); - } - - /** - * Tests a given byte array to see if it contains any characters within the alphabet or PAD. - * - * Intended for use in checking line-ending arrays - * - * @param arrayOctet - * byte array to test - * @return true if any byte is a valid character in the alphabet or PAD; false otherwise - */ - protected boolean containsAlphabetOrPad(final byte[] arrayOctet) { - if (arrayOctet == null) { - return false; - } - for (final byte element : arrayOctet) { - if (pad == element || isInAlphabet(element)) { - return true; - } - } - return false; - } - - /** - * Calculates the amount of space needed to encode the supplied array. - * - * @param pArray byte[] array which will later be encoded - * - * @return amount of space needed to encoded the supplied array. - * Returns a long since a max-len array will require > Integer.MAX_VALUE - */ - public long getEncodedLength(final byte[] pArray) { - // Calculate non-chunked size - rounded up to allow for padding - // cast to long is needed to avoid possibility of overflow - long len = ((pArray.length + unencodedBlockSize-1) / unencodedBlockSize) * (long) encodedBlockSize; - if (lineLength > 0) { // We're using chunking - // Round up to nearest multiple - len += ((len + lineLength-1) / lineLength) * chunkSeparatorLength; - } - return len; - } - - /** - * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte - * array. - * - * @param string - * the String to encode, may be null - * @return encoded bytes, or null if the input string was null - */ - protected static byte[] getBytesUtf8(final String string) { - if (string == null) { - return null; - } - - try { - return string.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - //should never be thrown because all JVMs must support UTF-8 - throw new RuntimeException(e); - } - } - - /** - * Constructs a new String by decoding the specified array of bytes using the UTF-8 charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new String decoded from the specified array of bytes using the UTF-8 charset, - * or null if the input byte array was null. - */ - protected static String newStringUtf8(final byte[] bytes) { - if (bytes == null) { - return null; - } - - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException e) { - //should never be thrown because all JVMs must support UTF-8 - throw new RuntimeException(e); - } - } -} diff --git a/app/src/main/java/biweekly/util/package-info.java b/app/src/main/java/biweekly/util/package-info.java deleted file mode 100644 index ecc8d86b78..0000000000 --- a/app/src/main/java/biweekly/util/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains miscellaneous utility classes. - */ -package biweekly.util; \ No newline at end of file diff --git a/metadata/en-US/changelogs/2147.txt b/metadata/en-US/changelogs/2147.txt index 165d7e71a1..7123c0ea67 100644 --- a/metadata/en-US/changelogs/2147.txt +++ b/metadata/en-US/changelogs/2147.txt @@ -12,6 +12,7 @@ Next version * Replaced javadns * Added account/identity options to enforce DNSSEC and/or DANE, see the FAQ * Small improvements and minor bug fixes +* Updated biweekly * Updated translations Preview/test versions are available here.