Skip to content

Commit

Permalink
Cookbook catchup, context list refactor (#198)
Browse files Browse the repository at this point in the history
* Flesh out ContextList test
* Catchup with cookbook recipes
  • Loading branch information
ksclarke authored Sep 8, 2024
1 parent cf4a4b4 commit 5a3233b
Show file tree
Hide file tree
Showing 15 changed files with 885 additions and 205 deletions.
103 changes: 46 additions & 57 deletions src/main/java/info/freelibrary/iiif/presentation/v3/ContextList.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@

package info.freelibrary.iiif.presentation.v3;

import static info.freelibrary.util.Constants.SINGLE_INSTANCE;

import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

Expand Down Expand Up @@ -62,29 +59,25 @@ public ContextList(final List<URI> aUriList) {
super.addAll(aUriList);

if (!super.contains(PRESENTATION_CONTEXT_URI)) {
super.add(0, PRESENTATION_CONTEXT_URI);
super.add(PRESENTATION_CONTEXT_URI);
} else {
super.sort(myComparator);
}
}

/**
* Adds a new context URI at the supplied index position. If the supplied context is not the IIIF Presentation
* context and the supplied index position is zero, it will be added at position one instead. Only the default
* context lives at position zero.
* Adds a new context URI at the supplied index position. The IIIF Presentation context URI cannot be added, because
* it exists in the list already.
*
* @param aIndex An index position at which to add the supplied URI
* @param aURI A URI to add at the supplied index position
*/
@Override
public void add(final int aIndex, final URI aURI) {
if (!PRESENTATION_CONTEXT_URI.equals(aURI)) {
if (aIndex == 0) {
super.add(1, aURI);
LOGGER.warn(MessageCodes.JPA_150, aURI);
} else {
super.add(aIndex, aURI);
}
super.add(aIndex, aURI);
} else {
LOGGER.warn(MessageCodes.JPA_150);
}
}

Expand Down Expand Up @@ -129,31 +122,29 @@ public boolean addAll(final int aIndex, final Collection<? extends URI> aCollect
}

/**
* If the supplied URI is not the default IIIF Presentation context, it is added at index position one. The first
* index position (i.e., zero) is reserved for the default IIIF Presentation context.
* Adds a new context to the list.
*
* @param aURI A context URI to add at the beginning of the list
* @throws UnsupportedOperationException If the default IIIF Presentation context URI was passed
*/
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED })
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED }) // JDK 21, but releasing with 17
public void addFirst(final URI aURI) {
if (!PRESENTATION_CONTEXT_URI.equals(aURI)) {
super.add(1, aURI);
} // Ignore if passing the default URI, because that already lives at index position zero
if (PRESENTATION_CONTEXT_URI.equals(aURI)) {
throw new UnsupportedOperationException(LOGGER.getMessage(MessageCodes.JPA_150));
}

super.add(0, aURI);
}

/**
* Adds the supplied context URI as the last in the list, unless the supplied context is the default IIIF
* Presentation context (in which case it's ignored -- the list already contains the default context).
* Unsupported operation. The last context URI is hard-coded.
*
* @param aURI A context URI to add at the end of the list
* @throws UnsupportedOperationException because the last context URI cannot be changed
*/
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED })
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED }) // JDK 21, but releasing with 17
public void addLast(final URI aURI) {
if (!PRESENTATION_CONTEXT_URI.equals(aURI)) {
super.add(aURI); // Adding, by default, adds as the last item
} else {
LOGGER.warn(MessageCodes.JPA_149);
}
throw new UnsupportedOperationException(LOGGER.getMessage(MessageCodes.JPA_150));
}

/**
Expand All @@ -162,7 +153,7 @@ public void addLast(final URI aURI) {
@Override
public void clear() {
super.clear();
super.add(0, PRESENTATION_CONTEXT_URI);
super.add(PRESENTATION_CONTEXT_URI);
}

@Override
Expand Down Expand Up @@ -193,10 +184,11 @@ public int hashCode() {
*
* @param aIndex The index position of the URI to remove from the list
* @return The URI removed from the list
* @throws IndexOutOfBoundsException If trying to remove the last context URI (which is required)
*/
@Override
public URI remove(final int aIndex) {
if (aIndex == 0) {
if (aIndex == size() - 1) {
throw new IndexOutOfBoundsException(LOGGER.getMessage(MessageCodes.JPA_039, PRESENTATION_CONTEXT_URI));
}

Expand Down Expand Up @@ -234,32 +226,27 @@ public boolean removeAll(final Collection<?> aCollection) {
* @param aFilter A filter to use to remove URIs from the list
* @return True if the URIs were removed
*/
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED })
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED }) // JDK 21, but releasing with 17
public boolean removeIf(final Predicate<? super URI> aFilter) {
final boolean result = super.removeIf(aFilter);

// If the filter removes our required default context, we add it back
if (!PRESENTATION_CONTEXT_URI.equals(get(0))) {
super.add(0, PRESENTATION_CONTEXT_URI);
if (!PRESENTATION_CONTEXT_URI.equals(get(size() - 1))) {
super.add(PRESENTATION_CONTEXT_URI);
}

return result;
}

/**
* Removes the last context URI, unless the last URI is the default context. In that case, a
* {@link NoSuchElementException} is thrown.
* Unsupported operation. The last context URI (the URI for the IIIF Presentation context) cannot be removed.
*
* @return The context URI that was removed
* @throws NoSuchElementException If the list only has the required IIIF Presentation context
* @throws UnsupportedOperationException because the last context URI cannot be removed
*/
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED })
@SuppressWarnings({ PMD.MISSING_OVERRIDE, Sonar.OVERRIDE_REQUIRED }) // JDK 21, but releasing with 17
public URI removeLast() {
if (size() == SINGLE_INSTANCE) {
throw new NoSuchElementException(LOGGER.getMessage(MessageCodes.JPA_039, PRESENTATION_CONTEXT_URI));
}

return remove(size() - 1);
throw new UnsupportedOperationException(LOGGER.getMessage(MessageCodes.JPA_039, PRESENTATION_CONTEXT_URI));
}

