summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java')
-rw-r--r--framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java307
1 files changed, 0 insertions, 307 deletions
diff --git a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java b/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
deleted file mode 100644
index 1c0e7313..00000000
--- a/framework/src/onos/utils/stc/src/main/java/org/onlab/stc/MonitorLayout.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 org.onlab.stc;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-/**
- * Computes scenario process flow layout for the Monitor GUI.
- */
-public class MonitorLayout {
-
- public static final int WIDTH = 210;
- public static final int HEIGHT = 30;
- public static final int W_GAP = 40;
- public static final int H_GAP = 50;
- public static final int SLOT_WIDTH = WIDTH + H_GAP;
-
- private final Compiler compiler;
- private final ProcessFlow flow;
-
- private Map<Step, Box> boxes = Maps.newHashMap();
-
- /**
- * Creates a new shared process flow monitor.
- *
- * @param compiler scenario compiler
- */
- MonitorLayout(Compiler compiler) {
- this.compiler = compiler;
- this.flow = compiler.processFlow();
-
- // Extract the flow and create initial bounding boxes.
- boxes.put(null, new Box(null, 0));
- flow.getVertexes().forEach(this::createBox);
-
- computeLayout(null, 0, 1);
- }
-
- // Computes the graph layout giving preference to group associations.
- private void computeLayout(Group group, int absoluteTier, int tier) {
- Box box = boxes.get(group);
-
- // Find all children of the group, or items with no group if at top.
- Set<Step> children = group != null ? group.children() :
- flow.getVertexes().stream().filter(s -> s.group() == null)
- .collect(Collectors.toSet());
-
- children.forEach(s -> visit(s, absoluteTier, 1, group));
-
- // Figure out what the group root vertexes are.
- Set<Step> roots = findRoots(group);
-
- // Compute the boxes for each of the roots.
- roots.forEach(s -> updateBox(s, absoluteTier + 1, 1, group));
-
- // Update the tier and depth of the group bounding box.
- computeTiersAndDepth(group, box, absoluteTier, tier, children);
-
- // Compute the minimum breadth of this group's bounding box.
- computeBreadth(group, box, children);
-
- // Compute child placements
- computeChildPlacements(group, box, children);
- }
-
- // Updates the box for the specified step, given the tier number, which
- // is relative to the parent.
- private Box updateBox(Step step, int absoluteTier, int tier, Group group) {
- Box box = boxes.get(step);
- if (step instanceof Group) {
- computeLayout((Group) step, absoluteTier, tier);
- } else {
- box.setTierAndDepth(absoluteTier, tier, 1, group);
- }
-
- // Follow the steps downstream of this one.
- follow(step, absoluteTier + box.depth(), box.tier() + box.depth());
- return box;
- }
-
- // Backwards follows edges leading towards the specified step to visit
- // the source vertex and compute layout of those vertices that had
- // sufficient number of visits to compute their tier.
- private void follow(Step step, int absoluteTier, int tier) {
- Group from = step.group();
- flow.getEdgesTo(step).stream()
- .filter(d -> visit(d.src(), absoluteTier, tier, from))
- .forEach(d -> updateBox(d.src(), absoluteTier, tier, from));
- }
-
- // Visits each step, records maximum tier and returns true if this
- // was the last expected visit.
- private boolean visit(Step step, int absoluteTier, int tier, Group from) {
- Box box = boxes.get(step);
- return box.visitAndLatchMaxTier(absoluteTier, tier, from);
- }
-
- // Computes the absolute and relative tiers and the depth of the group
- // bounding box.
- private void computeTiersAndDepth(Group group, Box box,
- int absoluteTier, int tier, Set<Step> children) {
- int depth = children.stream().mapToInt(this::bottomMostTier).max().getAsInt();
- box.setTierAndDepth(absoluteTier, tier, depth, group);
- }
-
- // Returns the bottom-most tier this step occupies relative to its parent.
- private int bottomMostTier(Step step) {
- Box box = boxes.get(step);
- return box.tier() + box.depth();
- }
-
- // Computes breadth of the specified group.
- private void computeBreadth(Group group, Box box, Set<Step> children) {
- if (box.breadth() == 0) {
- // Scan through all tiers and determine the maximum breadth of each.
- IntStream.range(1, box.depth)
- .forEach(t -> computeTierBreadth(t, box, children));
- box.latchBreadth(children.stream()
- .mapToInt(s -> boxes.get(s).breadth())
- .max().getAsInt());
- }
- }
-
- // Computes tier width.
- private void computeTierBreadth(int t, Box box, Set<Step> children) {
- box.latchBreadth(children.stream().map(boxes::get)
- .filter(b -> isSpanningTier(b, t))
- .mapToInt(Box::breadth).sum());
- }
-
- // Computes the actual child box placements relative to the parent using
- // the previously established tier, depth and breadth attributes.
- private void computeChildPlacements(Group group, Box box,
- Set<Step> children) {
- // Order the root-nodes in alphanumeric order first.
- List<Box> tierBoxes = Lists.newArrayList(boxesOnTier(1, children));
- tierBoxes.sort((a, b) -> a.step().name().compareTo(b.step().name()));
-
- // Place the boxes centered on the parent box; left to right.
- int tierBreadth = tierBoxes.stream().mapToInt(Box::breadth).sum();
- int slot = 1;
- for (Box b : tierBoxes) {
- b.updateCenter(1, slot(slot, tierBreadth));
- slot += b.breadth();
- }
- }
-
- // Returns the horizontal offset off the parent center.
- private int slot(int slot, int tierBreadth) {
- boolean even = tierBreadth % 2 == 0;
- int multiplier = -tierBreadth / 2 + slot - 1;
- return even ? multiplier * SLOT_WIDTH + SLOT_WIDTH / 2 : multiplier * SLOT_WIDTH;
- }
-
- // Returns a list of all child step boxes that start on the specified tier.
- private List<Box> boxesOnTier(int tier, Set<Step> children) {
- return boxes.values().stream()
- .filter(b -> b.tier() == tier && children.contains(b.step()))
- .collect(Collectors.toList());
- }
-
- // Determines whether the specified box spans, or occupies a tier.
- private boolean isSpanningTier(Box b, int tier) {
- return (b.depth() == 1 && b.tier() == tier) ||
- (b.tier() <= tier && tier < b.tier() + b.depth());
- }
-
-
- // Determines roots of the specified group or of the entire graph.
- private Set<Step> findRoots(Group group) {
- Set<Step> steps = group != null ? group.children() : flow.getVertexes();
- return steps.stream().filter(s -> isRoot(s, group)).collect(Collectors.toSet());
- }
-
- private boolean isRoot(Step step, Group group) {
- if (step.group() != group) {
- return false;
- }
-
- Set<Dependency> requirements = flow.getEdgesFrom(step);
- return requirements.stream().filter(r -> r.dst().group() == group)
- .collect(Collectors.toSet()).isEmpty();
- }
-
- /**
- * Returns the bounding box for the specified step. If null is given, it
- * returns the overall bounding box.
- *
- * @param step step or group; null for the overall bounding box
- * @return bounding box
- */
- public Box get(Step step) {
- return boxes.get(step);
- }
-
- /**
- * Returns the bounding box for the specified step name. If null is given,
- * it returns the overall bounding box.
- *
- * @param name name of step or group; null for the overall bounding box
- * @return bounding box
- */
- public Box get(String name) {
- return get(name == null ? null : compiler.getStep(name));
- }
-
- // Creates a bounding box for the specified step or group.
- private void createBox(Step step) {
- boxes.put(step, new Box(step, flow.getEdgesFrom(step).size()));
- }
-
- /**
- * Bounding box data for a step or group.
- */
- final class Box {
-
- private Step step;
- private int remainingRequirements;
-
- private int absoluteTier = 0;
- private int tier;
- private int depth = 1;
- private int breadth;
- private int center, top;
-
- private Box(Step step, int remainingRequirements) {
- this.step = step;
- this.remainingRequirements = remainingRequirements + 1;
- breadth = step == null || step instanceof Group ? 0 : 1;
- }
-
- private void latchTiers(int absoluteTier, int tier, Group from) {
- this.absoluteTier = Math.max(this.absoluteTier, absoluteTier);
- if (step == null || step.group() == from) {
- this.tier = Math.max(this.tier, tier);
- }
- }
-
- public void latchBreadth(int breadth) {
- this.breadth = Math.max(this.breadth, breadth);
- }
-
- void setTierAndDepth(int absoluteTier, int tier, int depth, Group from) {
- latchTiers(absoluteTier, tier, from);
- this.depth = depth;
- }
-
- boolean visitAndLatchMaxTier(int absoluteTier, int tier, Group from) {
- latchTiers(absoluteTier, tier, from);
- --remainingRequirements;
- return remainingRequirements == 0;
- }
-
- Step step() {
- return step;
- }
-
- public int absoluteTier() {
- return absoluteTier;
- }
-
- int tier() {
- return tier;
- }
-
- int depth() {
- return depth;
- }
-
- int breadth() {
- return breadth;
- }
-
- int top() {
- return top;
- }
-
- int center() {
- return center;
- }
-
- public void updateCenter(int top, int center) {
- this.top = top;
- this.center = center;
- }
- }
-}