From aa5bac2eee5ef38538566f07d5809267ca761e46 Mon Sep 17 00:00:00 2001 From: Ben Fortuna Date: Fri, 1 Dec 2023 11:52:31 +1100 Subject: [PATCH] Refactored api for consistent method conventions --- .../ical4j/connector/CalendarCollection.java | 42 ++++--- .../org/ical4j/connector/CardCollection.java | 40 ++++++- .../ical4j/connector/ObjectCollection.java | 57 ++++++++- .../local/AbstractLocalObjectCollection.java | 6 +- .../local/LocalCalendarCollection.java | 99 ++++++++------- .../connector/local/LocalCardCollection.java | 113 +++++++++--------- .../local/LocalCalendarCollectionTest.groovy | 23 ++-- .../local/LocalCardCollectionTest.groovy | 26 ++-- .../dav/CalDavCalendarCollection.java | 45 ++++--- .../connector/dav/CardDavCollection.java | 24 ++-- .../connector/dav/CalendarCollectionTest.java | 2 +- 11 files changed, 296 insertions(+), 181 deletions(-) diff --git a/ical4j-connector-api/src/main/java/org/ical4j/connector/CalendarCollection.java b/ical4j-connector-api/src/main/java/org/ical4j/connector/CalendarCollection.java index 1ca7cc4..871417e 100644 --- a/ical4j-connector-api/src/main/java/org/ical4j/connector/CalendarCollection.java +++ b/ical4j-connector-api/src/main/java/org/ical4j/connector/CalendarCollection.java @@ -36,12 +36,9 @@ import net.fortuna.ical4j.model.component.VFreeBusy; import net.fortuna.ical4j.model.property.Uid; import net.fortuna.ical4j.util.Calendars; -import org.ical4j.connector.local.LocalCalendarCollection; -import org.slf4j.LoggerFactory; import java.time.Instant; import java.time.temporal.Temporal; -import java.util.ArrayList; import java.util.List; /** @@ -121,34 +118,44 @@ default Calendar getFreeBusy(Temporal start, Temporal end) { * @return the UID extracted from the specified calendar * @throws ObjectStoreException when an unexpected error occurs (implementation-specific) * @throws ConstraintViolationException if the specified calendar has no single unique identifier (UID) + * @deprecated use {@link ObjectCollection#add(Object)} */ - Uid addCalendar(Calendar calendar) throws ObjectStoreException, ConstraintViolationException; + @Deprecated + default Uid addCalendar(Calendar calendar) throws ObjectStoreException, ConstraintViolationException { + return new Uid(add(calendar)); + } /** * Returns the calendar object with the specified UID. * @param uid the UID associated with the returned calendar * @return a calendar object or null if no calendar with the specified UID exists + * @deprecated use {@link ObjectCollection#getAll(String...)} */ - Calendar getCalendar(String uid) throws ObjectNotFoundException; + @Deprecated + default Calendar getCalendar(String uid) throws ObjectNotFoundException { + return get(uid).orElse(null); + } + /** + * + * @param uids + * @return + * @deprecated use {@link ObjectCollection#getAll(String...)} + */ + @Deprecated default List getCalendars(String... uids) { - List calendars = new ArrayList<>(); - for (String uid : uids) { - try { - calendars.add(getCalendar(uid)); - } catch (ObjectNotFoundException e) { - LoggerFactory.getLogger(LocalCalendarCollection.class).warn("Calendar not found: " + uid); - } - } - return calendars; + return getAll(uids); } /** * @param uid the UID of the calendar to remove * @return the calendar that was successfully removed from the collection - * @throws ObjectStoreException where an unexpected error occurs + * @deprecated use {@link ObjectCollection#removeAll(String...)} */ - Calendar removeCalendar(String uid) throws FailedOperationException, ObjectStoreException, ObjectNotFoundException; + @Deprecated + default Calendar removeCalendar(String uid) throws FailedOperationException { + return removeAll(uid).get(0); + } /** * Merges the specified calendar object with this collection. This is done by @@ -163,7 +170,6 @@ default List getCalendars(String... uids) { /** * Exports the entire collection as a single calendar object. * @return a calendar object instance that contains all calendars in the collection - * @throws ObjectStoreException where an unexpected error occurs */ - Calendar export() throws ObjectStoreException; + Calendar export(); } diff --git a/ical4j-connector-api/src/main/java/org/ical4j/connector/CardCollection.java b/ical4j-connector-api/src/main/java/org/ical4j/connector/CardCollection.java index edaa083..0a851ff 100644 --- a/ical4j-connector-api/src/main/java/org/ical4j/connector/CardCollection.java +++ b/ical4j-connector-api/src/main/java/org/ical4j/connector/CardCollection.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * $Id$ @@ -56,8 +57,12 @@ public interface CardCollection extends ObjectCollection { * @return the UID extracted from the vCard * @throws ObjectStoreException where an unexpected error occurs * @throws ConstraintViolationException where the specified object is not valid + * @deprecated use {@link ObjectCollection#add(Object)} */ - Uid addCard(VCard card) throws ObjectStoreException, ConstraintViolationException; + @Deprecated + default Uid addCard(VCard card) throws ObjectStoreException, ConstraintViolationException { + return new Uid(add(card)); + } /** * @@ -75,11 +80,37 @@ public interface CardCollection extends ObjectCollection { * @return the card object that was removed from the collection * @throws ObjectNotFoundException * @throws FailedOperationException + * @deprecated use {@link ObjectCollection#removeAll(String...)} + * */ - VCard removeCard(String uid) throws ObjectNotFoundException, FailedOperationException; + @Deprecated + default VCard removeCard(String uid) throws ObjectNotFoundException, FailedOperationException { + List result = removeAll(uid); + return result.get(0); + } - VCard getCard(String uid) throws ObjectNotFoundException, FailedOperationException; + /** + * + * @param uid + * @return + * @throws ObjectNotFoundException + * @throws FailedOperationException + * @deprecated use {@link ObjectCollection#getAll(String...)} + */ + @Deprecated + default VCard getCard(String uid) throws ObjectNotFoundException, FailedOperationException { + Optional card = get(uid); + return card.orElse(null); + } + /** + * + * @param uids + * @return + * @throws FailedOperationException + * @deprecated use {@link ObjectCollection#getAll(String...)} + */ + @Deprecated default VCardList getCards(String... uids) throws FailedOperationException { List cards = new ArrayList<>(); for (String uid : uids) { @@ -95,7 +126,6 @@ default VCardList getCards(String... uids) throws FailedOperationException { /** * Exports the entire collection as an array of objects. * @return a vCard object array that contains all cards in the collection - * @throws ObjectStoreException where an unexpected error occurs */ - VCard[] export() throws ObjectStoreException; + VCard[] export(); } diff --git a/ical4j-connector-api/src/main/java/org/ical4j/connector/ObjectCollection.java b/ical4j-connector-api/src/main/java/org/ical4j/connector/ObjectCollection.java index b9b5612..5ba5ffc 100644 --- a/ical4j-connector-api/src/main/java/org/ical4j/connector/ObjectCollection.java +++ b/ical4j-connector-api/src/main/java/org/ical4j/connector/ObjectCollection.java @@ -34,7 +34,9 @@ import net.fortuna.ical4j.filter.FilterExpression; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * Implementors provide support for a persistent collection of objects. A collection will typically support @@ -67,14 +69,57 @@ public interface ObjectCollection extends ObjectCollectionListenerSupport * Return a list of object identifiers in the collection * @return a list of object identifiers */ - List listObjectUids(); + List listObjectUIDs(); /** - * Returns all objects stored in the collection. - * @return an array of collection objects - * @throws ObjectStoreException where an unexpected error occurs + * Returns a list of objects found with the specified UIDs. Where no UID is specified all objects + * are returned. + * @param uid zero or more + * @return a list of all found objects */ - Iterable getComponents() throws ObjectStoreException; + default List getAll(String...uid) { + List result = new ArrayList<>(); + if (uid.length > 0) { + for (String u : uid) { + Optional cal = get(u); + cal.ifPresent(result::add); + } + } else { + for (String u : listObjectUIDs()) { + Optional cal = get(u); + cal.ifPresent(result::add); + } + } + return result; + } + + /** + * Return a single object with the specified UID if it exists. + * @param uid + * @return an optional reference to an existing object + */ + Optional get(String uid); + + /** + * Add a single object entity identified by an embedded UID value. + * @param object + * @return the UID discovered in the object entity + * @throws ObjectStoreException + */ + String add(T object) throws ObjectStoreException; + + /** + * Remove one or more objects found matching the specified UIDs. Where no UID is specified no + * action will be performed. + * + * Removal of all objects from a collection may be achieved as follows: + * + * collection.removeAll(collection.listObjectUIDs().toArray(new String[0])) + * + * @param uid + * @return a list of found objects that were removed + */ + List removeAll(String...uid) throws FailedOperationException; /** * Returns a subset of objects that satisfy the specified filter expression. @@ -82,7 +127,7 @@ public interface ObjectCollection extends ObjectCollectionListenerSupport * @return an iterable of objects matching the specified filter expressions * @throws ObjectStoreException when an unexpected error occurs. */ - default Iterable query(FilterExpression filterExpression) throws ObjectStoreException { + default List query(FilterExpression filterExpression) { throw new UnsupportedOperationException("Collection filtering not yet supported"); } diff --git a/ical4j-connector-api/src/main/java/org/ical4j/connector/local/AbstractLocalObjectCollection.java b/ical4j-connector-api/src/main/java/org/ical4j/connector/local/AbstractLocalObjectCollection.java index 552633d..1c67739 100644 --- a/ical4j-connector-api/src/main/java/org/ical4j/connector/local/AbstractLocalObjectCollection.java +++ b/ical4j-connector-api/src/main/java/org/ical4j/connector/local/AbstractLocalObjectCollection.java @@ -16,9 +16,9 @@ public abstract class AbstractLocalObjectCollection extends AbstractObjectCol public AbstractLocalObjectCollection(File root) throws IOException { this.root = Objects.requireNonNull(root); - if (!root.isDirectory()) { - throw new IllegalArgumentException("Root must be a directory"); - } +// if (!root.isDirectory()) { +// throw new IllegalArgumentException("Root must be a directory"); +// } File configRoot = new File(root, LocalCollectionConfiguration.DEFAULT_CONFIG_DIR); if ((configRoot.exists() && !configRoot.isDirectory()) || (!configRoot.exists() && !configRoot.mkdirs())) { diff --git a/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCalendarCollection.java b/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCalendarCollection.java index 62c39fc..ffeefa8 100644 --- a/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCalendarCollection.java +++ b/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCalendarCollection.java @@ -3,10 +3,12 @@ import net.fortuna.ical4j.data.CalendarOutputter; import net.fortuna.ical4j.data.ParserException; import net.fortuna.ical4j.model.Calendar; -import net.fortuna.ical4j.model.ConstraintViolationException; import net.fortuna.ical4j.model.property.Uid; import net.fortuna.ical4j.util.Calendars; -import org.ical4j.connector.*; +import org.ical4j.connector.CalendarCollection; +import org.ical4j.connector.FailedOperationException; +import org.ical4j.connector.MediaType; +import org.ical4j.connector.ObjectStoreException; import java.io.File; import java.io.FileWriter; @@ -15,6 +17,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public class LocalCalendarCollection extends AbstractLocalObjectCollection implements CalendarCollection { @@ -61,55 +64,63 @@ public Integer getMaxAttendeesPerInstance() { } @Override - public List listObjectUids() { + public List listObjectUIDs() { return Arrays.stream(getObjectFiles()).map(file -> file.getName().split(".ics")[0]) .collect(Collectors.toList()); } @Override - public Uid addCalendar(Calendar calendar) throws ObjectStoreException, ConstraintViolationException { - Uid uid = calendar.getUid(); - try { - Calendar existing = getCalendar(uid.getValue()); - + public String add(Calendar object) throws ObjectStoreException { + Uid uid = object.getUid(); + Optional existing = get(uid.getValue()); + if (existing.isPresent()) { // TODO: potentially merge/replace existing.. throw new ObjectStoreException("Calendar already exists"); - } catch (ObjectNotFoundException e) { - } try (FileWriter writer = new FileWriter(new File(getRoot(), uid.getValue() + ".ics"))) { - new CalendarOutputter(false).output(calendar, writer); + new CalendarOutputter(false).output(object, writer); } catch (IOException e) { throw new ObjectStoreException("Error writing calendar file", e); } // notify listeners.. - fireOnAddEvent(this, calendar); + fireOnAddEvent(this, object); - return uid; + return uid.getValue(); } @Override - public Calendar getCalendar(String uid) throws ObjectNotFoundException { + public Optional get(String uid) { + File calendarFile = new File(getRoot(), uid + ".ics"); + if (!calendarFile.exists()) { + return Optional.empty(); + } + try { - return Calendars.load(new File(getRoot(), uid + ".ics").getAbsolutePath()); + return Optional.of(Calendars.load(calendarFile.getAbsolutePath())); } catch (IOException | ParserException e) { - throw new ObjectNotFoundException(String.format("Calendar not found: %s", uid), e); + throw new RuntimeException(e); } } @Override - public Calendar removeCalendar(String uid) throws FailedOperationException, ObjectNotFoundException { - Calendar calendar = getCalendar(uid); - if (!new File(getRoot(), uid + ".ics").delete()) { - throw new FailedOperationException("Unable to delete calendar: " + uid); + public List removeAll(String... uid) throws FailedOperationException { + List removed = new ArrayList<>(); + for (String u : uid) { + File calendarFile = new File(getRoot(), u + ".ics"); + if (calendarFile.exists()) { + Optional cal = get(u); + if (cal.isPresent()) { + if (!calendarFile.delete()) { + throw new FailedOperationException("Unable to delete calendar: " + u); + } + removed.add(cal.get()); + fireOnRemoveEvent(this, cal.get()); + } + } } - - // notify listeners.. - fireOnRemoveEvent(this, calendar); - - return calendar; + return removed; } @Override @@ -117,13 +128,11 @@ public Uid[] merge(Calendar calendar) throws ObjectStoreException { Calendar[] uidCalendars = calendar.split(); for (Calendar c : uidCalendars) { Uid uid = c.getUid(); - try { - Calendar existing = getCalendar(uid.getValue()); + Optional existing = get(uid.getValue()); + if (existing.isPresent()) { // TODO: potentially merge/replace existing.. throw new ObjectStoreException("Calendar already exists"); - } catch (ObjectNotFoundException e) { - } try (FileWriter writer = new FileWriter(new File(getRoot(), uid.getValue() + ".ics"))) { @@ -152,22 +161,22 @@ public Calendar export() { return export; } - @Override - public Iterable getComponents() throws ObjectStoreException { - List calendars = new ArrayList<>(); - - File[] componentFiles = getObjectFiles(); - if (componentFiles != null) { - try { - for (File file : componentFiles) { - calendars.add(Calendars.load(file.getAbsolutePath())); - } - } catch (IOException | ParserException e) { - throw new ObjectStoreException(e); - } - } - return calendars; - } +// @Override +// public Iterable getAll() throws ObjectStoreException { +// List calendars = new ArrayList<>(); +// +// File[] componentFiles = getObjectFiles(); +// if (componentFiles != null) { +// try { +// for (File file : componentFiles) { +// calendars.add(Calendars.load(file.getAbsolutePath())); +// } +// } catch (IOException | ParserException e) { +// throw new ObjectStoreException(e); +// } +// } +// return calendars; +// } private File[] getObjectFiles() { return getRoot().listFiles(pathname -> diff --git a/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCardCollection.java b/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCardCollection.java index 07cc4fc..5ac0de1 100644 --- a/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCardCollection.java +++ b/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCardCollection.java @@ -7,16 +7,16 @@ import net.fortuna.ical4j.vcard.VCardBuilder; import net.fortuna.ical4j.vcard.VCardOutputter; import net.fortuna.ical4j.vcard.property.Uid; -import org.ical4j.connector.*; +import org.ical4j.connector.CardCollection; +import org.ical4j.connector.FailedOperationException; +import org.ical4j.connector.MediaType; +import org.ical4j.connector.ObjectStoreException; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; public class LocalCardCollection extends AbstractLocalObjectCollection implements CardCollection { @@ -31,41 +31,38 @@ public LocalCardCollection(File root) throws IOException { } @Override - public List listObjectUids() { + public List listObjectUIDs() { return Arrays.stream(getObjectFiles()).map(file -> file.getName().split(".vcf")[0]) .collect(Collectors.toList()); } @Override - public Uid addCard(VCard card) throws ObjectStoreException, ConstraintViolationException { - Uid uid = card.getRequiredProperty(PropertyName.UID.toString()); - - try { - VCard existing = getCard(uid.getValue()); + public String add(VCard card) throws ObjectStoreException, ConstraintViolationException { + Uid uid = card.getRequiredProperty(PropertyName.UID); + Optional existing = get(uid.getValue()); + if (existing.isPresent()) { // TODO: potentially merge/replace existing.. throw new ObjectStoreException("Card already exists"); - } catch (ObjectNotFoundException e) { + } + try (FileWriter writer = new FileWriter(new File(getRoot(), uid.getValue() + ".vcf"))) { + new VCardOutputter(false).output(card, writer); + } catch (IOException e) { + throw new ObjectStoreException("Error writing card file", e); } - save(card); // notify listeners.. fireOnAddEvent(this, card); - return uid; + return uid.getValue(); } @Override public Uid[] merge(VCard card) throws ObjectStoreException, ConstraintViolationException { Uid uid = card.getRequiredProperty(PropertyName.UID.toString()); - VCard existing = null; - try { - existing = getCard(uid.getValue()); - } catch (ObjectNotFoundException e) { - throw new ObjectStoreException(e); - } - existing.addAll(card.getProperties()); + Optional existing = get(uid.getValue()); + existing.ifPresent(vCard -> vCard.addAll(card.getProperties())); save(card); // notify listeners.. @@ -84,51 +81,59 @@ private void save(VCard card) throws ObjectStoreException { } } - public VCard getCard(String uid) throws ObjectNotFoundException { + public Optional get(String uid) { + File cardFile = new File(getRoot(), uid + ".vcf"); + if (!cardFile.exists()) { + return Optional.empty(); + } + try { - return new VCardBuilder(Files.newInputStream(new File(getRoot(), uid + ".vcf").toPath())).build(); + return Optional.of(new VCardBuilder(Files.newInputStream(cardFile.toPath())).build()); } catch (IOException | ParserException e) { - throw new ObjectNotFoundException(String.format("Card not found: %s", uid), e); + throw new RuntimeException(e); } } @Override - public VCard removeCard(String uid) throws ObjectNotFoundException, FailedOperationException { - VCard card = getCard(uid); - if (!new File(getRoot(), uid + ".vcf").delete()) { - throw new FailedOperationException("Unable to delete card: " + uid); - } - - // notify listeners.. - fireOnRemoveEvent(this, card); - - return card; - } - - @Override - public Iterable getComponents() throws ObjectStoreException { - List cards = new ArrayList<>(); - - File[] componentFiles = getObjectFiles(); - if (componentFiles != null) { - try { - for (File file : componentFiles) { - VCardBuilder builder = new VCardBuilder(Files.newInputStream(file.toPath())); - cards.add(builder.build()); + public List removeAll(String... uid) throws FailedOperationException { + List removed = new ArrayList<>(); + for (String u : uid) { + File cardFile = new File(getRoot(), u + ".vcf"); + if (cardFile.exists()) { + Optional card = get(u); + if (card.isPresent()) { + if (!cardFile.delete()) { + throw new FailedOperationException("Unable to delete card: " + u); + } + removed.add(card.get()); + fireOnRemoveEvent(this, card.get()); } - } catch (IOException | ParserException e) { - throw new ObjectStoreException(e); } } - return cards; + return removed; } +// @Override +// public Iterable getAll() throws ObjectStoreException { +// List cards = new ArrayList<>(); +// +// File[] componentFiles = getObjectFiles(); +// if (componentFiles != null) { +// try { +// for (File file : componentFiles) { +// VCardBuilder builder = new VCardBuilder(Files.newInputStream(file.toPath())); +// cards.add(builder.build()); +// } +// } catch (IOException | ParserException e) { +// throw new ObjectStoreException(e); +// } +// } +// return cards; +// } + @Override - public VCard[] export() throws ObjectStoreException { - List export = new ArrayList<>(); - for (VCard card : getComponents()) { - export.add(card); - } + public VCard[] export() { + List export = new ArrayList<>(getAll()); return export.toArray(new VCard[0]); } diff --git a/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCalendarCollectionTest.groovy b/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCalendarCollectionTest.groovy index 03f3d73..eb90ca1 100644 --- a/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCalendarCollectionTest.groovy +++ b/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCalendarCollectionTest.groovy @@ -4,7 +4,6 @@ import net.fortuna.ical4j.model.Calendar import net.fortuna.ical4j.model.Component import net.fortuna.ical4j.model.ContentBuilder import net.fortuna.ical4j.model.Property -import net.fortuna.ical4j.util.Calendars import net.fortuna.ical4j.util.RandomUidGenerator import org.ical4j.connector.event.ObjectCollectionEvent import org.ical4j.connector.event.ObjectCollectionListener @@ -42,7 +41,7 @@ class LocalCalendarCollectionTest extends AbstractLocalTest { collection.addObjectCollectionListener(listener) when: 'the new calendar is added to the collection' - collection.addCalendar(calendar) + collection.add(calendar) then: 'a new calendar file is created' new File(storeLocation, @@ -58,17 +57,17 @@ class LocalCalendarCollectionTest extends AbstractLocalTest { LocalCalendarCollection collection = calendarStore.addCollection('public_holidays') and: 'a calendar object that is added to the collection' - collection.addCalendar(calendar) + collection.add(calendar) when: 'the calendar is removed from the collection' - def removed = collection.removeCalendar(Calendars.getUid(calendar).value) + def removed = collection.removeAll(calendar.getUid().value) then: 'the exsiting calendar file is deleted' !new File(storeLocation, "public_holidays/${calendar.getComponent(Component.VEVENT).get().getRequiredProperty(Property.UID).getValue()}.ics").exists() and: 'removed calendar is identical to added' - removed == calendar + removed.contains(calendar) } def 'test get calendar from collection'() { @@ -77,13 +76,13 @@ class LocalCalendarCollectionTest extends AbstractLocalTest { LocalCalendarCollection collection = calendarStore.addCollection('public_holidays') and: 'a calendar object that is added to the collection' - collection.addCalendar(calendar) + collection.add(calendar) when: 'the calendar is retrieved from the collection' - def retrieved = collection.getCalendar(Calendars.getUid(calendar).value) + def retrieved = collection.get(calendar.getUid().value) then: 'retrieved calendar is identical to added' - retrieved == calendar + retrieved == Optional.of(calendar) } def 'test list object uids in collection'() { @@ -92,13 +91,13 @@ class LocalCalendarCollectionTest extends AbstractLocalTest { LocalCalendarCollection collection = calendarStore.addCollection('public_holidays') and: 'a calendar object that is added to the collection' - collection.addCalendar(calendar) + collection.add(calendar) when: 'the collection object uids are listed' - def uids = collection.listObjectUids() + def uids = collection.listObjectUIDs() then: 'the added calendar uid is in the list' - uids.contains(Calendars.getUid(calendar).value) + uids.contains(calendar.getUid().value) } def 'test export collection'() { @@ -107,7 +106,7 @@ class LocalCalendarCollectionTest extends AbstractLocalTest { LocalCalendarCollection collection = calendarStore.addCollection('public_holidays') and: 'a calendar object that is added to the collection' - collection.addCalendar(calendar) + collection.add(calendar) when: 'the collection is exported' def export = collection.export() diff --git a/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCardCollectionTest.groovy b/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCardCollectionTest.groovy index 7e8b78f..60742a1 100644 --- a/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCardCollectionTest.groovy +++ b/ical4j-connector-api/src/test/groovy/org/ical4j/connector/local/LocalCardCollectionTest.groovy @@ -36,11 +36,11 @@ class LocalCardCollectionTest extends AbstractLocalTest { collection.addObjectCollectionListener(listener) when: 'the new card is added to the collection' - collection.addCard(card) + collection.add(card) then: 'a new card file is created' new File(storeLocation, - "contacts/${card.getRequiredProperty(PropertyName.UID as String).getValue()}.vcf").exists() + "contacts/${card.getRequiredProperty(PropertyName.UID).getValue()}.vcf").exists() and: 'the listener is notified' event != null && event.object == card @@ -52,17 +52,17 @@ class LocalCardCollectionTest extends AbstractLocalTest { LocalCardCollection collection = cardStore.addCollection('contacts') and: 'a card object added' - collection.addCard(card) + collection.add(card) when: 'the card is removed' - def removed = collection.removeCard(card.getRequiredProperty(PropertyName.UID as String).value) + def removed = collection.removeAll(card.getRequiredProperty(PropertyName.UID).value) then: 'the existing card file is deleted' !new File(storeLocation, - "contacts/${card.getRequiredProperty(PropertyName.UID as String).getValue()}.vcf").exists() + "contacts/${card.getRequiredProperty(PropertyName.UID).getValue()}.vcf").exists() and: 'removed card is identical to added' - removed == card + removed.contains(card) } def 'test get card from collection'() { @@ -71,13 +71,13 @@ class LocalCardCollectionTest extends AbstractLocalTest { LocalCardCollection collection = cardStore.addCollection('contacts') and: 'a card object added' - collection.addCard(card) + collection.add(card) when: 'the card is removed' - def retrieved = collection.getCard(card.getRequiredProperty(PropertyName.UID as String).value) + def retrieved = collection.get(card.getRequiredProperty(PropertyName.UID).value) then: 'retrieved card is identical to added' - retrieved == card + retrieved == Optional.of(card) } def 'test list object uids in collection'() { @@ -86,13 +86,13 @@ class LocalCardCollectionTest extends AbstractLocalTest { LocalCardCollection collection = cardStore.addCollection('contacts') and: 'a card object that is added to the collection' - collection.addCard(card) + collection.add(card) when: 'the collection object uids are listed' - def uids = collection.listObjectUids() + def uids = collection.listObjectUIDs() then: 'the added calendar uid is in the list' - uids.contains(card.getRequiredProperty(PropertyName.UID as String).value) + uids.contains(card.getRequiredProperty(PropertyName.UID).value) } def 'test export collection'() { @@ -101,7 +101,7 @@ class LocalCardCollectionTest extends AbstractLocalTest { LocalCardCollection collection = cardStore.addCollection('contacts') and: 'a card object that is added to the collection' - collection.addCard(card) + collection.add(card) when: 'the collection is exported' def export = collection.export() diff --git a/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CalDavCalendarCollection.java b/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CalDavCalendarCollection.java index 1e7c7e7..97c9330 100644 --- a/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CalDavCalendarCollection.java +++ b/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CalDavCalendarCollection.java @@ -42,10 +42,7 @@ import org.apache.jackrabbit.webdav.property.DavPropertySet; import org.apache.jackrabbit.webdav.security.SecurityConstants; import org.apache.jackrabbit.webdav.version.report.ReportInfo; -import org.ical4j.connector.CalendarCollection; -import org.ical4j.connector.FailedOperationException; -import org.ical4j.connector.ObjectNotFoundException; -import org.ical4j.connector.ObjectStoreException; +import org.ical4j.connector.*; import org.ical4j.connector.dav.property.*; import org.ical4j.connector.dav.request.CalendarQuery; import org.ical4j.connector.dav.request.EventQuery; @@ -60,6 +57,7 @@ import java.time.Instant; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static org.apache.jackrabbit.webdav.property.DavPropertyName.DISPLAYNAME; @@ -103,6 +101,11 @@ public class CalDavCalendarCollection extends AbstractDavObjectCollection listObjectUids() { + public List listObjectUIDs() { //TODO: extract UIDs from calendar objects.. return null; } @@ -126,7 +129,7 @@ public List listObjectUids() { /** * @return an array of calendar objects * @deprecated Use the getEvents() method - * @see CalendarCollection#getComponents() + * @see ObjectCollection#getAll(String...) */ @Deprecated public Iterable getCalendars() { @@ -319,9 +322,9 @@ public int getOrder() { * Add a new calendar object in the collection. Creation will be done on the server right away. */ @Override - public Uid addCalendar(Calendar calendar) throws ObjectStoreException, ConstraintViolationException { + public String add(Calendar calendar) throws ObjectStoreException, ConstraintViolationException { writeCalendarOnServer(calendar, true); - return calendar.getRequiredProperty(Property.UID); + return calendar.getRequiredProperty(Property.UID).getValue(); } /** @@ -376,8 +379,12 @@ public void writeCalendarOnServer(String uri, Calendar calendar, boolean isNew) * {@inheritDoc} */ @Override - public Calendar getCalendar(String uid) throws ObjectNotFoundException { - return getCalendarFromUri(defaultUriFromUid(uid)); + public Optional get(String uid) { + try { + return Optional.of(getCalendarFromUri(defaultUriFromUid(uid))); + } catch (ObjectNotFoundException e) { + return Optional.empty(); + } } /** @@ -400,8 +407,16 @@ public Calendar getCalendarFromUri(String uri) throws ObjectNotFoundException { /** * {@inheritDoc} */ - public Calendar removeCalendar(String uid) throws FailedOperationException, ObjectStoreException, ObjectNotFoundException { - return removeCalendarFromUri(defaultUriFromUid(uid)); + public List removeAll(String... uid) { + List result = new ArrayList<>(); + for (String u : uid) { + try { + result.add(removeCalendarFromUri(defaultUriFromUid(u))); + } catch (FailedOperationException | ObjectStoreException | ObjectNotFoundException e) { + throw new RuntimeException(e); + } + } + return result; } /** @@ -427,7 +442,7 @@ public final Uid[] merge(Calendar calendar) throws FailedOperationException, Obj try { Calendar[] uidCalendars = Calendars.split(calendar); for (int i = 0; i < uidCalendars.length; i++) { - addCalendar(uidCalendars[i]); + add(uidCalendars[i]); uids.add(uidCalendars[i].getRequiredProperty(Property.UID)); } } catch (ConstraintViolationException cve) { @@ -439,14 +454,14 @@ public final Uid[] merge(Calendar calendar) throws FailedOperationException, Obj /** * {@inheritDoc} */ - public Calendar export() throws ObjectStoreException { + public Calendar export() { throw new UnsupportedOperationException("not implemented"); } /** * {@inheritDoc} */ - public Iterable getComponents() throws ObjectStoreException { + public Iterable getAll() throws ObjectStoreException { return getComponentsByType(Component.VEVENT); } diff --git a/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CardDavCollection.java b/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CardDavCollection.java index e110900..06f5377 100644 --- a/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CardDavCollection.java +++ b/ical4j-connector-dav/src/main/java/org/ical4j/connector/dav/CardDavCollection.java @@ -55,6 +55,7 @@ import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.Optional; import static org.apache.jackrabbit.webdav.property.DavPropertyName.DISPLAYNAME; @@ -98,6 +99,11 @@ public class CardDavCollection extends AbstractDavObjectCollection implem this.properties = _properties; } + @Override + String getPath() { + return getStore().pathResolver.getCardPath(getId(), getStore().getSessionConfiguration().getWorkspace()); + } + /** * Creates this collection on the CardDAV server. * @@ -142,7 +148,7 @@ public long getMaxResourceSize() { /** * {@inheritDoc} */ - public VCard[] export() throws ObjectStoreException { + public VCard[] export() { throw new UnsupportedOperationException("not implemented"); } @@ -195,7 +201,7 @@ public String getDescription() { } @Override - public List listObjectUids() { + public List listObjectUIDs() { //TODO: extract UIDs from vcards.. return null; } @@ -203,7 +209,7 @@ public List listObjectUids() { /* (non-Javadoc) * @see org.ical4j.connector.ObjectCollection#getComponents() */ - public Iterable getComponents() throws ObjectStoreException { + public Iterable getAll() throws ObjectStoreException { try { DavPropertyNameSet properties = new DavPropertyNameSet(); properties.add(DavPropertyName.GETETAG); @@ -220,10 +226,10 @@ public Iterable getComponents() throws ObjectStoreException { /* (non-Javadoc) * @see org.ical4j.connector.CardCollection#addCard(net.fortuna.ical4j.vcard.VCard) */ - public Uid addCard(VCard card) throws ObjectStoreException, ConstraintViolationException { + public String add(VCard card) throws ObjectStoreException, ConstraintViolationException { Uid uid = card.getRequiredProperty(PropertyName.UID.toString()); save(card); - return uid; + return uid.getValue(); } @Override @@ -256,16 +262,16 @@ private void save(VCard card) throws ObjectStoreException { } @Override - public VCard removeCard(String uid) throws ObjectNotFoundException, FailedOperationException { + public List removeAll(String... uid) { return null; } @Override - public VCard getCard(String uid) throws ObjectNotFoundException, FailedOperationException { + public Optional get(String uid) { try { - return getStore().getClient().getVCard(uid); + return Optional.of(getStore().getClient().getVCard(uid)); } catch (IOException e) { - throw new FailedOperationException(e); + throw new RuntimeException(e); } } } diff --git a/ical4j-connector-dav/src/test/java/org/ical4j/connector/dav/CalendarCollectionTest.java b/ical4j-connector-dav/src/test/java/org/ical4j/connector/dav/CalendarCollectionTest.java index a6d779c..42efa84 100644 --- a/ical4j-connector-dav/src/test/java/org/ical4j/connector/dav/CalendarCollectionTest.java +++ b/ical4j-connector-dav/src/test/java/org/ical4j/connector/dav/CalendarCollectionTest.java @@ -195,7 +195,7 @@ public void testGetCalendar() throws ObjectStoreException, ObjectNotFoundExcepti * @throws ObjectStoreException */ public void testGetCalendars() throws ObjectStoreException { - Iterable calendars = getCollection().getComponents(); + Iterable calendars = getCollection().getAll(); assertNotNull(calendars); } }