/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gses.webui.supervisor; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.util.ObjectProperty; import com.vaadin.data.util.PropertysetItem; import com.vaadin.terminal.ThemeResource; import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; import org.activiti.engine.ProcessEngine; import org.activiti.engine.impl.persistence.entity.ExecutionEntity; import org.activiti.engine.runtime.Execution; import org.activiti.engine.runtime.ExecutionQuery; import ru.codeinside.adm.AdminService; import ru.codeinside.adm.database.Bid; import ru.codeinside.adm.database.Procedure; import ru.codeinside.gses.lazyquerycontainer.LazyQueryContainer; import ru.codeinside.gses.service.F1; import ru.codeinside.gses.service.F3; import ru.codeinside.gses.service.Fn; import ru.codeinside.gses.webui.executor.ExecutorFactory; import java.util.ArrayList; import java.util.List; import static ru.codeinside.gses.webui.Flash.flash; import static ru.codeinside.gses.webui.utils.Components.stringProperty; final public class ExecutionsPanel extends VerticalLayout { final static ObjectProperty<Boolean> TRUE_VALUE = new ObjectProperty<Boolean>(true); final Persistence persistence = new Persistence(); final LazyQueryContainer container = persistence.createContainer(); final Table table; final PersistenceFilter filter; final VerticalLayout diagramLayout; public ExecutionsPanel() { setSizeFull(); setSpacing(true); setMargin(true); table = new Table(null, container); table.setSizeFull(); table.setColumnHeaders(new String[]{ "Заявка", "Дата подачи заявки", "Процедура", "Версия", "Маршрут", "Процесс", "Ветвь" }); table.setColumnIcon("eid", new ThemeResource("icon/branch.png")); table.setSelectable(true); table.setMultiSelect(false); table.setNullSelectionAllowed(true); table.setValue(null); table.setImmediate(true); table.addListener(new ShowExecutionListener()); filter = new PersistenceFilter(table, persistence); diagramLayout = new VerticalLayout(); diagramLayout.setMargin(false); diagramLayout.setSizeFull(); addComponent(filter); addComponent(table); addComponent(diagramLayout); setExpandRatio(table, 0.4f); setExpandRatio(diagramLayout, 0.6f); showDiagram(null); } void showDiagram(Component component) { diagramLayout.removeAllComponents(); if (component == null) { component = new Label("Выберите процесс для отображения схемы исполнения"); } diagramLayout.addComponent(component); } final static class Persistence extends SimpleQuery implements FilterablePersistence { String processInstanceFilter; Persistence() { super(false, 10); addProperty("bid", Long.class, null, true, false); addProperty("startDate", String.class, null, true, false); addProperty("name", String.class, null, true, false); addProperty("ver", String.class, null, true, false); addProperty("did", String.class, null, true, false); addProperty("pid", String.class, null, true, false); addProperty("eid", String.class, null, true, false); } public void setProcessInstanceFilter(String processInstanceFilter) { this.processInstanceFilter = processInstanceFilter; } @Override public int size() { return Fn.withEngine(new Count(), processInstanceFilter).intValue(); } @Override public List<Item> loadItems(final int startIndex, final int count) { return Fn.withEngine(new Items(), processInstanceFilter, startIndex, count); } static ExecutionQuery createQuery(final ProcessEngine engine, final String processInstanceFilter) { final ExecutionQuery query = engine.getRuntimeService().createExecutionQuery(); if (processInstanceFilter != null) { query.processInstanceId(processInstanceFilter); } return query; } final static class Count implements F1<Long, String> { @Override public Long apply(ProcessEngine engine, String processInstanceFilter) { return createQuery(engine, processInstanceFilter).count(); } } final static class Items implements F3<List<Item>, String, Integer, Integer> { @Override public List<Item> apply(final ProcessEngine engine, final String processInstanceFilter, final Integer startIndex, final Integer count) { final AdminService adminService = flash().getAdminService(); final List<Execution> processInstances = createQuery(engine, processInstanceFilter).listPage(startIndex, count); final List<Item> items = new ArrayList<Item>(processInstances.size()); for (final Execution execution : processInstances) { final PropertysetItem item = new PropertysetItem(); final ExecutionEntity entity = (ExecutionEntity) execution; item.addItemProperty("pid", stringProperty(execution.getProcessInstanceId())); if (!execution.getId().equals(execution.getProcessInstanceId())) { item.addItemProperty("eid", stringProperty(execution.getId())); } item.addItemProperty("_eid", stringProperty(execution.getId())); item.addItemProperty("act", stringProperty(entity.getCurrentActivityId())); item.addItemProperty("actName", stringProperty(entity.getCurrentActivityName())); item.addItemProperty("did", stringProperty(entity.getProcessDefinitionId())); if (entity.isConcurrent()) { item.addItemProperty("concurrent", TRUE_VALUE); } final Bid bid = adminService.getBidByProcessInstanceId(execution.getProcessInstanceId()); if (bid != null) { item.addItemProperty("bid", new ObjectProperty<Long>(bid.getId())); item.addItemProperty("startDate", stringProperty(ExecutorFactory.formatter.format(bid.getDateCreated()))); final Procedure procedure = bid.getProcedure(); if (procedure != null) { if (bid.getTag().isEmpty()) { item.addItemProperty("name", stringProperty(procedure.getName())); } else { item.addItemProperty("name", stringProperty(bid.getTag() + " - " + procedure.getName())); } item.addItemProperty("ver", stringProperty(procedure.getVersion())); } } items.add(item); } return items; } } } final class ShowExecutionListener implements Property.ValueChangeListener { @Override public void valueChange(Property.ValueChangeEvent event) { final Table table = (Table) event.getProperty(); Component diagram = null; final Object itemId = table.getValue(); if (itemId != null) { final Item item = table.getItem(itemId); final String _eid = Fn.getValue(item, "_eid", String.class); final String eid = Fn.getValue(item, "eid", String.class); final String did = Fn.getValue(item, "did", String.class); if (_eid != null && did != null) { diagram = new DiagramPanel(did, _eid); if (eid != null) { // блок показываем только для ветвей, для процесса их может быть много final String act = Fn.getValue(item, "act", String.class); final String actName = Fn.trimToNull(Fn.getValue(item, "actName", String.class)); final boolean concurrent = Boolean.TRUE == Fn.getValue(item, "concurrent", Boolean.class); diagram.setCaption((concurrent ? "Параллельно" : "Последовательно") + " исполяемый блок " + act + (actName == null ? "" : (" '" + actName + "'"))); } } } showDiagram(diagram); } } }