Package org.jboss.bpm.console.client.process

Source Code of org.jboss.bpm.console.client.process.InstanceListView

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.bpm.console.client.process;

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

import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.*;

import org.gwt.mosaic.core.client.Dimension;
import org.gwt.mosaic.ui.client.ListBox;
import org.gwt.mosaic.ui.client.MessageBox;
import org.gwt.mosaic.ui.client.ToolBar;
import org.gwt.mosaic.ui.client.event.RowSelectionEvent;
import org.gwt.mosaic.ui.client.event.RowSelectionHandler;
import org.gwt.mosaic.ui.client.layout.BorderLayout;
import org.gwt.mosaic.ui.client.layout.BorderLayoutData;
import org.gwt.mosaic.ui.client.layout.BoxLayout;
import org.gwt.mosaic.ui.client.layout.BoxLayoutData;
import org.gwt.mosaic.ui.client.layout.MosaicPanel;
import org.gwt.mosaic.ui.client.list.DefaultListModel;
import org.jboss.bpm.console.client.ApplicationContext;
import org.jboss.bpm.console.client.common.DataDriven;
import org.jboss.bpm.console.client.common.IFrameWindowCallback;
import org.jboss.bpm.console.client.common.IFrameWindowPanel;
import org.jboss.bpm.console.client.common.LoadingOverlay;
import org.jboss.bpm.console.client.common.WidgetWindowPanel;
import org.jboss.bpm.console.client.icons.ConsoleIconBundle;
import org.jboss.bpm.console.client.model.ProcessDefinitionRef;
import org.jboss.bpm.console.client.model.ProcessInstanceRef;
import org.jboss.bpm.console.client.model.TokenReference;
import org.jboss.bpm.console.client.process.events.InstanceEvent;
import org.jboss.bpm.console.client.process.events.SignalInstanceEvent;
import org.jboss.bpm.console.client.util.ConsoleLog;
import org.jboss.bpm.console.client.util.SimpleDateFormat;
import org.jboss.errai.workspaces.client.api.ProvisioningCallback;
import org.jboss.errai.workspaces.client.api.WidgetProvider;
import org.jboss.errai.workspaces.client.framework.Registry;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.mvc4g.client.Controller;
import com.mvc4g.client.Event;
import com.mvc4g.client.ViewInterface;

/**
* @author Heiko.Braun <heiko.braun@jboss.com>
*/
public class InstanceListView implements WidgetProvider, ViewInterface, DataDriven
{
    public final static String ID = InstanceListView.class.getName();

    private Controller controller;

    private MosaicPanel instanceList = null;

    private ListBox<ProcessInstanceRef> listBox;

    private ProcessDefinitionRef currentDefinition;

    private boolean isInitialized;

    private List<ProcessInstanceRef> cachedInstances = null;

    private SimpleDateFormat dateFormat = new SimpleDateFormat();

    private ApplicationContext appContext;

    private IFrameWindowPanel iframeWindow = null;

    private boolean isRiftsawInstance;

    //private PagingPanel pagingPanel;

    MosaicPanel panel;

    private Button startBtn, terminateBtn, deleteBtn, signalBtn, refreshBtn;

    // elements needed to signal waiting execution
    private List<TokenReference> tokensToSignal = null;

    private WidgetWindowPanel signalWindowPanel;

    private ListBox<TokenReference> listBoxTokens = null;

    private List<TextBox> signalTextBoxes = null;
   
    private TextBox eventData = null;

    private ImageResource greenIcon;

  private TextBox signalRef = null;

    public void provideWidget(ProvisioningCallback callback)
    {

        this.appContext = Registry.get(ApplicationContext.class);
        // riftsaw?
        isRiftsawInstance = appContext.getConfig().getProfileName().equals("BPEL Console");

        panel = new MosaicPanel();
        panel.setPadding(0);

        Registry.get(Controller.class).addView(ID, this);
        initialize();

        ConsoleIconBundle imageBundle = (ConsoleIconBundle)GWT.create(ConsoleIconBundle.class);
        greenIcon = imageBundle.greenIcon();

        callback.onSuccess(panel);
    }

    public boolean isInitialized()
    {
        return isInitialized;
    }

    public void initialize()
    {
        if(!isInitialized)
        {
            instanceList = new MosaicPanel( new BoxLayout(BoxLayout.Orientation.VERTICAL));
            instanceList.setPadding(0);
            instanceList.setWidgetSpacing(0);

            listBox =
                    new ListBox<ProcessInstanceRef>(
                            new String[] {
                                    "<b>Instance</b>", "State", "Start Date"}
                    );

            listBox.setCellRenderer(new ListBox.CellRenderer<ProcessInstanceRef>() {
                public void renderCell(ListBox<ProcessInstanceRef> listBox, int row, int column,
                                       ProcessInstanceRef item) {
                    switch (column) {
                        case 0:
                            listBox.setText(row, column, item.getId());
                            break;
                        case 1:
                            listBox.setText(row, column, item.getState().toString());
                            break;
                        case 2:
                            String d = item.getStartDate() != null ? dateFormat.format(item.getStartDate()) : "";
                            listBox.setText(row, column, d);
                            break;
                        default:
                            throw new RuntimeException("Unexpected column size");
                    }
                }
            });

            listBox.addRowSelectionHandler(
                    new RowSelectionHandler()
                    {
                        public void onRowSelection(RowSelectionEvent rowSelectionEvent)
                        {
                            int index = listBox.getSelectedIndex();
                            if(index!=-1)
                            {
                                ProcessInstanceRef item = listBox.getItem(index);

                                // enable or disable signal button depending on current activity
                                if (isSignalable(item)) {
                                    signalBtn.setEnabled(true);
                                } else {
                                    signalBtn.setEnabled(false);
                                }

                                terminateBtn.setEnabled(true);

                                // update details
                                controller.handleEvent(
                                        new Event(UpdateInstanceDetailAction.ID,
                                                new InstanceEvent(currentDefinition, item)
                                        )
                                );
                            }
                        }
                    }
            );

            // toolbar
            final MosaicPanel toolBox = new MosaicPanel();

            toolBox.setPadding(0);
            toolBox.setWidgetSpacing(5);

            final ToolBar toolBar = new ToolBar();
            refreshBtn = new Button("Refresh", new ClickHandler() {

                public void onClick(ClickEvent clickEvent) {
                    controller.handleEvent(
                            new Event(
                                    UpdateInstancesAction.ID,
                                    getCurrentDefinition()
                            )
                    );
                }
            }
            );
            toolBar.add(refreshBtn);
            refreshBtn.setEnabled(false);
            toolBar.addSeparator();

            startBtn = new Button("Start", new ClickHandler()
            {
                public void onClick(ClickEvent clickEvent)
                {
                    MessageBox.confirm("Start new execution",
                            "Do you want to start a new execution of this process?",
                            new MessageBox.ConfirmationCallback()
                            {
                                public void onResult(boolean doIt)
                                {
                                    if (doIt)
                                    {
                                        String url = getCurrentDefinition().getFormUrl();
                                        boolean hasForm = (url != null && !url.equals(""));
                                        if (hasForm)
                                        {
                                            ProcessDefinitionRef definition = getCurrentDefinition();
                                            iframeWindow = new IFrameWindowPanel(
                                                    definition.getFormUrl(), "New Process Instance: " + definition.getId()
                                            );

                                            iframeWindow.setCallback(
                                                    new IFrameWindowCallback()
                                                    {
                                                        public void onWindowClosed()
                                                        {
                                                            controller.handleEvent(
                                                                    new Event(UpdateInstancesAction.ID, getCurrentDefinition())
                                                            );
                                                        }
                                                    }
                                            );

                                            iframeWindow.show();
                                        }
                                        else
                                        {
                                            controller.handleEvent(
                                                    new Event(
                                                            StartNewInstanceAction.ID,
                                                            getCurrentDefinition()
                                                    )
                                            );
                                        }
                                    }

                                }
                            });

                }
            }
            );


            terminateBtn = new Button("Terminate", new ClickHandler()
            {
                public void onClick(ClickEvent clickEvent)
                {
                    if (getSelection() != null)
                    {

                        MessageBox.confirm("Terminate instance",
                                "Terminating this instance will stop further execution.",
                                new MessageBox.ConfirmationCallback()
                                {
                                    public void onResult(boolean doIt)
                                    {
                                        if (doIt)
                                        {
                                          ProcessInstanceRef selection = getSelection();
                                          if (selection.getState().equals(ProcessInstanceRef.STATE.ENDED)) {
                                              MessageBox.alert("Info", "Process is already completed");
                                            } else {
                                             
                                              selection.setState(ProcessInstanceRef.STATE.ENDED);
                                              selection.setEndResult(ProcessInstanceRef.RESULT.OBSOLETE);
                                              controller.handleEvent(
                                                      new Event(
                                                              StateChangeAction.ID,
                                                              selection
                                                      )
                                              );
                                            }
                                        }
                                    }
                                });
                    }
                    else
                    {
                        MessageBox.alert("Missing selection", "Please select an instance");
                    }
                }
            }
            );           


            deleteBtn = new Button("Delete", new ClickHandler()
            {
                public void onClick(ClickEvent clickEvent)
                {
                    if (getSelection() != null)
                    {
                        MessageBox.confirm("Delete instance",
                                "Deleting this instance will remove any history information and associated tasks as well.",
                                new MessageBox.ConfirmationCallback()
                                {
                                    public void onResult(boolean doIt)
                                    {

                                        if (doIt)
                                        {
                                          try {
                                              ProcessInstanceRef selection = getSelection();
                                              if (selection.getState().equals(ProcessInstanceRef.STATE.ENDED)) {
                                                MessageBox.alert("Info", "Process is already completed");
                                              } else {
                                                selection.setState(ProcessInstanceRef.STATE.ENDED);
   
                                                controller.handleEvent(
                                                        new Event(
                                                                DeleteInstanceAction.ID,
                                                                selection
                                                        )
                                                );
                                              }
                                          } catch (Exception e) {
                        MessageBox.alert("Warning", e.getMessage());
                      }
                                        }
                                    }
                                });

                    }
                    else
                    {
                        MessageBox.alert("Missing selection", "Please select an instance");
                    }
                }
            }
            );

            signalBtn = new Button("Signal", new ClickHandler()
            {
                public void onClick(ClickEvent clickEvent)
                {
                 
                  if (getSelection() != null)
                    {
                    createSignalWindow();
                  }
                  else
                  {
                      MessageBox.alert("Missing selection", "Please select an instance");
                  }
                }
            }
            );

            if(!isRiftsawInstance// riftsaw doesn't support instance operations
            {
                toolBar.add(startBtn);
                toolBar.add(signalBtn);
                toolBar.add(deleteBtn);

                startBtn.setEnabled(false);
                deleteBtn.setEnabled(false);
                signalBtn.setEnabled(false);
            }

            // terminate works on any BPM Engine
            toolBar.add(terminateBtn);
            terminateBtn.setEnabled(false);

            toolBox.add(toolBar, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));


            instanceList.add(toolBox, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));
            instanceList.add(listBox, new BoxLayoutData(BoxLayoutData.FillStyle.BOTH));

            /*pagingPanel = new PagingPanel(
              new PagingCallback()
              {
                public void rev()
                {
                  renderUpdate();
                }

                public void ffw()
                {
                  renderUpdate();
                }
              }
          );
          instanceList.add(pagingPanel, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));*/

            // cached data?
            if(this.cachedInstances!=null)
                bindData(this.cachedInstances);

            // layout
            MosaicPanel layout = new MosaicPanel(new BorderLayout());
            layout.setPadding(0);
            layout.add(instanceList, new BorderLayoutData(BorderLayout.Region.CENTER));

            // details
            InstanceDetailView detailsView = new InstanceDetailView();
            controller.addView(InstanceDetailView.ID, detailsView);
            controller.addAction(UpdateInstanceDetailAction.ID, new UpdateInstanceDetailAction());
            controller.addAction(ClearInstancesAction.ID, new ClearInstancesAction());
            controller.addAction(SignalExecutionAction.ID, new SignalExecutionAction());
            layout.add(detailsView, new BorderLayoutData(BorderLayout.Region.SOUTH,10,200));

            panel.add(layout);

            isInitialized = true;

        }
    }

    public ProcessInstanceRef getSelection()
    {
        ProcessInstanceRef selection = null;
        if(listBox.getSelectedIndex()!=-1)
            selection = listBox.getItem( listBox.getSelectedIndex());
        return selection;
    }

    public ProcessDefinitionRef getCurrentDefinition()
    {
        return this.currentDefinition;
    }

    public void setController(Controller controller)
    {
        this.controller = controller;
    }

    public void reset()
    {
        this.currentDefinition = null;
        this.cachedInstances = new ArrayList<ProcessInstanceRef>();
        renderUpdate();

        startBtn.setEnabled(false);
        terminateBtn.setEnabled(false);
        deleteBtn.setEnabled(false);
        signalBtn.setEnabled(false);
        refreshBtn.setEnabled(false);
    }

    public void update(Object... data)
    {
        this.currentDefinition = (ProcessDefinitionRef)data[0];
        this.cachedInstances = (List<ProcessInstanceRef>)data[1];

        //if(isInitialized()) pagingPanel.reset();
        renderUpdate();
    }

    public void setLoading(boolean isLoading)
    {
        LoadingOverlay.on(instanceList, isLoading);
    }

    private void renderUpdate()
    {
        if(isInitialized())
        {
            bindData(this.cachedInstances);

            // clear details
            controller.handleEvent(
                    new Event(UpdateInstanceDetailAction.ID,
                            new InstanceEvent(this.currentDefinition, null)
                    )
            );

            startBtn.setEnabled(true);           
            deleteBtn.setEnabled(true);
            refreshBtn.setEnabled(true);
            signalBtn.setEnabled(false);
        }
    }

    private void bindData(List<ProcessInstanceRef> instances)
    {
        final DefaultListModel<ProcessInstanceRef> model =
                (DefaultListModel<ProcessInstanceRef>) listBox.getModel();
        model.clear();

        List<ProcessInstanceRef> list = instances;//pagingPanel.trim(instances);
        for(ProcessInstanceRef inst : list)
        {
          model.add(inst);
        }

        // layout again
        panel.invalidate();
    }

    private boolean isSignalable(ProcessInstanceRef processInstance) {

        tokensToSignal = new ArrayList<TokenReference>();

        // first check if the parent execution is signalable
        if (processInstance.getRootToken() != null && processInstance.getRootToken().canBeSignaled()) {
            tokensToSignal.add(processInstance.getRootToken());

        } else if (processInstance.getRootToken() != null && processInstance.getRootToken().getChildren() != null) {
            // next verify children
            collectSignalableTokens(processInstance.getRootToken(), tokensToSignal);
        }

        if (tokensToSignal.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    private void collectSignalableTokens(TokenReference tokenParent, List<TokenReference> tokensToSignal) {
        if (tokenParent.getChildren() != null) {
            for (TokenReference token : tokenParent.getChildren()) {
                if (token.canBeSignaled()) {
                    tokensToSignal.add(token);
                }

                collectSignalableTokens(token, tokensToSignal);
            }
        }
    }

    private void createSignalWindow()
    {
        signalTextBoxes = new ArrayList<TextBox>();

        MosaicPanel layout = new MosaicPanel(new BoxLayout(BoxLayout.Orientation.VERTICAL));
        layout.setStyleName("bpm-window-layout");
        layout.setPadding(5);
        // toolbar
        final MosaicPanel toolBox = new MosaicPanel();

        toolBox.setPadding(0);
        toolBox.setWidgetSpacing(5);
        toolBox.setLayout(new BoxLayout(BoxLayout.Orientation.HORIZONTAL));

        final ToolBar toolBar = new ToolBar();
        toolBar.add(
                new Button("Signal", new ClickHandler() {

                    public void onClick(ClickEvent clickEvent)
                    {
                        int selectedToken = listBoxTokens.getSelectedIndex();
                     // issue warning if user selected row and typed into signal ref text box
                      if (selectedToken != -1 && signalRef.getText().length() > 0)
                      {
                        MessageBox.alert("Multi selection", "Known active nodes and signal ref (text box) is given, please choose only one of them");
                      } else
                       
                        if (selectedToken != -1) {

                            controller.handleEvent(
                                    new Event(SignalExecutionAction.ID,
                                            new SignalInstanceEvent(getCurrentDefinition(), getSelection(), listBoxTokens.getItem(selectedToken), eventData.getText(), selectedToken)));

                        } else if (signalRef.getText().length() > 0) {
                         
                          TokenReference token = new TokenReference();
                          token.setId(getSelection().getId());
                          token.setName(signalRef.getText());
                          int foundMatch = -1;
                          int index = 0;
                          // try to find matching element from the list to avoid double signal problems
                          for (TokenReference ref : tokensToSignal)
                          {
                            if (ref.getName().equals(token.getName())) {
                              foundMatch = index;
                              break;
                            }
                            index++;
                          }
                         
                            controller.handleEvent(
                                    new Event(SignalExecutionAction.ID,
                                            new SignalInstanceEvent(getCurrentDefinition(), getSelection(), token, eventData.getText(), foundMatch)));

                        } else {
                            MessageBox.alert("Incomplete selection", "Please select element you want to signal");
                        }


                    }
                }
                )
        );

        toolBar.add(
                new Button("Close", new ClickHandler() {

                    public void onClick(ClickEvent clickEvent)
                    {

                        signalWindowPanel.close();
                        controller.handleEvent( new Event(UpdateInstancesAction.ID, getCurrentDefinition()));
                    }
                }
                )
        );

       

        toolBox.add(toolBar, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));

        layout.add(toolBox, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));
       
        Label header = new Label("Known active nodes to signal: ");
        header.setStyleName("bpm-label-header");
        layout.add(header, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));

        listBoxTokens = new ListBox<TokenReference>(new String[] { "Node name", "Signal ref" });

        listBoxTokens.setCellRenderer(new ListBox.CellRenderer<TokenReference>() {

            public void renderCell(ListBox<TokenReference> listBox, int row, int column, TokenReference item) {
                switch (column) {
                    case 0:
                        listBox.setText(row, column, item.getCurrentNodeName());
                        break;
                    case 1:
                        listBox.setText(row, column, item.getName());
                        break;
                    default:
                        throw new RuntimeException("Unexpected column size");
                }
            }
        });


        renderSignalListBox(-1);
        layout.add(listBoxTokens, new BoxLayoutData(BoxLayoutData.FillStyle.BOTH));
       
        Label headerSignalRef = new Label("Signal ref");
        headerSignalRef.setStyleName("bpm-label-header");
        layout.add(headerSignalRef, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));

        signalRef = new TextBox();
        signalRef.addFocusHandler(new FocusHandler() {
     
      @Override
      public void onFocus(FocusEvent event) {
        if (listBox.getSelectedIndex() != -1) {
          listBoxTokens.setItemSelected(listBox.getSelectedIndex(), false);
        }
      }
    });

        layout.add(signalRef, new BoxLayoutData(BoxLayoutData.FillStyle.BOTH));

        Label headerSignals = new Label("Event data");
        headerSignals.setStyleName("bpm-label-header");
        layout.add(headerSignals, new BoxLayoutData(BoxLayoutData.FillStyle.HORIZONTAL));

        eventData = new TextBox();

        layout.add(eventData, new BoxLayoutData(BoxLayoutData.FillStyle.BOTH));

        signalWindowPanel = new WidgetWindowPanel(
                "Signal process",
                layout, false
        );
        signalWindowPanel.setSize(new Dimension(500, 400));

    }

    public void renderSignalListBox(int i) {
        // remove currently signaled token
        if (i > -1) {
            tokensToSignal.remove(i);
        }

        ((DefaultListModel<TokenReference>)listBoxTokens.getModel()).clear();
        if (!tokensToSignal.isEmpty()) {
          // display all remaining token possible to signal
         
          for (TokenReference token : tokensToSignal) {
              ((DefaultListModel<TokenReference>)listBoxTokens.getModel()).add(token);
          }
        }
        // clear
        if (signalRef != null) {
           
          signalRef.setText("");
        }
        if (eventData != null) {
           
            eventData.setText("");
        }
       
    }


}
TOP

Related Classes of org.jboss.bpm.console.client.process.InstanceListView

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.