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

org.umlg.runtime.collection.persistent.PropertyTree Maven / Gradle / Ivy

The newest version!
package org.umlg.runtime.collection.persistent;

import org.apache.commons.collections4.set.ListOrderedSet;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer;
import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
import org.apache.tinkerpop.gremlin.structure.*;
import org.umlg.runtime.collection.UmlgRuntimeProperty;
import org.umlg.runtime.util.PathTree;

import java.util.*;

import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;

/**
 * Date: 2016/05/24
 * Time: 8:24 PM
 */
public class PropertyTree {

    //Only the root may have an label
    private String label;
    private UmlgRuntimeProperty umlgRuntimeProperty;
    private PropertyTree parent;
    private ListOrderedSet children = new ListOrderedSet<>();
    private Set hasContainers = new HashSet<>();

    public void addHasContainer(HasContainer hasContainer) {
        this.hasContainers.add(hasContainer);
    }

    private PropertyTree(String label) {
        this.label = label;
    }

    private PropertyTree(UmlgRuntimeProperty umlgRuntimeProperty) {
        this.umlgRuntimeProperty = umlgRuntimeProperty;
    }

    public static PropertyTree from(UmlgRuntimeProperty umlgRuntimeProperty) {
        return new PropertyTree(umlgRuntimeProperty);
    }

    public static PropertyTree from(String label) {
        return new PropertyTree(label);
    }

    public PropertyTree addChild(PropertyTree propertyTree) {
        this.children.add(propertyTree);
        propertyTree.parent = this;
        return propertyTree;
    }

    public PropertyTree addChild(UmlgRuntimeProperty umlgRuntimeProperty) {
        PropertyTree propertyTree = PropertyTree.from(umlgRuntimeProperty);
        return addChild(propertyTree);
    }

    public UmlgRuntimeProperty getUmlgRuntimeProperty() {
        return umlgRuntimeProperty;
    }

    public List traversal(Graph graph) {
        GraphTraversal traversal = graph.traversal().V().hasLabel(this.label).as(this.label);
        for (HasContainer hasContainer : this.hasContainers) {
            traversal.has(hasContainer.getKey(), hasContainer.getPredicate());
        }
        List> traversals = walk(traversal);
        List pathTree = PathTree.from(traversals);
        return pathTree;
    }

    public List traversal(Graph graph, Vertex vertex) {
        PropertyTree rootPropertyTree = PropertyTree.from("Root");
        rootPropertyTree.addChild(this);
        GraphTraversal traversal = graph.traversal().V(vertex).as("Root");
        List> traversals = walk(traversal);
        List pathTree = PathTree.from(traversals);
        return pathTree;
    }

    List> walk(GraphTraversal traversal) {
        Set leafNodes = leafNodes();
        List> graphTraversals = new ArrayList<>();
        for (PropertyTree leafNode : leafNodes) {
            GraphTraversal leafTraversal = null;
            List rootToLeafPropertyTrees = rootToLeaf(leafNode);
            for (PropertyTree node : rootToLeafPropertyTrees) {
                if (leafTraversal == null) {
                    if (node.umlgRuntimeProperty.isControllingSide()) {
                        leafTraversal = __.outE(node.label()).as("e_" + node.umlgRuntimeProperty.getLabel()).inV();
                        for (HasContainer hasContainer : node.hasContainers) {
                            leafTraversal.has(hasContainer.getKey(), hasContainer.getPredicate());
                        }
                        if (node.umlgRuntimeProperty.isOrdered()) {
                            leafTraversal.order()
                                    .by(select("e_" + node.umlgRuntimeProperty.getLabel())
                                            .by(BaseCollection.IN_EDGE_SEQUENCE_ID), Order.asc);
                        }
                    } else {
                        leafTraversal = __.inE(node.label()).as("e_" + node.umlgRuntimeProperty.getLabel()).outV();
                        for (HasContainer hasContainer : node.hasContainers) {
                            leafTraversal.has(hasContainer.getKey(), hasContainer.getPredicate());
                        }
                        if (node.umlgRuntimeProperty.isOrdered()) {
                            leafTraversal.order()
                                    .by(select("e_" + node.umlgRuntimeProperty.getLabel())
                                            .by(BaseCollection.OUT_EDGE_SEQUENCE_ID), Order.asc);
                        }
                        leafTraversal = __.local(__.optional(leafTraversal));
                    }
                } else {
                    if (node.umlgRuntimeProperty.isControllingSide()) {
                        GraphTraversal tmpTraversal = __.outE(node.label()).as("e_" + node.umlgRuntimeProperty.getLabel()).inV();
                        for (HasContainer hasContainer : node.hasContainers) {
                            tmpTraversal.has(hasContainer.getKey(), hasContainer.getPredicate());
                        }
                        if (node.umlgRuntimeProperty.isOrdered()) {
                            tmpTraversal.order()
                                    .by(select("e_" + node.umlgRuntimeProperty.getLabel())
                                            .by(BaseCollection.IN_EDGE_SEQUENCE_ID), Order.asc);
                        }
                        leafTraversal.local(__.optional(tmpTraversal));
                    } else {
                        GraphTraversal tmpTraversal = __.inE(node.label()).as("e_" + node.umlgRuntimeProperty.getLabel()).outV();
                        for (HasContainer hasContainer : node.hasContainers) {
                            tmpTraversal.has(hasContainer.getKey(), hasContainer.getPredicate());
                        }
                        if (node.umlgRuntimeProperty.isOrdered()) {
                            tmpTraversal.order()
                                    .by(select("e_" + node.umlgRuntimeProperty.getLabel())
                                            .by(BaseCollection.OUT_EDGE_SEQUENCE_ID), Order.asc);
                        }
                        leafTraversal.local(__.optional(tmpTraversal));
                    }
                }
            }
            if (leafTraversal != null) {
                graphTraversals.add(traversal.asAdmin().clone().local(__.optional(leafTraversal)).path());
            }
        }
        if (graphTraversals.isEmpty()) {
            graphTraversals.add(traversal.path());
        }
        return graphTraversals;
    }

    private List rootToLeaf(PropertyTree leafNode) {
        List result = new ArrayList<>();
        PropertyTree tmp = leafNode;
        while (tmp.parent != null) {
            result.add(0, tmp);
            tmp = tmp.parent;
        }
        return result;
    }

//    /**
//     * g.V(id).local(
//     * optional(
//     * outE().as('e')
//     * )
//     * )
//     *
//     * @param traversal
//     */
//    void walk(GraphTraversal traversal) {
//        Set leafNodes = leafNodes();
//        List> graphTraversals = new ArrayList<>();
//        for (PropertyTree leafNode : leafNodes) {
//            PropertyTree node = leafNode;
//            GraphTraversal leafTraversal = null;
//            while (node.parent != null) {
//                if (leafTraversal == null) {
//                    if (node.umlgRuntimeProperty.isControllingSide()) {
//                        leafTraversal = __.outE(label()).as("e2").inV().order().by(T.label);
//                    } else {
//                        leafTraversal = __.inE(label()).as("e2").inV().order().by(T.label);
//                    }
//                } else {
//                    if (node.umlgRuntimeProperty.isControllingSide()) {
//                        leafTraversal =
//                                __.outE(label()).as("e2").inV().order().by(T.label)
//                                        .local(
//                                                __.optional(
//                                                        leafTraversal
//                                                )
//                                        );
//                    } else {
//                        leafTraversal =
//                                __.inE(label()).as("e2").inV().order().by(T.label)
//                                        .local(
//                                                __.optional(
//                                                        leafTraversal
//                                                )
//                                        );
//                    }
//                }
//                node = node.parent;
//            }
//            graphTraversals.add(__.local(__.optional(leafTraversal)));
//        }
//    }

//    void walk(GraphTraversal traversal) {
//        if (!this.children.isEmpty() && this.childrenAreUnique()) {
//            Traversal outInnerTraversal = outInnerTraversal();
//            if (!(outInnerTraversal instanceof EmptyTraversal)) {
//                for (PropertyTree child : children) {
//                    child.walk((GraphTraversal) outInnerTraversal);
//                }
//            }
//
//            Traversal inInnerTraversal = inInnerTraversal();
//            if (!(inInnerTraversal instanceof EmptyTraversal)) {
//                for (PropertyTree child : children) {
//                    child.walk((GraphTraversal) inInnerTraversal);
//                }
//            }
//            if (!(outInnerTraversal instanceof EmptyTraversal) && !(inInnerTraversal instanceof EmptyTraversal)) {
//                GraphTraversal tmpOut = traversal.asAdmin().clone().optional(outInnerTraversal);
//                GraphTraversal tmpIn = traversal.asAdmin().clone().optional(inInnerTraversal);
//                traversal.union(tmpOut, tmpIn);
//            } else if (!(outInnerTraversal instanceof EmptyTraversal)) {
//                traversal.optional(outInnerTraversal);
//            } else if (!(inInnerTraversal instanceof EmptyTraversal)) {
//                traversal.optional(inInnerTraversal);
//            } else {
//                throw new IllegalStateException();
//            }
//        }
//    }

