Skip to content

Allow Subclasses in the CompositeItemReader #2

Closed
@berse2212

Description

@berse2212

I am currently trying out the CompositeItemReader. In my use case the two Delegates are RepositoryItemReader created via the Builder .

Now my two RepositoryItemReader do not return the exact same class but one that have a shared parent in their hierarchy.

E.g.:

public class Animal { }

class Duck extends Animal {}

class Dog extends Animal {}

This results in me having a RepositoryItemReader<Duck> and RepositoryItemReader<Dog>. Unfortunately the current implementation doesn't allow such a constellation. Both need to be (unsavely) cast to a RepositoryItemReader<Animal>

So my proposition ist to make the CompositeItemReader less restrictive and allow the delegates to read the same subclass while still having the same return value from the read-method:

/**
 * Composite reader that delegates reading to a list of {@link ItemStreamReader}s.
 * This implementation is not thread-safe and not restartable.
 *
 * @param <T> type of objects to read
 * @author Mahmoud Ben Hassine
 */
public class CompositeItemReader<T> implements ItemStreamReader<T> {

    private final List<ItemStreamReader<? extends T>> delegates;

    private final Iterator<ItemStreamReader<? extends T>> delegatesIterator;

    private ItemStreamReader<? extends T> currentDelegate;

    public CompositeItemReader(List<ItemStreamReader<? extends T>> delegates) {
        this.delegates = delegates;
        this.delegatesIterator = this.delegates.iterator();
        this.currentDelegate = this.delegatesIterator.hasNext() ? this.delegatesIterator.next() : null;
    }

    @Override
    public void open(@NonNull ExecutionContext executionContext) throws ItemStreamException {
        for (ItemStreamReader<? extends T> delegate : delegates) {
            delegate.open(executionContext);
        }
    }

    @Override
    public T read() throws Exception {
        if (this.currentDelegate == null) {
            return null;
        }
        T item = currentDelegate.read();
        if (item == null) {
            currentDelegate = this.delegatesIterator.hasNext() ? this.delegatesIterator.next() : null;
            return read();
        }
        return item;
    }

    @Override
    public void close() throws ItemStreamException {
        for (ItemStreamReader<? extends T> delegate : delegates) {
            delegate.close();
        }
    }
}

p.s. I would gladly create a fitting PR if this suggestion get's approved!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions