Example #1
0
 /** Must be called on process execution thread! Gets infos about the current threads. */
 protected ProcessThreadInfo[] getThreadInfos() {
   List ret = null;
   ThreadContext tc = instance.getThreadContext();
   Set threads = tc.getAllThreads();
   if (threads != null) {
     ret = new ArrayList();
     for (Iterator it = threads.iterator(); it.hasNext(); ) {
       ProcessThread pt = (ProcessThread) it.next();
       ret.add(
           new ProcessThreadInfo(
               pt.getId(),
               pt.getActivity(), // pt.getLastEdge(),
               pt.getException(),
               pt.isWaiting(),
               pt.getData() == null ? new HashMap() : new HashMap(pt.getData())));
     }
   }
   return (ProcessThreadInfo[]) ret.toArray(new ProcessThreadInfo[ret.size()]);
 }
Example #2
0
  /** Create an agenda panel. */
  public ProcessViewPanel(final BpmnInterpreter instance, IBreakpointPanel bpp) {
    this.instance = instance;
    this.bpp = bpp;
    this.ptmodel = new ProcessThreadModel();
    this.hmodel = new HistoryModel();

    // todo: problem should be called on process execution thread!
    instance.setHistoryEnabled(true); // Todo: Disable history on close?

    threads_clone = getThreadInfos();
    history_clone = instance.getHistory().toArray();

    TableSorter sorter = new TableSorter(ptmodel);
    this.threads = new JTable(sorter);
    ResizeableTableHeader header = new ResizeableTableHeader(threads.getColumnModel());
    header.setIncludeHeaderWidth(true);
    //		threads.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    threads.setTableHeader(header);
    threads.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    sorter.setTableHeader(header);
    threads.getColumnModel().setColumnMargin(10);

    sorter = new TableSorter(hmodel);
    this.history = new JTable(sorter);
    header = new ResizeableTableHeader(history.getColumnModel());
    header.setIncludeHeaderWidth(true);
    //		history.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    history.setTableHeader(header);
    history.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    sorter.setTableHeader(header);
    history.getColumnModel().setColumnMargin(10);

    this.listener =
        new IChangeListener() {
          ProcessThreadInfo[] threads_clone;
          Object[] history_clone;
          Object next;
          boolean invoked;

          public void changeOccurred(ChangeEvent event) {
            synchronized (ProcessViewPanel.this) {
              List his = instance.getHistory();
              threads_clone = getThreadInfos();
              history_clone = his != null ? his.toArray() : new Object[0];
              //					next	= instance.getNextActivation();
            }
            if (!invoked) {
              invoked = true;
              SwingUtilities.invokeLater(
                  new Runnable() {
                    public void run() {
                      invoked = false;
                      synchronized (ProcessViewPanel.this) {
                        ProcessViewPanel.this.threads_clone = threads_clone;
                        ProcessViewPanel.this.history_clone = history_clone;
                        ProcessViewPanel.this.next = next;
                      }
                      updateViews();
                    }
                  });
            }
          }
        };
    instance.addChangeListener(listener);

    SwingUtilities.invokeLater(
        new Runnable() {
          public void run() {
            updateViews();
          }
        });

    JButton clear = new JButton("Clear");
    clear.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // todo: invoke on agent thread with invoke later
            // works because history is synchronized.
            List his = instance.getHistory();
            if (his != null) {
              his.clear();
              history_clone = new Object[0];
              history.repaint();
            }
          }
        });

    final JCheckBox hon = new JCheckBox("Store History");
    hon.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // todo: invoke on agent thread with invoke later
            instance.setHistoryEnabled(hon.isSelected());
          }
        });
    hon.setSelected(true);

    JPanel procp = new JPanel(new BorderLayout());
    procp.add(new JScrollPane(threads));
    procp.setBorder(BorderFactory.createTitledBorder("Processes"));

    JPanel historyp = new JPanel(new BorderLayout());
    historyp.add(new JScrollPane(history));
    historyp.setBorder(BorderFactory.createTitledBorder("History"));

    JPanel buts = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    buts.add(hon);
    buts.add(clear);
    historyp.add(buts, BorderLayout.SOUTH);

    JSplitPane tmp = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    tmp.add(procp);
    tmp.add(historyp);
    tmp.setDividerLocation(200); // Hack?!

    setLayout(new BorderLayout());
    add(tmp, BorderLayout.CENTER);
  }
  /**
   * Make a process step, i.e. find the next edge or activity for a just executed thread.
   *
   * @param activity The activity to execute.
   * @param instance The process instance.
   * @param thread The process thread.
   */
  public void step(
      MActivity activity, BpmnInterpreter instance, ProcessThread thread, Object event) {
    //		System.out.println(instance.getComponentIdentifier().getLocalName()+": step "+activity+",
    // data "+thread.getData());

    // Hack!!! Should be in interpreter/thread?
    thread.updateParametersAfterStep(activity, instance);

    MNamedIdElement next = null;
    ThreadContext remove = null; // Context that needs to be removed (if any).
    Exception ex = thread.getException();

    // Store event (if any).
    if (event != null) {
      thread.setParameterValue("$event", event);
      //			System.out.println("Event: "+activity+" "+thread+" "+event);
    }

    // Timer occurred flow
    if (AbstractEventIntermediateTimerActivityHandler.TIMER_EVENT.equals(event)) {
      // Cancel subflows.
      remove = thread.getThreadContext().getSubcontext(thread);

      // Continue with timer edge.
      List outedges = activity.getOutgoingSequenceEdges();
      if (outedges != null && outedges.size() == 1) {
        next = (MSequenceEdge) outedges.get(0);
      } else if (outedges != null && outedges.size() > 1) {
        throw new RuntimeException("Cannot determine outgoing edge: " + activity);
      }
    }

    // Find next element and context(s) to be removed.
    else {
      boolean outside = false;
      ThreadContext context = thread.getThreadContext();
      while (next == null && !outside) {
        // Normal flow
        if (ex == null) {
          List outgoing = activity.getOutgoingSequenceEdges();
          if (outgoing != null && outgoing.size() == 1) {
            next = (MSequenceEdge) outgoing.get(0);
          } else if (outgoing != null && outgoing.size() > 1) {
            throw new UnsupportedOperationException(
                "Activity has more than one one outgoing edge. Please overridge step() for disambiguation: "
                    + activity);
          }
          // else no outgoing edge -> check parent context, if any.
        }

        // Exception flow.
        else {
          List handlers = activity.getEventHandlers();
          for (int i = 0; handlers != null && next == null && i < handlers.size(); i++) {
            MActivity handler = (MActivity) handlers.get(i);
            if (handler.getActivityType().equals("EventIntermediateError")) {
              // Todo: match exception types.
              //						Class	clazz	= handler.getName()!=null ? SReflect.findClass0(clname, imports,
              // classloader);
              next = handler;
            }
          }
        }

        outside = context.getParent() == null;
        if (next == null && !outside) {
          // When last thread or exception, mark current context for removal.
          if (context.getThreads().size() == 1 || ex != null) {
            activity = (MActivity) context.getModelElement();
            remove = context;
            context = context.getParent();

            // Cancel subprocess handlers.
            if (activity instanceof MSubProcess) {
              List handlers = activity.getEventHandlers();
              for (int i = 0; handlers != null && i < handlers.size(); i++) {
                MActivity handler = (MActivity) handlers.get(i);
                instance
                    .getActivityHandler(handler)
                    .cancel(handler, instance, remove.getInitiator());
              }
            }
          }

          // If more threads are available in current context just exit loop.
          else if (context.getThreads().size() > 1) {
            outside = true;
          }
        }
      }
    }

    // Remove inner context(s), if any.
    if (remove != null) {
      thread = remove.getInitiator();
      thread.setNonWaiting();
      // Todo: Callbacks for aborted threads (to abort external activities)
      thread.getThreadContext().removeSubcontext(remove);
    }

    if (next != null) {

      // Todo: store exception as parameter!?
      if (ex != null) thread.setException(null);
    } else if (ex != null) {
      if (ex instanceof RuntimeException) throw (RuntimeException) ex;
      else throw new RuntimeException("Unhandled exception in process: " + activity, ex);
    }

    // Perform step settings, i.e. set next edge/activity or remove thread.
    if (next instanceof MSequenceEdge) {
      thread.setLastEdge((MSequenceEdge) next);
    } else if (next instanceof MActivity) {
      thread.setActivity((MActivity) next);
    } else if (next == null) {
      thread.getThreadContext().removeThread(thread);
    } else {
      throw new UnsupportedOperationException("Unknown outgoing element type: " + next);
    }
  }