Package org.aperteworkflow.editor.stepeditor.user

Source Code of org.aperteworkflow.editor.stepeditor.user.UserStepEditorWindow

package org.aperteworkflow.editor.stepeditor.user;


import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.StreamResource;
import com.vaadin.ui.*;
import com.vaadin.ui.Tree.TreeDragMode;
import com.vaadin.ui.Window.Notification;
import com.vaadin.ui.themes.Reindeer;
import org.aperteworkflow.editor.domain.Permission;
import org.aperteworkflow.editor.stepeditor.AbstractStepEditorWindow;
import org.aperteworkflow.editor.stepeditor.StepEditorApplication;
import org.aperteworkflow.editor.stepeditor.user.JSONHandler.ParsingFailedException;
import org.aperteworkflow.editor.stepeditor.user.JSONHandler.WidgetNotFoundException;
import org.aperteworkflow.editor.ui.permission.PermissionDefinition;
import org.aperteworkflow.editor.ui.permission.PermissionEditor;
import org.aperteworkflow.editor.ui.permission.PermissionProvider;
import org.aperteworkflow.editor.ui.property.PropertiesForm;
import org.aperteworkflow.editor.ui.property.PropertiesPanel;
import org.aperteworkflow.util.vaadin.VaadinUtility;
import org.vaadin.dialogs.ConfirmDialog;
import pl.net.bluesoft.rnd.util.i18n.I18NSource;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

import static org.aperteworkflow.util.vaadin.VaadinUtility.htmlLabel;
import static org.aperteworkflow.util.vaadin.VaadinUtility.styled;
import static pl.net.bluesoft.util.lang.FormatUtil.nvl;

public class UserStepEditorWindow extends AbstractStepEditorWindow implements Handler, ValueChangeListener {

  private static final Logger logger = Logger.getLogger(UserStepEditorWindow.class.getName());
    private static final Action[] COMMON_ACTIONS = new Action[] {};

  private HierarchicalContainer stepTreeContainer;
  private Tree stepTree;
  private Component availableWidgetsPane;
  private WidgetItemInStep rootItem;
  private TextField assigneeField;
  private TextField candidateGroupsField;
  private TextField swimlaneField;
    private TextField descriptionField;
    private RichTextArea commentaryTextArea;
  private WidgetFormWindow paramPanel;
    private PermissionEditor permissionEditor;

    private Action actionDelete;
  private Action[] actions;
    private Collection<Permission> permissions;

    public UserStepEditorWindow(StepEditorApplication application, String jsonConfig, String url, String stepName, String stepType) {
    super(application, jsonConfig, url, stepName, stepType);
        permissions = new LinkedHashSet<Permission>();
        actionDelete = new Action(I18NSource.ThreadUtil.getThreadI18nSource().getMessage("stepTree.action.delete"));
    actions = new Action[] { actionDelete };
    }

    @Override
  public ComponentContainer init() {
    ComponentContainer comp = buildLayout();
   
    if (jsonConfig != null && jsonConfig.trim().length() > 0) {
      if (stepTreeContainer != null && rootItem != null) {
        loadJSONConfig();
      }
    }

        permissionEditor.loadData();
   
    return comp;
  }
 
  private ComponentContainer buildLayout() {
    I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
        prepareAvailableWidgetsComponent();
       
    stepTree = new Tree(messages.getMessage("stepTree.title"), getCurrentStep());
        stepTree.setItemCaptionMode(Tree.ITEM_CAPTION_MODE_PROPERTY);
        stepTree.setItemCaptionPropertyId("name");
    stepTree.setDragMode(TreeDragMode.NODE);
    stepTree.addActionHandler(this);
        stepTree.addListener(this);
    stepTree.setSelectable(true);
    stepTree.setImmediate(true);
        stepTree.setItemDescriptionGenerator(new PropertiesDescriptionGenerator());
        stepTree.expandItemsRecursively(rootItem);
    stepTree.setDropHandler(new TreeDropHandler(stepTree, stepTreeContainer));

        paramPanel = new WidgetFormWindow();

        permissionEditor = new PermissionEditor();
        permissionEditor.setMargin(true);
        permissionEditor.setProvider(new PermissionProvider() {
            @Override
            public Collection<Permission> getPermissions() {
                return permissions;
            }

            @Override
            public Collection<PermissionDefinition> getPermissionDefinitions() {
                PermissionDefinition perm1 = new PermissionDefinition();
                perm1.setKey("SEARCH");
                perm1.setDescription("editor.permissions.description.step.SEARCH");
                return Arrays.asList(perm1);
            }

            @Override
            public boolean isNewPermissionDefinitionAllowed() {
                return false;
            }

            @Override
            public void addPermission(Permission permission) {
                permissions.add(permission);
            }

            @Override
            public void removePermission(Permission permission) {
                permissions.remove(permission);
            }
        });

        VerticalLayout assignmentLayout = prepareAssignmentLayout();
        VerticalLayout stepDefinitionLayout = buildStateDefinitionLayout();
        VerticalLayout stepLayout = buildWidgetEditorTabContent();

        VerticalLayout vl = new VerticalLayout();
        vl.setSizeFull();
        vl.setSpacing(true);
        vl.addComponent(new Label(messages.getMessage("userstep.editor.instructions"), Label.CONTENT_XHTML));

        TabSheet ts = new TabSheet();
        ts.setSizeFull();
        ts.addTab(stepLayout, messages.getMessage("userstep.editor.widgets.tabcaption"));
        ts.addTab(stepDefinitionLayout, messages.getMessage("userstep.state.tabcaption"));
        ts.addTab(assignmentLayout, messages.getMessage("userstep.editor.assignment.tabcaption"));
        ts.addTab(permissionEditor, messages.getMessage("userstep.editor.permissions.tabcaption"));
        ts.setSelectedTab(stepLayout);
        vl.addComponent(ts);
        vl.setExpandRatio(ts, 1.0f);
        return vl;

  }

    private VerticalLayout prepareAssignmentLayout() {
      I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
     
      assigneeField = new TextField();//Messages.getString("field.assignee"));
        assigneeField.setWidth("100%");
        assigneeField.setNullRepresentation("");
       
        candidateGroupsField = new TextField();//Messages.getString("field.candidateGroups"));
        candidateGroupsField.setWidth("100%");
        candidateGroupsField .setNullRepresentation("");
       
        swimlaneField = new TextField();//Messages.getString("field.swimlane"));
        swimlaneField.setWidth("100%");
        swimlaneField.setNullRepresentation("");
       
        VerticalLayout assignmentLayout = new VerticalLayout();
        assignmentLayout.setWidth("100%");
        assignmentLayout.setSpacing(true);
        assignmentLayout.setMargin(true);
        assignmentLayout.addComponent(styled(new Label(messages.getMessage("field.assignee")), "h1"));
        assignmentLayout.addComponent(htmlLabel(messages.getMessage("field.assignee.info")));
        assignmentLayout.addComponent(assigneeField);
        assignmentLayout.addComponent(styled(new Label(messages.getMessage("field.candidateGroups")), "h1"));
        assignmentLayout.addComponent(htmlLabel(messages.getMessage("field.candidateGroups.info")));
        assignmentLayout.addComponent(candidateGroupsField);
        assignmentLayout.addComponent(styled(new Label(messages.getMessage("field.swimlane")), "h1"));
        assignmentLayout.addComponent(htmlLabel(messages.getMessage("field.swimlane.info")));
        assignmentLayout.addComponent(swimlaneField);
        return assignmentLayout;
    }

