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

io.qameta.allure.tree.AbstractTree Maven / Gradle / Ivy

/*
 *  Copyright 2019 Qameta Software OÜ
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package io.qameta.allure.tree;

import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

/**
 * @param  the type of accepted items
 * @param  the type of tree group
 * @param  the type of tree leaf
 * @author charlie (Dmitry Baev).
 */
public abstract class AbstractTree implements Tree {

    protected final S root;

    private final TreeClassifier treeClassifier;

    private final TreeGroupFactory groupFactory;

    private final TreeLeafFactory leafFactory;

    public AbstractTree(final S root, final TreeClassifier treeClassifier,
                        final TreeGroupFactory groupFactory, final TreeLeafFactory leafFactory) {
        this.root = root;
        this.treeClassifier = treeClassifier;
        this.groupFactory = groupFactory;
        this.leafFactory = leafFactory;
    }

    @Override
    public void add(final T item) {
        getEndNodes(item, root, treeClassifier.classify(item), 0)
                .forEach(node -> {
                    final TreeLeaf leafNode = leafFactory.create(node, item);
                    node.addChild(leafNode);
                });
    }

    protected Stream getEndNodes(final T item, final S node,
                                    final List classifiers,
                                    final int index) {
        if (index >= classifiers.size()) {
            return Stream.of(node);
        }
        final TreeLayer layer = classifiers.get(index);
        return layer.getGroupNames().stream()
                .flatMap(name -> {
                    // @formatter:off
                    final S child = node.findNodeOfType(name, getRootType())
                        .orElseGet(() -> {
                            final S created = groupFactory.create(node, name, item);
                            node.addChild(created);
                            return created;
                        });
                    // @formatter:on
                    return getEndNodes(item, child, classifiers, index + 1);
                });
    }

    @Override
    public String getName() {
        return root.getName();
    }

    @Override
    public List getChildren() {
        return Collections.unmodifiableList(root.getChildren());
    }

    @Override
    public void addChild(final TreeNode node) {
        root.addChild(node);
    }

    protected abstract Class getRootType();

}