    private Traversal outInnerTraversal() {
        String[] labels = outLabels();
        Traversal innerTraversal;
        if (labels.length == 1) {
            innerTraversal = __.toE(Direction.OUT, labels).as("e_" + labels[0]).otherV();
            Set hasContainers = getChildrenHasContainers();
            for (HasContainer hasContainer : hasContainers) {
                ((GraphTraversal) innerTraversal).has(hasContainer.getKey(), hasContainer.getPredicate());
            }
        } else if (labels.length > 1) {
            String[] edgeLabels = Arrays.copyOfRange(labels, 1, labels.length);
            for (int i = 0; i < edgeLabels.length; i++) {
                edgeLabels[i] = "e_" + edgeLabels[i];
            }
            innerTraversal = __.toE(Direction.OUT, labels).as("e_" + labels[0], edgeLabels).otherV();
            Set hasContainers = getChildrenHasContainers();
            for (HasContainer hasContainer : hasContainers) {
                ((GraphTraversal) innerTraversal).has(hasContainer.getKey(), hasContainer.getPredicate());
            }
        } else {
            innerTraversal = EmptyTraversal.instance();
        }
        return innerTraversal;
    }

    private Traversal inInnerTraversal() {
        String[] labels = inLabels();
        Traversal innerTraversal;
        if (labels.length == 1) {
            innerTraversal = __.toE(Direction.IN, labels).as("e_" + labels[0]).otherV();
            Set hasContainers = getChildrenHasContainers();
            for (HasContainer hasContainer : hasContainers) {
                ((GraphTraversal) innerTraversal).has(hasContainer.getKey(), hasContainer.getPredicate());
            }
        } else if (labels.length > 1) {
            String[] edgeLabels = Arrays.copyOfRange(labels, 1, labels.length);
            for (int i = 0; i < edgeLabels.length; i++) {
                edgeLabels[i] = "e_" + edgeLabels[i];
            }
            innerTraversal = __.toE(Direction.IN, labels).as("e_" + labels[0], edgeLabels).otherV();
            Set hasContainers = getChildrenHasContainers();
            for (HasContainer hasContainer : hasContainers) {
                ((GraphTraversal) innerTraversal).has(hasContainer.getKey(), hasContainer.getPredicate());
            }
        } else {
            innerTraversal = EmptyTraversal.instance();
        }
        return innerTraversal;
    }


    private void applyOrder(GraphTraversal traversal) {
        if (this.umlgRuntimeProperty != null && this.umlgRuntimeProperty.isOrdered()) {
            traversal = traversal.order().by(
                    select("e_" + this.umlgRuntimeProperty.getLabel()).by(
                            this.umlgRuntimeProperty.isControllingSide() ? BaseCollection.IN_EDGE_SEQUENCE_ID : BaseCollection.OUT_EDGE_SEQUENCE_ID
                    ), Order.asc);
        }
        for (PropertyTree child : this.children) {
            child.applyOrder(traversal);
        }
    }

    private String[] labels() {
        List result = new ArrayList<>();
        for (PropertyTree child : this.children) {
            result.add(child.label());
        }
        return result.toArray(new String[result.size()]);
    }

    private String[] outLabels() {
        List result = new ArrayList<>();
        for (PropertyTree child : this.children) {
            if (child.getUmlgRuntimeProperty().isControllingSide()) {
                result.add(child.label());
            }
        }
        return result.toArray(new String[result.size()]);
    }

    private String[] inLabels() {
        List result = new ArrayList<>();
        for (PropertyTree child : this.children) {
            if (!child.getUmlgRuntimeProperty().isControllingSide()) {
                result.add(child.label());
            }
        }
        return result.toArray(new String[result.size()]);
    }

    private Set getChildrenHasContainers() {
        Set result = new HashSet<>();
        for (PropertyTree child : this.children) {
            if (child.getUmlgRuntimeProperty().isControllingSide() && !child.hasContainers.isEmpty()) {
                result.addAll(child.hasContainers);
            }
        }
        return result;
    }

    private boolean childrenAreUnique() {
        Set labels = new HashSet<>();
        for (PropertyTree child : this.children) {
            if (labels.contains(child.label())) {
                return false;
            } else {
                labels.add(child.label());
            }
        }
        return true;
    }

    public Set leafNodes() {
        Set leafNodes = new HashSet<>();
        leafNodes(leafNodes);
        return leafNodes;
    }

    private void leafNodes(Set leafNodes) {
        if (this.children.isEmpty()) {
            leafNodes.add(this);
        }
        for (PropertyTree child : this.children) {
            child.leafNodes(leafNodes);
        }
    }

    private String label() {
        return this.umlgRuntimeProperty.getLabel();
    }

    public ListOrderedSet getChildren() {
        return this.children;
    }

    @Override
    public String toString() {
        if (this.umlgRuntimeProperty == null) {
            return "Root " + label;
        } else {
            return this.umlgRuntimeProperty.getLabel();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy