diff --git a/webcal/src/main/java/com/onixbyte/icalendar/CalendarUtil.java b/webcal/src/main/java/com/onixbyte/icalendar/CalendarUtil.java new file mode 100644 index 0000000..a94d8c2 --- /dev/null +++ b/webcal/src/main/java/com/onixbyte/icalendar/CalendarUtil.java @@ -0,0 +1,15 @@ +package com.onixbyte.icalendar; + +/** + * CalendarUtil + * + * @author Zihlu WANG + */ +public final class CalendarUtil { + + private CalendarUtil() { + } + + + +} diff --git a/webcal/src/main/java/com/onixbyte/icalendar/component/Calendar.java b/webcal/src/main/java/com/onixbyte/icalendar/component/Calendar.java new file mode 100644 index 0000000..40e6eed --- /dev/null +++ b/webcal/src/main/java/com/onixbyte/icalendar/component/Calendar.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2023-2024 OnixByte. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.onixbyte.icalendar.component; + +import com.onixbyte.icalendar.property.calendar.CalendarScale; +import com.onixbyte.icalendar.property.calendar.Method; +import com.onixbyte.icalendar.property.calendar.ProductIdentifier; +import com.onixbyte.icalendar.property.calendar.Version; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * {@code WebCalendar} class represents a web calendar in iCalendar format. + *
+ * It allows users to create and customise calendar components and events and + * generate an iCalendar string containing all the calendar information. + *
+ * Usage Example: + *
+ * WebCalendar calendar = new WebCalendar()
+ * .setName("My Web Calendar")
+ * .setCompanyName("CodeCrafters Inc.")
+ * .setProductName("WebCal")
+ * .setDomainName("codecrafters.org.cn")
+ * .setMethod("PUBLISH")
+ * .addEvent(event1)
+ * .addEvent(event2);
+ * String iCalendarString = calendar.resolve();
+ *
+ *
+ * The {@code WebCalendar} class is designed to generate an iCalendar string
+ * conforming to the iCalendar specification, which can be used to share
+ * calendar data with other calendar applications or services.
+ *
+ * @author Zihlu Wang
+ * @version 1.1.0
+ * @since 1.0.0
+ */
+public final class Calendar {
+
+ private static final String COMPONENT_NAME = "VCALENDAR";
+
+ /**
+ * This property are OPTIONAL, but MUST NOT occur more than once.
+ */
+ private CalendarScale scale;
+
+ /**
+ * This property are OPTIONAL, but MUST NOT occur more than once.
+ */
+ private Method method;
+
+ /**
+ * This property are REQUIRED, but MUST NOT occur more than once.
+ */
+ private ProductIdentifier productIdentifier;
+
+ /**
+ * This property are REQUIRED, but MUST NOT occur more than once.
+ */
+ private final Version version = Version.VERSION_2_0;
+
+ private String calendarName;
+
+ private final List
+ * Subclasses of {@code WebCalendarNode} should implement the {@link #resolve()} method to generate the corresponding iCalendar content for the specific calendar component or event.
+ *
+ * @author Zihlu Wang
+ * @version 1.1.0
+ * @since 1.0.0
+ */
+public abstract class CalendarComponent {
+
+ public abstract String resolve();
+
+}
+
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/component/Event.java b/webcal/src/main/java/com/onixbyte/icalendar/component/Event.java
new file mode 100644
index 0000000..3ef6848
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/component/Event.java
@@ -0,0 +1,23 @@
+package com.onixbyte.icalendar.component;
+
+import com.onixbyte.icalendar.property.component.DateTimeStamp;
+import com.onixbyte.icalendar.property.component.UniqueIdentifier;
+
+/**
+ * Event
+ *
+ * @author Zihlu WANG
+ */
+public class Event extends CalendarComponent {
+
+ private DateTimeStamp dtStamp;
+
+ private UniqueIdentifier uid;
+
+
+
+ @Override
+ public String resolve() {
+ return "";
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/webcal/config/Formatters.java b/webcal/src/main/java/com/onixbyte/icalendar/config/Formatters.java
similarity index 97%
rename from webcal/src/main/java/com/onixbyte/webcal/config/Formatters.java
rename to webcal/src/main/java/com/onixbyte/icalendar/config/Formatters.java
index 89c1d31..4668723 100644
--- a/webcal/src/main/java/com/onixbyte/webcal/config/Formatters.java
+++ b/webcal/src/main/java/com/onixbyte/icalendar/config/Formatters.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package com.onixbyte.webcal.config;
+package com.onixbyte.icalendar.config;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
diff --git a/webcal/src/main/java/com/onixbyte/webcal/config/package-info.java b/webcal/src/main/java/com/onixbyte/icalendar/config/package-info.java
similarity index 90%
rename from webcal/src/main/java/com/onixbyte/webcal/config/package-info.java
rename to webcal/src/main/java/com/onixbyte/icalendar/config/package-info.java
index de753b5..f02aab7 100644
--- a/webcal/src/main/java/com/onixbyte/webcal/config/package-info.java
+++ b/webcal/src/main/java/com/onixbyte/icalendar/config/package-info.java
@@ -23,11 +23,11 @@
* The classes in this package include:
+ * The property can be specified once in a {@link CalendarEvent CalEvent}, {@link
+ * com.onixbyte.icalendar.impl.CalTodo CalTodo}, or {@link com.onixbyte.icalendar.impl.CalJournal CalJournal}
+ * calendar properties.
+ */
+public enum Classification {
+
+ /**
+ * Public events mean that anyone can view and access their detailed information. These events are typically used
+ * in public calendars such as holiday calendars or company-wide event calendars. For public events, anyone with
+ * access to the calendar can see all the event details.
+ */
+ PUBLIC,
+ /**
+ * Private events mean that only invited or specifically authorized individuals can view and access their detailed
+ * information. Private events are visible to the owner of the calendar but not to others. This classification is
+ * commonly used for personal appointments, private meetings, etc.
+ */
+ PRIVATE,
+ /**
+ * Confidential events have detailed information that is not visible to anyone, including the owner of the calendar.
+ * Only individuals who have been granted specific permissions can access the detailed information of confidential
+ * events. This classification is typically used for sensitive business meetings, personal privacy matters, etc.
+ */
+ CONFIDENTIAL,
+ ;
+
+ @Override
+ public String toString() {
+ return name();
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/webcal/package-info.java b/webcal/src/main/java/com/onixbyte/icalendar/package-info.java
similarity index 84%
rename from webcal/src/main/java/com/onixbyte/webcal/package-info.java
rename to webcal/src/main/java/com/onixbyte/icalendar/package-info.java
index c15787d..3f87d13 100644
--- a/webcal/src/main/java/com/onixbyte/webcal/package-info.java
+++ b/webcal/src/main/java/com/onixbyte/icalendar/package-info.java
@@ -23,16 +23,16 @@
* The main classes and modules in this package include:
*
+ * The value MUST be specified in the UTC time format.
+ *
+ * This property is also useful to protocols such as [2447bis] that have inherent latency issues with the delivery of
+ * content. This property will assist in the proper sequencing of messages containing {@link
+ * com.onixbyte.icalendar.component.Calendar iCalendar} objects.
+ *
+ * In the case of an {@link com.onixbyte.icalendar.component.Calendar iCalendar} object that specifies a "{@link
+ * com.onixbyte.icalendar.property.calendar.Method Method}" property, this property differs from the "{@link
+ * DateTimeCreated CREATED}" and "{@link LastModified LAST-MODIFIED}" properties. These two properties are used to
+ * specify when the particular calendar data in the calendar store was created and last modified. This is different
+ * from when the {@link com.onixbyte.icalendar.component.Calendar iCalendar} object representation of the calendar
+ * service information was created or last modified.
+ *
+ * In the case of an {@link com.onixbyte.icalendar.component.Calendar iCalendar} object that specifies a "{@link
+ * com.onixbyte.icalendar.property.calendar.Method METHOD}" property, this property is equivalent to the "{@link
+ * LastModified LAST-MODIFIED}" property.
+ *
+ * @author Zihlu WANG
+ */
+public final class DateTimeStamp implements Prop {
+
+ private static final String PROPERTY_NAME = "DTSTAMP";
+
+ private LocalDateTime value;
+
+ public DateTimeStamp(LocalDateTime value) {
+ this.value = value;
+ }
+
+ public DateTimeStamp() {
+ this.value = LocalDateTime.now();
+ }
+
+ @Override
+ public String resolve() {
+ return PROPERTY_NAME + ":" + Formatters.getUtcDatetimeFormatter().format(value) + '\n';
+ }
+
+ public static class Builder {
+ private final DateTimeStamp dateTimeStamp = new DateTimeStamp();
+
+ public Builder dateTimeStamp(LocalDateTime dateTime) {
+ this.dateTimeStamp.value = dateTime;
+ return this;
+ }
+
+ public DateTimeStamp build() {
+ return dateTimeStamp;
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/component/LastModified.java b/webcal/src/main/java/com/onixbyte/icalendar/property/component/LastModified.java
new file mode 100644
index 0000000..12d7023
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/component/LastModified.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.component;
+
+/**
+ * LastModified
+ *
+ * @author Zihlu WANG
+ */
+public final class LastModified {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/component/UniqueIdentifier.java b/webcal/src/main/java/com/onixbyte/icalendar/property/component/UniqueIdentifier.java
new file mode 100644
index 0000000..e976a5b
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/component/UniqueIdentifier.java
@@ -0,0 +1,51 @@
+package com.onixbyte.icalendar.property.component;
+
+import com.onixbyte.icalendar.property.Prop;
+
+/**
+ * UniqueIdentifier
+ *
+ * @author Zihlu WANG
+ */
+public final class UniqueIdentifier implements Prop {
+
+ private String value;
+
+ private UniqueIdentifier() {
+ }
+
+ private void setValue(String value) {
+ this.value = value;
+ }
+
+ public static class Builder {
+ private final UniqueIdentifier uniqueIdentifier;
+
+ private Builder() {
+ this.uniqueIdentifier = new UniqueIdentifier();
+ }
+
+ public Builder uniqueIdentifier(String uniqueIdentifier) {
+ this.uniqueIdentifier.value = uniqueIdentifier;
+ return this;
+ }
+
+ public Builder uniqueIdentifier(String uniqueIdentifier, String domainName) {
+ this.uniqueIdentifier.value = uniqueIdentifier + "@" + domainName;
+ return this;
+ }
+
+ public UniqueIdentifier build() {
+ return uniqueIdentifier;
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public String resolve() {
+ return "uid:" + this.value + '\n';
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/AlarmTriggerRelationship.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/AlarmTriggerRelationship.java
new file mode 100644
index 0000000..4bb54a5
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/AlarmTriggerRelationship.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * AlarmTriggerRelationship
+ *
+ * @author Zihlu WANG
+ */
+public class AlarmTriggerRelationship {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/AlternateRepresentation.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/AlternateRepresentation.java
new file mode 100644
index 0000000..0af028d
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/AlternateRepresentation.java
@@ -0,0 +1,48 @@
+package com.onixbyte.icalendar.property.parameter;
+
+import com.onixbyte.icalendar.property.Prop;
+
+import java.net.URI;
+
+/**
+ * Alternate Text Representation specifies a URI that points to an alternate representation for a
+ * textual property value. A property specifying this parameter MUST also include a value that
+ * reflects the default representation of the text value. The URI parameter value MUST be specified
+ * in a quoted-string.
+ *
+ * Note: While there is no restriction imposed on the URI schemes allowed for this
+ * parameter, Content Identifier (CID) [RFC 2392], HTTP [RFC 2616], and HTTPS [RFC 2818] are the
+ * URI schemes most commonly used by current implementations.
+ *
+ * @author Zihlu Wang
+ */
+public final class AlternateRepresentation implements Prop {
+
+ private static final String PROPERTY_NAME = "ALTREP";
+
+ private URI uri;
+
+ private AlternateRepresentation() {
+ }
+
+ public AlternateRepresentation setUri(String uri) {
+ this.uri = URI.create(uri);
+ return this;
+ }
+
+ public AlternateRepresentation setUri(URI uri) {
+ this.uri = uri;
+ return this;
+ }
+
+ public static AlternateRepresentation createInstance(String uri) {
+ var instance = new AlternateRepresentation();
+ instance.uri = URI.create(uri);
+ return instance;
+ }
+
+ @Override
+ public String resolve() {
+ return PROPERTY_NAME + "=\"" + uri.toString() + "\"";
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/CalendarUserType.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/CalendarUserType.java
new file mode 100644
index 0000000..fe383ca
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/CalendarUserType.java
@@ -0,0 +1,44 @@
+package com.onixbyte.icalendar.property.parameter;
+
+import com.onixbyte.icalendar.property.Prop;
+
+/**
+ * CalendarUserType
+ *
+ * @author Zihlu WANG
+ */
+public enum CalendarUserType implements Prop {
+
+ /**
+ * An individual.
+ */
+ INDIVIDUAL,
+
+ /**
+ * A group of individuals.
+ */
+ GROUP,
+
+ /**
+ * A physical resource.
+ */
+ RESOURCE,
+
+ /**
+ * A room resource.
+ */
+ ROOM,
+
+ /**
+ * Otherwise not known.
+ */
+ UNKNOWN,
+ ;
+
+ private static final String PROPERTY_NAME = "CUTYPE";
+
+ @Override
+ public String resolve() {
+ return PROPERTY_NAME + "=" + this.name();
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/CommonName.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/CommonName.java
new file mode 100644
index 0000000..83abfff
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/CommonName.java
@@ -0,0 +1,35 @@
+package com.onixbyte.icalendar.property.parameter;
+
+import com.onixbyte.icalendar.property.Prop;
+
+/**
+ * Common Name can be specified on properties with a CAL-ADDRESS value type. The parameter
+ * specifies the common name to be associated with the calendar user specified by the property.
+ * The parameter value is text. The parameter value can be used for display text to be associated
+ * with the calendar address specified by the property.
+ *
+ * @author Zihlu Wang
+ */
+public final class CommonName implements Prop {
+
+ private String value;
+
+ private CommonName() {
+ }
+
+ public CommonName setValue(String value) {
+ this.value = value;
+ return this;
+ }
+
+ public static CommonName createInstance(String commonName) {
+ var instance = new CommonName();
+ instance.value = commonName;
+ return instance;
+ }
+
+ @Override
+ public String resolve() {
+ return "CN=\"" + this.value + "\"";
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Delegatee.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Delegatee.java
new file mode 100644
index 0000000..ed02b5a
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Delegatee.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * Delegate
+ *
+ * @author Zihlu WANG
+ */
+public class Delegatee {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Delegator.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Delegator.java
new file mode 100644
index 0000000..884b6f6
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Delegator.java
@@ -0,0 +1,47 @@
+package com.onixbyte.icalendar.property.parameter;
+
+import com.onixbyte.icalendar.property.Prop;
+
+import java.net.URI;
+
+/**
+ * Delegator
+ *
+ * @author Zihlu WANG
+ */
+public final class Delegator implements Prop {
+
+ private static final String PROPERTY_NAME = "DELEGATED-FROM";
+
+ private URI calendarUserAddress;
+
+ private Delegator() {
+ }
+
+ private Delegator setCalendarUserAddress(String calendarUserAddress) {
+ this.calendarUserAddress = URI.create(calendarUserAddress);
+ return this;
+ }
+
+ private Delegator setCalendarUserAddress(URI calendarUserAddress) {
+ this.calendarUserAddress = calendarUserAddress;
+ return this;
+ }
+
+ private static Delegator initialiseInstance() {
+ return new Delegator();
+ }
+
+ public static Delegator createInstance(String calendarUserAddress) {
+ return initialiseInstance().setCalendarUserAddress(calendarUserAddress);
+ }
+
+ public static Delegator createInstance(URI calendarUserAddress) {
+ return initialiseInstance().setCalendarUserAddress(calendarUserAddress);
+ }
+
+ @Override
+ public String resolve() {
+ return PROPERTY_NAME + "=\"" + calendarUserAddress + "\"";
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/DirectoryEntryReference.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/DirectoryEntryReference.java
new file mode 100644
index 0000000..fc1dbbf
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/DirectoryEntryReference.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * DirectoryEntryReference
+ *
+ * @author Zihlu WANG
+ */
+public class DirectoryEntryReference {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/FormatType.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/FormatType.java
new file mode 100644
index 0000000..adc3d7c
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/FormatType.java
@@ -0,0 +1,26 @@
+package com.onixbyte.icalendar.property.parameter;
+
+import com.onixbyte.icalendar.property.Prop;
+
+/**
+ * FormatType
+ *
+ * @author Zihlu WANG
+ */
+public enum FormatType implements Prop {
+
+ JSON("application/json"),
+
+ ;
+
+ private final String ianaRegistry;
+
+ FormatType(String ianaRegistry) {
+ this.ianaRegistry = ianaRegistry;
+ }
+
+ @Override
+ public String resolve() {
+ return "FMTTYPE:" + this.ianaRegistry;
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/FreeBusyTimeType.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/FreeBusyTimeType.java
new file mode 100644
index 0000000..1326ee2
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/FreeBusyTimeType.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * FreeBusyTimeType
+ *
+ * @author Zihlu WANG
+ */
+public class FreeBusyTimeType {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/GroupOrListMembership.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/GroupOrListMembership.java
new file mode 100644
index 0000000..3e2e956
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/GroupOrListMembership.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * GroupOrListMembership
+ *
+ * @author Zihlu WANG
+ */
+public class GroupOrListMembership {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/InlineEncoding.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/InlineEncoding.java
new file mode 100644
index 0000000..75f9902
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/InlineEncoding.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * InlineEncoding
+ *
+ * @author Zihlu WANG
+ */
+public class InlineEncoding {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Language.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Language.java
new file mode 100644
index 0000000..5b81408
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/Language.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * Language
+ *
+ * @author Zihlu WANG
+ */
+public class Language {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ParticipationRole.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ParticipationRole.java
new file mode 100644
index 0000000..e88aaf6
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ParticipationRole.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * ParticipationRole
+ *
+ * @author Zihlu WANG
+ */
+public class ParticipationRole {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ParticipationStatus.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ParticipationStatus.java
new file mode 100644
index 0000000..ce986f3
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ParticipationStatus.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * ParticipationStatus
+ *
+ * @author Zihlu WANG
+ */
+public class ParticipationStatus {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RecurrenceIdentifierRange.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RecurrenceIdentifierRange.java
new file mode 100644
index 0000000..bd6ae3f
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RecurrenceIdentifierRange.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * RecurrenceIdentifierRange
+ *
+ * @author Zihlu WANG
+ */
+public class RecurrenceIdentifierRange {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RelationshipType.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RelationshipType.java
new file mode 100644
index 0000000..c73a314
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RelationshipType.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * RelationshipType
+ *
+ * @author Zihlu WANG
+ */
+public class RelationshipType {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RsvpExpectation.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RsvpExpectation.java
new file mode 100644
index 0000000..b08b0c9
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/RsvpExpectation.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * RsvpExpectation
+ *
+ * @author Zihlu WANG
+ */
+public class RsvpExpectation {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/SentBy.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/SentBy.java
new file mode 100644
index 0000000..1105fcb
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/SentBy.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * SentBy
+ *
+ * @author Zihlu WANG
+ */
+public class SentBy {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/TimeZoneIdentifier.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/TimeZoneIdentifier.java
new file mode 100644
index 0000000..f35ad9a
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/TimeZoneIdentifier.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * TimeZoneIdentifier
+ *
+ * @author Zihlu WANG
+ */
+public class TimeZoneIdentifier {
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ValueDataType.java b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ValueDataType.java
new file mode 100644
index 0000000..b8d63fb
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/property/parameter/ValueDataType.java
@@ -0,0 +1,9 @@
+package com.onixbyte.icalendar.property.parameter;
+
+/**
+ * ValueDataType
+ *
+ * @author Zihlu WANG
+ */
+public class ValueDataType {
+}
diff --git a/webcal/src/main/java/com/onixbyte/webcal/WebCalendar.java b/webcal/src/main/java/com/onixbyte/webcal/WebCalendar.java
deleted file mode 100644
index 374b484..0000000
--- a/webcal/src/main/java/com/onixbyte/webcal/WebCalendar.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2023 CodeCraftersCN.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.onixbyte.webcal;
-
-import com.onixbyte.webcal.impl.WebCalendarEvent;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * {@code WebCalendar} class represents a web calendar in iCalendar format.
- *
- * It allows users to create and customise calendar components and events and
- * generate an iCalendar string containing all the calendar information.
- *
- * Usage Example:
- *
- * The {@code WebCalendar} class is designed to generate an iCalendar string
- * conforming to the iCalendar specification, which can be used to share
- * calendar data with other calendar applications or services.
- *
- * @author Zihlu Wang
- * @version 1.1.0
- * @since 1.0.0
- */
-public final class WebCalendar {
-
- /**
- * Constructor for WebCalendar class, initializes the list of calendar
- * components and events.
- */
- public WebCalendar() {
- this.nodes = new ArrayList<>();
- }
-
- /**
- * Set the name of the web calendar.
- *
- * @param name the name of the web calendar
- * @return the WebCalendar object
- */
- public WebCalendar setName(String name) {
- this.name = name;
- return this;
- }
-
- /**
- * Set the company name associated with the web calendar.
- *
- * @param companyName the company name
- * @return the WebCalendar object
- */
- public WebCalendar setCompanyName(String companyName) {
- this.companyName = companyName;
- return this;
- }
-
- /**
- * Set the domain name associated with the web calendar.
- *
- * @param domainName the domain name
- * @return the WebCalendar object
- */
- public WebCalendar setDomainName(String domainName) {
- this.domainName = domainName;
- return this;
- }
-
- /**
- * Set the product name of the web calendar.
- *
- * @param productName the product name
- * @return the WebCalendar object
- */
- public WebCalendar setProductName(String productName) {
- this.productName = productName;
- return this;
- }
-
- /**
- * Set the method for publishing the web calendar.
- *
- * @param method the publishing method
- * @return the WebCalendar object
- */
- public WebCalendar setMethod(String method) {
- this.method = method;
- return this;
- }
-
- /**
- * Add an node to the web calendar.
- *
- * @param node the calendar component or event to be added
- * @return the WebCalendar object
- */
- public WebCalendar addNode(WebCalendarNode node) {
- this.nodes.add(node);
- return this;
- }
-
- /**
- * Add an event to the web calendar.
- *
- * @param event the calendar component or event to be added
- * @return the WebCalendar object
- */
- public WebCalendar addEvent(WebCalendarEvent event) {
- this.nodes.add(event);
- return this;
- }
-
- /**
- * Generate and resolve the iCalendar string for the web calendar.
- *
- * @return the resolved iCalendar string
- */
- public String resolve() {
- var eventBuilder = new StringBuilder();
- if (!nodes.isEmpty()) {
- for (var node : nodes) {
- if (Objects.isNull(node.getDomainName()) || node.getDomainName().isBlank()) {
- node.setDomainName(this.domainName);
- }
-
- eventBuilder.append(node.resolve());
- }
- }
-
- return "BEGIN:" + TAG + "\n" +
- "PRODID:-//" + companyName + "//" + productName + "//EN\n" +
- "VERSION:" + version + "\n" +
- "X-WR-CALNAME:" + name + "\n" +
- eventBuilder + "\n" +
- "END:" + TAG;
- }
-
- /**
- * The {@code VCALENDAR} tag for iCalendar format
- */
- private final static String TAG = "VCALENDAR";
-
- /**
- * The name of this calendar.
- */
- private String name;
-
- /**
- * The company who produces this calendar.
- *
- * This property will be used in {@code PRODID}.
- */
- private String companyName;
-
- /**
- * The product name.
- *
- * This property will be used in {@code PRODID}
- */
- private String productName;
-
- /**
- * The producer's domain name.
- */
- private String domainName;
-
- /**
- * Scale of this calendar.
- */
- private final String scale = "GREGORIAN";
-
- /**
- * The method of this calendar.
- */
- private String method;
-
- /**
- * The version of this calendar.
- */
- private final String version = "2.0";
-
- /**
- * List of calendar components and events
- */
- private final List
- * Subclasses of {@code WebCalendarNode} should implement the {@link
- * #resolve()} method to generate the corresponding iCalendar content for the
- * specific calendar component or event.
- *
- * @author Zihlu Wang
- * @version 1.1.0
- * @since 1.0.0
- */
-public abstract class WebCalendarNode {
-
- // Common properties for all calendar components and events
- protected List
- * Calendar events or components can be classified as one of the following
- * levels:
- *
- * Indicates that the calendar content is public and can be freely
- * distributed.
- */
- PUBLIC,
-
- /**
- * Private classification level.
- *
- * Indicates that the calendar content is private and should not be shared
- * with others.
- */
- PRIVATE,
-
- /**
- * Confidential classification level.
- *
- * Indicates that the calendar content is confidential and should be kept
- * strictly private.
- */
- CONFIDENTIAL,
- ;
-
-}
diff --git a/webcal/src/main/java/com/onixbyte/webcal/impl/WebCalendarEvent.java b/webcal/src/main/java/com/onixbyte/webcal/impl/WebCalendarEvent.java
deleted file mode 100644
index de26f5e..0000000
--- a/webcal/src/main/java/com/onixbyte/webcal/impl/WebCalendarEvent.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2023 CodeCraftersCN.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.onixbyte.webcal.impl;
-
-import com.onixbyte.webcal.WebCalendarNode;
-import com.onixbyte.webcal.config.Classification;
-import com.onixbyte.webcal.config.Formatters;
-
-import java.text.MessageFormat;
-import java.time.Duration;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Optional;
-import java.util.UUID;
-
-/**
- * The {@code WebCalendarEvent} class represents an event in the web calendar.
- * It extends the abstract class WebCalendarNode and provides additional
- * methods to set properties specific to events.
- *
- * Users can use the methods in this class to add categories, set the
- * classification, add comments, descriptions, locations, set percent
- * complete, set priority, set summary, set start time, set end time, set
- * duration, set URL, set UID, and set timezone for the event. After setting
- * the properties, users can call the {@link #resolve()} method to generate the
- * corresponding iCalendar content for the event.
- *
- * @author Zihlu Wang
- * @version 1.1.0
- * @since 1.0.0
- */
-public final class WebCalendarEvent extends WebCalendarNode {
-
- /**
- * Add categories to the event.
- *
- * @param categories the categories to add
- * @return the WebCalendarEvent object
- */
- public WebCalendarEvent addCategories(String... categories) {
- this.categories.addAll(Arrays.asList(categories));
- return this;
- }
-
- /**
- * Add a collection of categories to the event.
- *
- * @param categories the collection of categories to add
- * @return the WebCalendarEvent object
- */
- public WebCalendarEvent addCategories(Collection
*
*
* @since 1.0.0
*/
-package com.onixbyte.webcal.config;
\ No newline at end of file
+package com.onixbyte.icalendar.config;
\ No newline at end of file
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/constant/CalendarUserType.java b/webcal/src/main/java/com/onixbyte/icalendar/constant/CalendarUserType.java
new file mode 100644
index 0000000..5b9b554
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/constant/CalendarUserType.java
@@ -0,0 +1,16 @@
+package com.onixbyte.icalendar.constant;
+
+public enum CalendarUserType {
+
+ INDIVIDUAL,
+ GROUP,
+ RESOURCE,
+ ROOM,
+ UNKNOWN,
+ ;
+
+ @Override
+ public String toString() {
+ return name();
+ }
+}
diff --git a/webcal/src/main/java/com/onixbyte/icalendar/constant/Classification.java b/webcal/src/main/java/com/onixbyte/icalendar/constant/Classification.java
new file mode 100644
index 0000000..3828e94
--- /dev/null
+++ b/webcal/src/main/java/com/onixbyte/icalendar/constant/Classification.java
@@ -0,0 +1,36 @@
+package com.onixbyte.icalendar.constant;
+
+/**
+ * This property defines the access classification for a calendar component.
+ *
*
- * WebCalendar calendar = new WebCalendar()
- * .setName("My Web Calendar")
- * .setCompanyName("CodeCrafters Inc.")
- * .setProductName("WebCal")
- * .setDomainName("codecrafters.org.cn")
- * .setMethod("PUBLISH")
- * .addEvent(event1)
- * .addEvent(event2);
- * String iCalendarString = calendar.resolve();
- *
- *
- *
- *
- * @author Zihlu Wang
- * @version 1.1.0
- * @since 1.0.0
- */
-public enum Classification {
-
- /**
- * Public classification level.
- *