    private void prepareAvailableWidgetsComponent() {
        List<WidgetItem> availableWidgetItems = getAvailableWidgetItems();
        Collections.sort(availableWidgetItems, new Comparator<WidgetItem>(){
      @Override
      public int compare(WidgetItem o1, WidgetItem o2) {
        return o1.getName().compareTo(o2.getName());
      }
        });
       
        CssLayout pane = new CssLayout() {
            @Override
            protected String getCss(Component component) {
                if (component instanceof WidgetInfoDnDWrapper) {
                    WidgetInfoDnDWrapper wrapper = (WidgetInfoDnDWrapper) component;
                    String basicCss = "float: left; margin: 3px; padding: 3px;  display: inline; font-weight: bold; border: 2px solid ";
                    return basicCss +  (nvl(wrapper.widgetItem.getChildrenAllowed(), false)
                            ? "#287ece;" : "#60b30e;");
                }
                return super.getCss(component);
            }
        };
        pane.setWidth("100%");
        for (WidgetItem wi : availableWidgetItems) {
            Label lbl = new Label(wi.getName());
            lbl.setDescription(wi.getDescription());
            lbl.setSizeUndefined();
            DragAndDropWrapper c = new WidgetInfoDnDWrapper(lbl, wi);
            c.setSizeUndefined();
            pane.addComponent(c);
            c.setDragStartMode(DragAndDropWrapper.DragStartMode.WRAPPER);
        }

        DragAndDropWrapper wr = new DragAndDropWrapper(pane);
        wr.setDropHandler(new DropHandler() {
            @Override
            public void drop(DragAndDropEvent event) {
                Transferable t = event.getTransferable();
                Component src = t.getSourceComponent();
                if (src != stepTree || !(t instanceof DataBoundTransferable)) {
                    return;
                }
                Object sourceItemId = ((DataBoundTransferable) t).getItemId();

                stepTreeContainer.removeItemRecursively(sourceItemId);
            }
            @Override
            public AcceptCriterion getAcceptCriterion() {
                return AcceptAll.get();
            }
        });
        this.availableWidgetsPane = wr;
    }

    private List<WidgetItem> getAvailableWidgetItems() {
        List<WidgetItem> widgetItems = new ArrayList<WidgetItem>();
        Map<BundleItem, Collection<WidgetItem>> availableWidgets = new HashMap<BundleItem, Collection<WidgetItem>>();
        try {
            availableWidgets = WidgetInfoLoader.loadAvailableWidgets(application);
        } catch (ClassNotFoundException e) {
            logger.log(Level.SEVERE, "Error loading available widgets", e);
        }
        for (Entry<BundleItem, Collection<WidgetItem>> entry : availableWidgets.entrySet()) {
            final Collection<WidgetItem> widgets = entry.getValue();
            for (WidgetItem widgetItem : widgets) {
                widgetItems.add(widgetItem);
            }
        }
        return widgetItems;
    }

    private VerticalLayout buildWidgetEditorTabContent() {
      I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
      VerticalLayout availableWidgetsLayout = new VerticalLayout();
        availableWidgetsLayout.setSpacing(true);
        availableWidgetsLayout.setWidth("100%");
        availableWidgetsLayout.addComponent(availableWidgetsPane);
        VerticalLayout stepLayout = new VerticalLayout();
        stepLayout.setWidth("100%");
        stepLayout.setSpacing(true);
        stepLayout.setMargin(true);
        stepLayout.addComponent(new Label(messages.getMessage("userstep.editor.widgets.instructions"), Label.CONTENT_XHTML));
        stepLayout.addComponent(availableWidgetsLayout);
        Panel treePanel = new Panel();
        treePanel.setStyleName(Reindeer.PANEL_LIGHT);
        treePanel.addComponent(stepTree);
        treePanel.setWidth("245px");

        HorizontalLayout treeAndParamLayout = new HorizontalLayout();
        treeAndParamLayout.setWidth("100%");
        treeAndParamLayout.setSpacing(true);
        treeAndParamLayout.addComponent(treePanel);
        treeAndParamLayout.addComponent(paramPanel);
        treeAndParamLayout.setExpandRatio(paramPanel, 1.0f);
        stepLayout.addComponent(treeAndParamLayout);
        stepLayout.setExpandRatio(treeAndParamLayout, 1.0f);
        return stepLayout;
    }

    private VerticalLayout buildStateDefinitionLayout() {
        I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();

        descriptionField = new TextField();
        descriptionField.setNullRepresentation("");
        descriptionField.setWidth("100%");
       
        commentaryTextArea = new RichTextArea();
        commentaryTextArea.setNullRepresentation("");
        commentaryTextArea.setWidth("100%");

        VerticalLayout stateLayout = new VerticalLayout();
        stateLayout.setWidth("100%");
        stateLayout.setSpacing(true);
        stateLayout.setMargin(true);

        stateLayout.addComponent(styled(new Label(messages.getMessage("field.description")), "h1"));
        stateLayout.addComponent(htmlLabel(messages.getMessage("field.description.info")));
        stateLayout.addComponent(descriptionField);

        stateLayout.addComponent(styled(new Label(messages.getMessage("field.commentary")), "h1"));
        stateLayout.addComponent(htmlLabel(messages.getMessage("field.commentary.info")));
        stateLayout.addComponent(commentaryTextArea);

        return stateLayout;
    }

    public void deleteTreeItem(final Object widget) {
      I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
      ConfirmDialog.show(application.getMainWindow(),
          messages.getMessage("dialog.delete.title"),
          messages.getMessage("dialog.delete.question"),
          messages.getMessage("dialog.delete.confirm"),
          messages.getMessage("dialog.delete.cancel"),
                new ConfirmDialog.Listener() {
                    public void onClose(ConfirmDialog dialog) {
                        if (dialog.isConfirmed()) {
                            HierarchicalContainer hc = (HierarchicalContainer) stepTree.getContainerDataSource();
                            hc.removeItemRecursively(widget);
                            showParams(null);
                        }
                    }
                }
        );
  }

  @Override
  public Action[] getActions(Object target, Object sender) {
    if (target != rootItem) {
      return actions;
        } else {
      return COMMON_ACTIONS;
        }
  }

  private Resource getWidgetIcon(WidgetItem widgetItem) {
    try {
      final InputStream stream = widgetItem.getBundle().getIconStream(widgetItem.getIcon());

      if (stream != null)
        return new StreamResource(new StreamResource.StreamSource() {
          @Override
          public InputStream getStream() {
            return stream;
          }
        }, widgetItem.getIcon(), application);
    } catch (IOException e) {
      logger.log(Level.WARNING, "Icon \"" + widgetItem.getIcon() + "\" for widget \"" + widgetItem.getName() + "\" not found!");
    }

    return getResource("icon.widget.default");
  }

  private Resource getResource(String pathKey) {
    I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
    final String path = messages.getMessage(pathKey);
    final InputStream stream = getClass().getClassLoader().getResourceAsStream(path);
    if (stream != null) {
      String[] pathParts = path.split("/");
      return new StreamResource(new StreamResource.StreamSource() {
        @Override
        public InputStream getStream() {
          return stream;
        }
      }, pathParts[pathParts.length - 1], application);
    }
    return null;
  }

  private Container getCurrentStep() {
    prepareTreeContainer();

    return stepTreeContainer;
  }

  @Override
  public void handleAction(Action action, Object sender, Object target) {
    if (action == actionDelete) {
      deleteTreeItem(target);
    }
  }

