@Test void testMementoHeadersMultipleFirst() { final SortedSet<Instant> mementos = new TreeSet<>(); final Instant time = now(); mementos.add(time); mementos.add(time.plusSeconds(1L)); mementos.add(time.plusSeconds(2L)); final List<Link> links = MementoResource.getMementoHeaders(URL, mementos, time).collect(toList()); assertEquals(4L, links.size()); checkMementoHeaders(links, 0L, 1L, 3L); }
public static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos, final Instant time) { if (mementos.isEmpty()) { return empty(); } else if (mementos.size() == 1) { return of( Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build(), Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS).getEpochSecond()) .rel(FIRST).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } final Stream.Builder<Link> builder = Stream.builder(); builder.accept(Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); final Link.Builder first = Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS) .getEpochSecond()).rel(FIRST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); final Link.Builder last = Link.fromUri(identifier + VERSION_PARAM + mementos.last().truncatedTo(SECONDS) .getEpochSecond()).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); if (shouldAddPrevNextLinks(mementos, time)) { final Instant memento = time.truncatedTo(SECONDS); final SortedSet<Instant> head = mementos.headSet(memento); if (!head.isEmpty()) { final Instant prev = head.last(); if (mementos.first().equals(prev)) { first.rel(PREV); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + prev.truncatedTo(SECONDS).getEpochSecond()) .rel(PREV).rel(MEMENTO) .param(DATETIME, ofInstant(prev.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } final Iterator<Instant> tail = mementos.tailSet(memento).iterator(); tail.next(); if (tail.hasNext()) { final Instant next = tail.next(); if (mementos.last().equals(next)) { last.rel(NEXT); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + next.truncatedTo(SECONDS) .getEpochSecond()).rel(NEXT).rel(MEMENTO) .param(DATETIME, ofInstant(next.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } } builder.accept(first.build()); builder.accept(last.build()); return builder.build(); }
MementoResource { public static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos, final Instant time) { if (mementos.isEmpty()) { return empty(); } else if (mementos.size() == 1) { return of( Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build(), Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS).getEpochSecond()) .rel(FIRST).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } final Stream.Builder<Link> builder = Stream.builder(); builder.accept(Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); final Link.Builder first = Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS) .getEpochSecond()).rel(FIRST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); final Link.Builder last = Link.fromUri(identifier + VERSION_PARAM + mementos.last().truncatedTo(SECONDS) .getEpochSecond()).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); if (shouldAddPrevNextLinks(mementos, time)) { final Instant memento = time.truncatedTo(SECONDS); final SortedSet<Instant> head = mementos.headSet(memento); if (!head.isEmpty()) { final Instant prev = head.last(); if (mementos.first().equals(prev)) { first.rel(PREV); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + prev.truncatedTo(SECONDS).getEpochSecond()) .rel(PREV).rel(MEMENTO) .param(DATETIME, ofInstant(prev.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } final Iterator<Instant> tail = mementos.tailSet(memento).iterator(); tail.next(); if (tail.hasNext()) { final Instant next = tail.next(); if (mementos.last().equals(next)) { last.rel(NEXT); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + next.truncatedTo(SECONDS) .getEpochSecond()).rel(NEXT).rel(MEMENTO) .param(DATETIME, ofInstant(next.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } } builder.accept(first.build()); builder.accept(last.build()); return builder.build(); } }
MementoResource { public static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos, final Instant time) { if (mementos.isEmpty()) { return empty(); } else if (mementos.size() == 1) { return of( Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build(), Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS).getEpochSecond()) .rel(FIRST).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } final Stream.Builder<Link> builder = Stream.builder(); builder.accept(Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); final Link.Builder first = Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS) .getEpochSecond()).rel(FIRST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); final Link.Builder last = Link.fromUri(identifier + VERSION_PARAM + mementos.last().truncatedTo(SECONDS) .getEpochSecond()).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); if (shouldAddPrevNextLinks(mementos, time)) { final Instant memento = time.truncatedTo(SECONDS); final SortedSet<Instant> head = mementos.headSet(memento); if (!head.isEmpty()) { final Instant prev = head.last(); if (mementos.first().equals(prev)) { first.rel(PREV); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + prev.truncatedTo(SECONDS).getEpochSecond()) .rel(PREV).rel(MEMENTO) .param(DATETIME, ofInstant(prev.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } final Iterator<Instant> tail = mementos.tailSet(memento).iterator(); tail.next(); if (tail.hasNext()) { final Instant next = tail.next(); if (mementos.last().equals(next)) { last.rel(NEXT); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + next.truncatedTo(SECONDS) .getEpochSecond()).rel(NEXT).rel(MEMENTO) .param(DATETIME, ofInstant(next.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } } builder.accept(first.build()); builder.accept(last.build()); return builder.build(); } MementoResource(final ServiceBundler trellis, final boolean includeMementoDates); }
MementoResource { public static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos, final Instant time) { if (mementos.isEmpty()) { return empty(); } else if (mementos.size() == 1) { return of( Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build(), Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS).getEpochSecond()) .rel(FIRST).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } final Stream.Builder<Link> builder = Stream.builder(); builder.accept(Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); final Link.Builder first = Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS) .getEpochSecond()).rel(FIRST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); final Link.Builder last = Link.fromUri(identifier + VERSION_PARAM + mementos.last().truncatedTo(SECONDS) .getEpochSecond()).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); if (shouldAddPrevNextLinks(mementos, time)) { final Instant memento = time.truncatedTo(SECONDS); final SortedSet<Instant> head = mementos.headSet(memento); if (!head.isEmpty()) { final Instant prev = head.last(); if (mementos.first().equals(prev)) { first.rel(PREV); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + prev.truncatedTo(SECONDS).getEpochSecond()) .rel(PREV).rel(MEMENTO) .param(DATETIME, ofInstant(prev.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } final Iterator<Instant> tail = mementos.tailSet(memento).iterator(); tail.next(); if (tail.hasNext()) { final Instant next = tail.next(); if (mementos.last().equals(next)) { last.rel(NEXT); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + next.truncatedTo(SECONDS) .getEpochSecond()).rel(NEXT).rel(MEMENTO) .param(DATETIME, ofInstant(next.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } } builder.accept(first.build()); builder.accept(last.build()); return builder.build(); } MementoResource(final ServiceBundler trellis, final boolean includeMementoDates); ResponseBuilder getTimeMapBuilder(final SortedSet<Instant> mementos, final TrellisRequest req,
            final String baseUrl); ResponseBuilder getTimeGateBuilder(final SortedSet<Instant> mementos, final TrellisRequest req,
            final String baseUrl); Link filterLinkParams(final Link link); static Stream<Link> getMementoLinks(final String identifier, final SortedSet<Instant> mementos); static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos,
            final Instant time); static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos); static Link filterLinkParams(final Link link, final boolean filter); static Link mementoToLink(final String identifier, final Instant time, final List<String> rels); }
MementoResource { public static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos, final Instant time) { if (mementos.isEmpty()) { return empty(); } else if (mementos.size() == 1) { return of( Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build(), Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS).getEpochSecond()) .rel(FIRST).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } final Stream.Builder<Link> builder = Stream.builder(); builder.accept(Link.fromUri(identifier + TIMEMAP_PARAM).rel(TIMEMAP).type(APPLICATION_LINK_FORMAT) .param(FROM, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .param(UNTIL, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); final Link.Builder first = Link.fromUri(identifier + VERSION_PARAM + mementos.first().truncatedTo(SECONDS) .getEpochSecond()).rel(FIRST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.first().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); final Link.Builder last = Link.fromUri(identifier + VERSION_PARAM + mementos.last().truncatedTo(SECONDS) .getEpochSecond()).rel(LAST).rel(MEMENTO) .param(DATETIME, ofInstant(mementos.last().truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)); if (shouldAddPrevNextLinks(mementos, time)) { final Instant memento = time.truncatedTo(SECONDS); final SortedSet<Instant> head = mementos.headSet(memento); if (!head.isEmpty()) { final Instant prev = head.last(); if (mementos.first().equals(prev)) { first.rel(PREV); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + prev.truncatedTo(SECONDS).getEpochSecond()) .rel(PREV).rel(MEMENTO) .param(DATETIME, ofInstant(prev.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } final Iterator<Instant> tail = mementos.tailSet(memento).iterator(); tail.next(); if (tail.hasNext()) { final Instant next = tail.next(); if (mementos.last().equals(next)) { last.rel(NEXT); } else { builder.accept(Link.fromUri(identifier + VERSION_PARAM + next.truncatedTo(SECONDS) .getEpochSecond()).rel(NEXT).rel(MEMENTO) .param(DATETIME, ofInstant(next.truncatedTo(SECONDS), UTC).format(RFC_1123_DATE_TIME)) .build()); } } } builder.accept(first.build()); builder.accept(last.build()); return builder.build(); } MementoResource(final ServiceBundler trellis, final boolean includeMementoDates); ResponseBuilder getTimeMapBuilder(final SortedSet<Instant> mementos, final TrellisRequest req,
            final String baseUrl); ResponseBuilder getTimeGateBuilder(final SortedSet<Instant> mementos, final TrellisRequest req,
            final String baseUrl); Link filterLinkParams(final Link link); static Stream<Link> getMementoLinks(final String identifier, final SortedSet<Instant> mementos); static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos,
            final Instant time); static Stream<Link> getMementoHeaders(final String identifier, final SortedSet<Instant> mementos); static Link filterLinkParams(final Link link, final boolean filter); static Link mementoToLink(final String identifier, final Instant time, final List<String> rels);  }