All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.mike10004.containment.lifecycle.LifecycleStackElement Maven / Gradle / Ivy

There is a newer version: 0.6
Show newest version
package io.github.mike10004.containment.lifecycle;

import java.util.ArrayList;
import java.util.List;

import static java.util.Objects.requireNonNull;

/**
 * Element of a lifestyle stack. A stack element has a corresponding lifecycle
 * stage and a link to stack element corresponding to the previous stage in the
 * lifecycle. The first lifecycle stack element is the root and has no previous stage.
 * The root stack element is created by {@link LifecycleStack#startingAt(Lifecycle)}.
 * Add stages with {@link #andThen(LifecycleStage)}.
 * When all stages have been added, build the multi-stage lifecycle
 * with {@link #toSequence()}.
 * @param  type of resource produced by the stage corresponding to this element
 */
public class LifecycleStackElement {

    private final LifecycleStackElement parent;
    private final LifecycleStage stage;

    private  LifecycleStackElement(LifecycleStackElement parent, LifecycleStage stage) {
        this.parent = parent;
        this.stage = requireNonNull(stage);
    }

    static  LifecycleStackElement root(LifecycleStage content) {
        return new LifecycleStackElement<>(null, content);
    }

    /**
     * Builds a lifecycle that is the sequence of stages starting at the root and finishing with this element's stage.
     * @return a new lifecycle instance
     */
    public Lifecycle toSequence() {
        return new LifecycleStack<>(toSequence(new ArrayList<>()));
    }

    /**
     * Adds a stage, creating a new stack element.
     * @param stage stage
     * @param  type of resource produced by the next stage
     * @return a new stack element containing argument stage and all previously-added stage
     */
    public  LifecycleStackElement andThen(LifecycleStage stage) {
        return new LifecycleStackElement<>(this, stage);
    }

    private List> toSequence(List> list) {
        if (parent != null) {
            parent.toSequence(list);
        }
        list.add(stage);
        return list;
    }
}