/**
Expand All @@ -275,14 +262,12 @@ public void replaceAll(final UnaryOperator<URI> anOperator) {
super.removeAll(List.of(PRESENTATION_CONTEXT_URI));

// Add back a single instance of our default context URI
if (!PRESENTATION_CONTEXT_URI.equals(get(0))) {
super.add(0, PRESENTATION_CONTEXT_URI);
}
super.add(PRESENTATION_CONTEXT_URI);
}

/**
* Retains the contexts in the supplied collection and the default context (if it's also not included in the
* supplied collection).
* Retains the contexts in the supplied collection and the default context (regardless of whether or not it exists
* in the supplied collection).
*
* @param aCollection A collection of URIs to retain, removing the rest
* @return Whether the URIs were successfully retained
Expand All @@ -292,8 +277,8 @@ public boolean retainAll(final Collection<?> aCollection) {
final boolean result = super.retainAll(aCollection);

// If we haven't added retained the required context, we add it back
if (!PRESENTATION_CONTEXT_URI.equals(get(0))) {
super.add(0, PRESENTATION_CONTEXT_URI);
if (!PRESENTATION_CONTEXT_URI.equals(get(size() - 1))) {
super.add(PRESENTATION_CONTEXT_URI);
}

return result;
Expand All @@ -306,21 +291,25 @@ public boolean retainAll(final Collection<?> aCollection) {
* @param aIndex An index position of the URI to set
* @param aURI A URI to set at the supplied index position
* @return The context URI that used to be at the supplied index position
* @throws IndexOutOfBoundsException If an invalid index position is used
*/
@Override
public URI set(final int aIndex, final URI aURI) {
if (PRESENTATION_CONTEXT_URI.equals(aURI)) {
if (aIndex != 0) {
throw new IndexOutOfBoundsException(LOGGER.getMessage(MessageCodes.JPA_149));
if (!PRESENTATION_CONTEXT_URI.equals(aURI)) {
if (aIndex != size() - 1) {
return super.set(aIndex, aURI);
}

return aURI;
throw new IndexOutOfBoundsException(LOGGER.getMessage(MessageCodes.JPA_149));
}
if (aIndex != 0) {
return super.set(aIndex, aURI);

// We're trying to set the default IIIF Presentation context URI at the wrong index? It's supplied by default.
if (aIndex != size() - 1) {
throw new IndexOutOfBoundsException(LOGGER.getMessage(MessageCodes.JPA_150));
}

throw new IndexOutOfBoundsException(LOGGER.getMessage(MessageCodes.JPA_151, aURI));
// We're setting the IIIF Presentation in the index position where it already lives
return PRESENTATION_CONTEXT_URI;
}

/**
Expand Down Expand Up @@ -350,9 +339,9 @@ public int compare(final URI aFirstURI, final URI aSecondURI) {

if (!PRESENTATION_CONTEXT_URI.equals(aFirstURI) || !PRESENTATION_CONTEXT_URI.equals(aSecondURI)) {
if (PRESENTATION_CONTEXT_URI.equals(aFirstURI)) {
result = -1;
} else if (PRESENTATION_CONTEXT_URI.equals(aSecondURI)) {
result = 1;
} else if (PRESENTATION_CONTEXT_URI.equals(aSecondURI)) {
result = -1;
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/main/resources/iiif_presentation_messages.xml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@
<entry key="JPA-146">{} is not a valid navPlace type</entry>
<entry key="JPA-147">A physical dimensions service must contain scale and units</entry>
<entry key="JPA-148">Supplied Optional was unexpectedly empty</entry>
<entry key="JPA-149">The IIIF Presentation context URI can only exist as the first context in the list</entry>
<entry key="JPA-150">Context '{}' was added at list position 1 because 0 is reserved for the default context</entry>
<entry key="JPA-151">The '{}' context cannot be set as the first context; this position is reserved for the default
IIIF Presentation context</entry>
<entry key="JPA-149">The last URI (i.e., the IIIF Presentation context) cannot be overwritten by another URI</entry>
<entry key="JPA-150">The default context URI cannot be set or added; it exists in the ContextList by default</entry>
<entry key="JPA-151"></entry>
</properties>
Loading

0 comments on commit 5a3233b

Please sign in to comment.