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

com.centurylink.mdw.model.workflow.Linked Maven / Gradle / Ivy

There is a newer version: 6.1.39
Show newest version
package com.centurylink.mdw.model.workflow;

import com.centurylink.mdw.model.Jsonable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

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

public class Linked implements Jsonable {

    protected static final int INDENT = 2;

    private T element;
    public T get() { return element; }

    private Linked parent;
    public Linked getParent() { return parent; }
    public void setParent(Linked parent) { this.parent = parent; }

    private List> children = new ArrayList<>();
    public List> getChildren() { return children; }
    public void setChildren(List> children) { this.children = children; }

    private boolean circular;
    public boolean isCircular() { return circular; }
    public void setCircular(boolean snipped) { this.circular = snipped; }

    public Linked(T element) {
        if (element == null)
            throw new NullPointerException("null element");
        this.element = element;
    }

    public JSONObject getJson() throws JSONException {
        return getJson(0);
    }

    /**
     * Includes children (not parent).
     * @param detail level of detail to include in element summary
     */
    public JSONObject getJson(int detail) throws JSONException {
        JSONObject json = create();
        json.put(element.getObjectName(), element.getSummaryJson(detail));
        if (!children.isEmpty()) {
            JSONArray childrenArr = new JSONArray();
            for (Linked child : children) {
                childrenArr.put(child.getJson(detail));
            }
            json.put("children", childrenArr);
        }
        if (isCircular())
            json.put("circular", true);
        return json;
    }

    @Override
    public String toString() {
        return element.getQualifiedLabel() + (isCircular() ? " (+)" : "");
    }

    /**
     * Indented per specified depth
     */
    public String toString(int depth) {
        if (depth == 0) {
            return toString();
        }
        else {
            return String.format("%1$" + (depth * INDENT) + "s", "") + " - " + toString();
        }
    }

    @Override
    public boolean equals(Object o) {
        return o.getClass() == getClass() && ((Linked)o).element.equals(element);
    }

    public String getJsonName() {
        return getClass().getSimpleName();
    }

    /**
     * Remove all branches that don't lead to specified element.
     */
    public void prune(T element) {
        if (element.equals(this.element))
            return;
        Linked caller = this;
        List> toRemove = new ArrayList<>();
        for (Linked child : caller.children) {
            if (!child.contains(element)) {
                toRemove.add(child);
            }
            child.prune(element);
        }
        caller.children.removeAll(toRemove);
    }

    /**
     * Returns true if the call hierarchy contains the specified element.
     */
    public boolean contains(T element) {
        if (element.equals(this.element))
            return true;
        for (Linked child : children) {
            if (child.contains(element))
                return true;
        }
        return false;
    }

    private Linked callChain;  // cached
    /**
     * @return direct line call chain to me
     */
    public Linked getCallChain() {
        if (callChain == null) {
            Linked parent = getParent();
            if (parent == null) {
                callChain = new Linked<>(get());
            }
            else {
                Linked chainedParent = new Linked<>(get());
                while (parent != null) {
                    Linked newParent = new Linked<>(parent.get());
                    newParent.getChildren().add(chainedParent);
                    chainedParent.setParent(newParent);
                    chainedParent = newParent;
                    parent = parent.getParent();
                }
                callChain = chainedParent;
            }
        }
        return callChain;
    }

    public boolean checkCircular() {
        Linked p = getCallChain();
        List called = new ArrayList<>();
        List> c;
        while (!(c = p.getChildren()).isEmpty()) {
            Linked child = c.get(0);
            if (called.contains(child.get())) {
                setCircular(true);
                return true;
            }
            called.add(child.get());
            p = child;
        }
        return false;
    }

    /**
     * Returns all end-of-the-line elements (no children)
     */
    public List> getEnds() {
        List> ends = new ArrayList<>();
        for (Linked child : children) {
            if (child.getChildren().isEmpty()) {
                ends.add(child);
            }
            else {
                ends.addAll(child.getEnds());
            }
        }
        return ends;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy