コード例 #1
0
  /**
   * @param currentElement
   * @param precedingElements
   * @param context
   * @return cellOfElement
   */
  private Cell<BPMNElement> placeElement(
      BPMNElement currentElement, List<LayoutingElement> precedingElements, GridContext context) {
    Cell<BPMNElement> newCell;
    if (precedingElements.isEmpty()) {
      // StartEvents
      context.startCell.setValue(currentElement);
      newCell = context.startCell;
      context.startCell = context.startCell.beneath();
    } else {
      Cell<BPMNElement> leftCell;
      newCell = context.grid.getCellOfItem(currentElement); // not
      // null
      // if
      // join
      if (currentElement.isJoin()) {

        Point tmp;
        boolean splitFound = false;
        BPMNElement split = (BPMNElement) currentElement.prevSplit();
        if (split != null) {
          // get all close splits
          Queue<BPMNElement> splits =
              new PriorityQueue<BPMNElement>(
                  precedingElements.size() / 2, // should be a
                  // good rule of
                  // thumb
                  new BackwardDistanceComperator(currentElement));
          splits.add(split);
          for (LayoutingElement elem : precedingElements) {
            split = (BPMNElement) elem.prevSplit();
            if (split != null && !splits.contains(split)) {
              splits.add(split);
            }
          }
          split = null;
          // get split with most connections
          int maxCon = 0;
          for (BPMNElement target : splits) {
            if (target == currentElement) {
              // beeing my own splits only makes trouble
              continue;
            } else if (target.getParent() != currentElement.getParent()) {

              continue;
            }
            int curCon = 0;
            for (LayoutingElement elem : precedingElements) {
              if (elem.backwardDistanceTo(target) < Integer.MAX_VALUE) {
                curCon++;
              }
            }
            if (curCon > maxCon) {
              maxCon = curCon;
              split = target;
            }
          }
          splitFound = split != null;
        }

        int x = 0;
        int yAcc = 0;
        int yCnt = 0;
        for (LayoutingElement el : precedingElements) {
          BPMNElement elem = (BPMNElement) el;
          tmp = context.grid.find(context.grid.getCellOfItem(elem));
          if (tmp == null) {
            Grid<BPMNElement> preGrid = getContextByElement(elem).grid;
            tmp = preGrid.find(preGrid.getCellOfItem(elem));
            if (tmp == null) {
              tmp = new Point(0, 0);
            }
          } else {
            yAcc += tmp.y;
            yCnt++;
          }
          x = Math.max(x, tmp.x);
        }
        if (splitFound) {

          leftCell = context.grid.getCellOfItem(split).getParent().get(x);
          // set path to split unpackable
          for (Cell<BPMNElement> cCell = leftCell;
              cCell.getValue() != split;
              cCell = cCell.getPrevCell()) {
            cCell.setPackable(false);
          }

        } else {
          if (yCnt == 0) {
            leftCell = context.grid.getFirstRow().above().get(x);
          } else {
            leftCell = context.grid.get(yAcc / yCnt).get(x);
          }
        }
        if (newCell != null && newCell.getValue() == currentElement) {
          newCell.setValue(null);
        }
        newCell = leftCell.after();

        // set all incoming pathes unpackable
        for (LayoutingElement e : precedingElements) {
          BPMNElement el = (BPMNElement) e;
          Cell<BPMNElement> target = context.grid.getCellOfItem(el);
          if (target == null) {
            // don't set unpackable in other grids (other edge
            // layout)
            continue;
          }
          Cell<BPMNElement> start = target.getParent().get(x + 1);
          for (Cell<BPMNElement> cCell = start; cCell != target; cCell = cCell.getPrevCell()) {
            cCell.setPackable(false);
          }
        }

        // if not prelayouted
      } else if (newCell == null) {
        BPMNElement preElem = (BPMNElement) precedingElements.get(0);
        leftCell = context.grid.getCellOfItem(preElem);
        if (leftCell == null) {
          Grid<BPMNElement> preGrid = getContextByElement(preElem).grid;
          Cell<BPMNElement> preCell = preGrid.getCellOfItem(preElem);
          if (preCell == null) {
            System.err.println("Cannot find Cell for " + preElem);
          }

          List<Grid<BPMNElement>> grids = superGrid.getGrids();
          Row<BPMNElement> newRow = null;
          if (grids.indexOf(preGrid) < grids.indexOf(context.grid)) {
            newRow = context.grid.addFirstRow();
          } else {
            newRow = context.grid.addLastRow();
          }
          leftCell = newRow.get(Math.max(0, preCell.getParent().find(preCell)));
        }
        newCell = leftCell.after();
      }
      if (newCell.isFilled() && !newCell.getValue().equals(currentElement)) {
        newCell.getParent().insertRowBeneath();
        newCell = newCell.beneath();
      }
      newCell.setValue(currentElement);
    }
    return newCell;
  }