  private void loadJSONConfig() {
    I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
   
    try {
      Map<String, String> map = JSONHandler.loadConfig(stepTreeContainer, rootItem, jsonConfig, permissions);
      if (stepTree != null) {
        stepTree.expandItemsRecursively(rootItem);
      }

      assigneeField.setValue(map.get(JSONHandler.ASSIGNEE));
      swimlaneField.setValue(map.get(JSONHandler.SWIMLANE));
      candidateGroupsField.setValue(map.get(JSONHandler.CANDIDATE_GROUPS));
            commentaryTextArea.setValue(map.get(JSONHandler.COMMENTARY));
            descriptionField.setValue(map.get(JSONHandler.DESCRIPTION));

      for (Object widget : stepTreeContainer.getItemIds()) {
        if (widget != rootItem) {
          stepTree.getItem(widget).getItemProperty("icon").setValue(getWidgetIcon(((WidgetItemInStep) widget).getWidgetItem()));
                }
            }
    } catch (WidgetNotFoundException e) {
      logger.log(Level.SEVERE, "Widget not found", e);
      application.getMainWindow().showNotification(messages.getMessage("error.config_not_loaded.title"),
          messages.getMessage("error.config_not_loaded.widget_not_found.body", e.getWidgetItemName()),
                        Notification.TYPE_ERROR_MESSAGE);
    } catch (ParsingFailedException e) {
            logger.log(Level.SEVERE, "Parsing failed found", e);
      application.getMainWindow().showNotificationmessages.getMessage("error.config_not_loaded.title"),
          messages.getMessage("error.config_not_loaded.unexpected_error.body", e.getLocalizedMessage()),
                        Notification.TYPE_ERROR_MESSAGE);
    }
  }

  private HierarchicalContainer prepareTreeContainer() {
    I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
    stepTreeContainer = new HierarchicalContainer();
    stepTreeContainer.addContainerProperty("name", String.class, messages.getMessage("stepTree.name.default"));
    stepTreeContainer.addContainerProperty("icon", Resource.class, getResource("icon.widget.default"));

    final WidgetItem widgetItem = new WidgetItem(
                "ROOT",
                messages.getMessage("stepTree.root.name"),
                messages.getMessage("stepTree.root.description"),
                null,
        null,
                new ArrayList<PermissionDefinition>(),
                true,
                null
        );
    rootItem = new WidgetItemInStep(widgetItem, null, null, null);
    Item item = stepTreeContainer.addItem(rootItem);
    item.getItemProperty("name").setValue(widgetItem.getName());
    item.getItemProperty("icon").setValue(getResource("icon.root.default"));
    stepTreeContainer.setChildrenAllowed(item, widgetItem.getChildrenAllowed());

    return stepTreeContainer;
  }

  private void showParams(WidgetItemInStep widget) {
        paramPanel.loadWidget(widget, true);
  }

    @Override
  public void save() {
        // perform validation of all the widget definitions
        Collection<?> itemIds = stepTreeContainer.getItemIds();
        for (Object itemId : itemIds) {
            WidgetItemInStep widgetInStep = (WidgetItemInStep) itemId;

            PropertiesPanel propertiesPanel = widgetInStep.getWidgetPropertiesPanel();
            if (propertiesPanel != null) {
                widgetInStep.getWidgetPropertiesPanel().ensureForm();

                PropertiesForm propertiesForm = propertiesPanel.getPropertiesForm();
                if (!propertiesForm.isValid()) {
                    I18NSource messages = I18NSource.ThreadUtil.getThreadI18nSource();
                    VaadinUtility.validationNotification(
                            application,
                            messages,
                            messages.getMessage("stepTree.contains.invalid")
                    );

                    // switch to problematic widget
                    paramPanel.loadWidget(widgetInStep, false);
                    stepTree.setValue(widgetInStep);
                    return;
                }
            }
        }

        String json = JSONHandler.dumpTreeToJSON(stepTree, rootItem,
                assigneeField.getValue(), candidateGroupsField.getValue(), swimlaneField.getValue(),
                stepType, descriptionField.getValue(), commentaryTextArea.getValue(),
                permissions
        );
        application.getJsHelper().postAndRedirectStep(url, json);
  }

    @Override
    public void valueChange(ValueChangeEvent event) {
    if (event.getProperty() == stepTree) {
      if (stepTree.getValue() == null || stepTree.getValue() == rootItem) {
          showParams(null);
      } else {
          WidgetItemInStep widget = (WidgetItemInStep) stepTree.getValue();
          stepTree.setValue(widget);
          showParams(widget);
      }
    }
  }

}
TOP

Related Classes of org.aperteworkflow.editor.stepeditor.user.UserStepEditorWindow

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.