Skip to content

Commit

Permalink
Add iterator.Paged and removve checkstyle suppression yegor256#1464
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivier B. OURA committed Jan 23, 2021
1 parent 1fed966 commit 4477ddf
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 45 deletions.
46 changes: 1 addition & 45 deletions src/main/java/org/cactoos/iterable/Paged.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,8 @@
package org.cactoos.iterable;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicReference;
import org.cactoos.Func;
import org.cactoos.Scalar;
import org.cactoos.func.UncheckedFunc;
import org.cactoos.scalar.Sticky;
import org.cactoos.scalar.Unchecked;

/**
* Paged iterable.
Expand All @@ -41,11 +36,7 @@
*
* @param <X> Type of item
* @since 0.47
* @todo #1183:30m Continue refactoring and add `iterator.Paged` by
* extracting inner anon class from this class. The checkstyle suppression
* should be removed after that.
*/
@SuppressWarnings("PMD.OnlyOneConstructorShouldDoInitialization")
public final class Paged<X> extends IterableEnvelope<X> {

/**
Expand All @@ -55,47 +46,12 @@ public final class Paged<X> extends IterableEnvelope<X> {
* @param next Subsequent bags of elements
* @param <I> Custom iterator
*/
@SuppressWarnings("PMD.ConstructorOnlyInitializesOrCallOtherConstructors")
public <I extends Iterator<X>> Paged(
final Scalar<I> first, final Func<I, I> next
) {
// @checkstyle AnonInnerLengthCheck (30 lines)
super(
new IterableOf<>(
() -> new Iterator<X>() {
private final AtomicReference<Unchecked<I>> current =
new AtomicReference<>(
new Unchecked<>(
new Sticky<>(first)
)
);

private final UncheckedFunc<I, I> subsequent =
new UncheckedFunc<>(next);

@Override
public boolean hasNext() {
if (!this.current.get().value().hasNext()) {
final I next = this.subsequent.apply(
this.current.get().value()
);
this.current.set(
new Unchecked<>(
new Sticky<>(() -> next)
)
);
}
return this.current.get().value().hasNext();
}

@Override
public X next() {
if (this.hasNext()) {
return this.current.get().value().next();
}
throw new NoSuchElementException();
}
}
new org.cactoos.iterator.Paged<>(first, next)
)
);
}
Expand Down
99 changes: 99 additions & 0 deletions src/main/java/org/cactoos/iterator/Paged.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2017-2020 Yegor Bugayenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.cactoos.iterator;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicReference;
import org.cactoos.Func;
import org.cactoos.Scalar;
import org.cactoos.func.UncheckedFunc;
import org.cactoos.scalar.Sticky;
import org.cactoos.scalar.Unchecked;

/**
* Paged iterator.
* Elements will continue to be provided so long as {@code next} produces
* non-empty iterators.
*
* <p>There is no thread-safety guarantee.
*
* @param <I> Subtype of item iterator
* @param <X> Type of item
* @since 0.49
* @todo #1464:30min We want to use {@code Iterator<X>} directly in the class without
* introducing I, maybe using {@code Iterator<? extends X>} for example because, we don't
* have to constrain the {@link Func} to give exactly the same Iterator type as long as it
* is an iterator that provides X. {@link org.cactoos.iterable.Paged} should be changed too.
*/
public final class Paged<I extends Iterator<X>, X> implements Iterator<X> {

/**
* Current element.
*/
private final AtomicReference<Unchecked<I>> current;

/**
* Function to get the next element.
*/
private final Func<I, I> subsequent;

/**
* Ctor.
* @param first First element.
* @param next Function to get the next element.
*/
public Paged(final Scalar<I> first, final Func<I, I> next) {
this.current =
new AtomicReference<>(
new Unchecked<>(
new Sticky<>(first)
)
);
this.subsequent = next;
}

@Override
public boolean hasNext() {
if (!this.current.get().value().hasNext()) {
final I next = new UncheckedFunc<>(this.subsequent).apply(
this.current.get().value()
);
this.current.set(
new Unchecked<>(
new Sticky<>(() -> next)
)
);
}
return this.current.get().value().hasNext();
}

@Override
public X next() {
if (this.hasNext()) {
return this.current.get().value().next();
}
throw new NoSuchElementException();
}
}

0 comments on commit 4477ddf

Please sign in to comment.