コード例 #2
0
  /**
   * @param currentElement
   * @param context
   * @param cellOfElement
   */
  private void prelayoutSuccessors(
      BPMNElement currentElement, GridContext context, Cell<BPMNElement> cellOfElement) {
    // preLayout following Elements
    Cell<BPMNElement> baseCell = cellOfElement.after();
    Cell<BPMNElement> topCell = baseCell;
    List<LayoutingElement> followingElements = currentElement.getFollowingElements();

    if (BPMNType.isAActivity(currentElement.getType())) {
      // special case for docked events
      List<BPMNElement> dockedEventFollowers = new LinkedList<BPMNElement>();
      for (LayoutingElement el : currentElement.getOutgoingLinks()) {
        BPMNElement element = (BPMNElement) el;
        if (element.isADockedIntermediateEvent()) {
          for (LayoutingElement follower : element.getFollowingElements()) {
            dockedEventFollowers.add((BPMNElement) follower);
          }
        }
      }
      // to avoid crossing edges if there is more than one
      // docked event
      Collections.reverse(dockedEventFollowers);

      // put them under the task
      Cell<BPMNElement> insertCell = baseCell;
      for (BPMNElement dockedEventFollower : dockedEventFollowers) {
        Cell<BPMNElement> oldCell = context.grid.getCellOfItem(dockedEventFollower);
        if (oldCell != null) {
          if (oldCell.getValue() == dockedEventFollower) {
            continue; // Bug-Workaround: Don't prelayout
            // layouted elements;
          }
        }
        insertCell.getParent().insertRowBeneath();
        insertCell = insertCell.beneath();
        context.grid.setCellOfItem(dockedEventFollower, insertCell); // prelayout
      }

      // remove them from the following processing
      followingElements.removeAll(dockedEventFollowers);
    }

    // heuristic for text- & data-objects: put them to the top
    List<BPMNElement> textAnnotations = new LinkedList<BPMNElement>();
    List<BPMNElement> dataObjects = new LinkedList<BPMNElement>();
    for (LayoutingElement el : followingElements) {
      BPMNElement e = (BPMNElement) el;
      if (e.getType().equals(BPMNType.TextAnnotation)) {
        textAnnotations.add(e);
      } else if (e.getType().equals(BPMNType.DataObject)) {
        dataObjects.add(e);
      }
    }
    followingElements.removeAll(textAnnotations);
    followingElements.removeAll(dataObjects);
    // add them at the front
    followingElements.addAll(0, dataObjects);
    followingElements.addAll(0, textAnnotations);

    // heuristic for direct connection to join
    BPMNElement directJoin = null;
    for (LayoutingElement possibleJoin : followingElements) {
      if (possibleJoin.isJoin()) {
        directJoin = (BPMNElement) possibleJoin;
      }
    }
    if (directJoin != null) {
      // put in the middle
      followingElements.remove(directJoin);
      int position = (followingElements.size() / 2);
      followingElements.add(position, directJoin);
    }

    // normal preLayout following Elements
    int follow = 0;
    for (LayoutingElement newElem : followingElements) {
      if (newElem.getParent() == currentElement.getParent()) {
        follow++;
      }
    }
    for (int i = 0; i < follow / 2; i++) {
      topCell.getParent().insertRowAbove();
      baseCell.getParent().insertRowBeneath();
      topCell = topCell.above();
    }

    for (LayoutingElement newElem : followingElements) {
      if (newElem.getParent() != currentElement.getParent()) {
        continue;
      }
      context.grid.setCellOfItem((BPMNElement) newElem, topCell); // prelayout
      topCell = topCell.beneath();
      if (topCell == baseCell && follow % 2 == 0) {
        // skip baseCell if an even amount of elements is
        // following
        topCell = topCell.beneath();
      }
    }
  }