package pl.net.bluesoft.rnd.processtool.ui.activity; import static pl.net.bluesoft.util.lang.Strings.hasText; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.aperteworkflow.util.vaadin.VaadinUtility; import org.aperteworkflow.util.vaadin.ui.AligningHorizontalLayout; import org.aperteworkflow.util.view.AbstractListPane; import pl.net.bluesoft.rnd.processtool.ProcessToolContext; import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession; import pl.net.bluesoft.rnd.processtool.hibernate.ResultsPageWrapper; import pl.net.bluesoft.rnd.processtool.model.BpmTask; import pl.net.bluesoft.rnd.processtool.model.ProcessInstance; import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceFilter; import pl.net.bluesoft.rnd.processtool.model.UserData; import pl.net.bluesoft.rnd.processtool.ui.tasks.TaskTableItem; import pl.net.bluesoft.rnd.processtool.ui.widgets.taskitem.TaskItemProviderBase; import pl.net.bluesoft.rnd.processtool.ui.widgets.taskitem.TaskItemProviderParams; import com.vaadin.terminal.Resource; import com.vaadin.terminal.StreamResource; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; /** * @author tlipski@bluesoft.net.pl * @author mpawlak@bluesoft.net.pl */ public abstract class ProcessListPane extends AbstractListPane { protected ActivityMainPane activityMainPane; protected VerticalLayout dataPane = new VerticalLayout(); protected int limit = 10; protected int offset = 0; protected int totalResults = 0; private List<BpmTask> bpmTasks = Collections.synchronizedList(new ArrayList<BpmTask>()); private TasksFilterBox filterBox; private ProcessInstanceFilter filter; private NavigationComponent topNavigationComponent; private NavigationComponent bottomNavigationComponent; public ProcessListPane(ActivityMainPane activityMainPane, String title, ProcessInstanceFilter filter) { super(activityMainPane.getApplication(), activityMainPane.getI18NSource(), title); this.activityMainPane = activityMainPane; this.filter = filter; this.addRefreshButton = false; } public ProcessListPane(ActivityMainPane activityMainPane, String title) { this(activityMainPane, title, null); } public void setFilter(ProcessInstanceFilter filter) { this.filter = filter; } @Override public ProcessListPane init() { super.init(); limit = 10; offset = 0; totalResults = 0; filter = filter == null ? getDefaultFilter() : filter; VerticalLayout marginPanel = new VerticalLayout(); marginPanel.addComponent(new Label(getMessage("activity.tasks.help.short"), Label.CONTENT_XHTML)); marginPanel.setMargin(true); marginPanel.setWidth("100%"); addComponent(marginPanel); filterBox = new TasksFilterBox(messageSource, getBpmSession(), application, this); filterBox.setFilter(filter); filterBox.setLimit(limit); marginPanel.addComponent(filterBox); addComponent(dataPane); setExpandRatio(dataPane, 1.0f); refreshData(); topNavigationComponent = new NavigationComponent(); bottomNavigationComponent = new NavigationComponent(); reloadView(); filterBox.addListener(new TasksFilterBox.ItemSetChangeListener() { @Override public void itemSetChange() { reloadView(); } }); return this; } protected ProcessToolBpmSession getBpmSession() { return activityMainPane.getBpmSession(); } protected abstract ProcessInstanceFilter getDefaultFilter(); public void reloadView() { dataPane.setSpacing(getDataPaneUsesSpacing()); dataPane.setMargin(true); dataPane.setWidth("100%"); dataPane.removeAllComponents(); topNavigationComponent.refresh(); bottomNavigationComponent.refresh(); dataPane.addComponent(topNavigationComponent); dataPane.setComponentAlignment(topNavigationComponent, Alignment.TOP_RIGHT); for(BpmTask bpmTask: bpmTasks) dataPane.addComponent(getTaskItem(new TaskTableItem(bpmTask))); if(bpmTasks.size() > 2) { dataPane.addComponent(bottomNavigationComponent); dataPane.setComponentAlignment(bottomNavigationComponent, Alignment.TOP_RIGHT); } } protected void sortTaskItems(List<TaskTableItem> taskItems) { } @Override public void refreshData() { /* get current filter from filter box */ filter = filterBox.getFilter(); if(filter == null) new ResultsPageWrapper<BpmTask>(); ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext(); totalResults = getBpmSession().getFilteredTasksCount(filter, ctx); /* Get tasks filtered by given filter */ bpmTasks = Collections.synchronizedList(getBpmSession().findFilteredTasks(filter, ctx, offset, limit)); } public List<BpmTask> getBpmTasks() { return bpmTasks; } protected boolean getDataPaneUsesSpacing() { return true; } protected abstract Component getTaskItem(TaskTableItem tti); private class NavigationComponent extends AligningHorizontalLayout implements ClickListener { private Button prevButton; private Button nextButton; private Label resultsLabel; public NavigationComponent() { super(Alignment.MIDDLE_RIGHT, true); init(); } public void refresh() { boolean privButtonEnabled = offset-limit >= 0; boolean nextButtonEnabled = offset+limit <= totalResults - 1; prevButton.setEnabled(privButtonEnabled); nextButton.setEnabled(nextButtonEnabled); int first = getTotalResults() > 0 ? offset + 1 : 0; int last = Math.min(offset + limit, getTotalResults()); resultsLabel.setValue(String.format(getMessage("activity.tasks.of.line"), first, last, getTotalResults())); } private void init() { setWidth("100%"); prevButton = VaadinUtility.link(getMessage("activity.tasks.previous")); prevButton.addListener((ClickListener)NavigationComponent.this); nextButton = VaadinUtility.link(getMessage("activity.tasks.next")); nextButton.addListener((ClickListener)NavigationComponent.this); int first = getTotalResults() > 0 ? offset + 1 : 0; int last = Math.min(offset + limit, getTotalResults()); HorizontalLayout resultsLayout = new HorizontalLayout(); resultsLayout.setMargin(false); resultsLayout.setWidth("75px"); resultsLabel = new Label(String.format(getMessage("activity.tasks.of.line"), first, last, getTotalResults())); resultsLayout.addComponent(resultsLabel); resultsLayout.setComponentAlignment(resultsLabel, Alignment.MIDDLE_CENTER); refresh(); setMargin(false, true, false, true); addComponents(new Component[] {new Label() {{ setWidth("100%"); }}, prevButton, resultsLayout, nextButton}); } @Override public void buttonClick(ClickEvent event) { if(event.getButton().equals(prevButton)) { offset -= limit; refreshData(); reloadView(); } else if(event.getButton().equals(nextButton)) { offset += limit; refreshData(); reloadView(); } } } public void setNewSearch() { offset = 0; titleLabel.setValue(getMessage("activity.search.results")); } public ActivityMainPane getActivityMainPane() { return activityMainPane; } public int getTotalResults() { return totalResults; } protected static String getLogin(UserData userData) { return userData != null ? userData.getLogin() : null; } protected TaskItemProviderBase getTaskItemProvider(final ProcessToolContext ctx, ProcessInstance pi) { String itemClass = pi.getDefinition().getTaskItemClass(); if (hasText(itemClass) && !itemClass.equals("null")) { try { return new TaskItemProviderBase(ctx.getRegistry().makeTaskItemProvider(itemClass.trim())); } catch (Exception e) { throw new RuntimeException(e); } } return new TaskItemProviderBase(null); } private TaskItemProviderParams createTaskItemProviderParams() { return new TaskItemProviderParams() { @Override public Resource getImage(String image) { return ProcessListPane.this.getImage(image); } @Override public Resource getResource(String path) { return ProcessListPane.this.getResource(path); } @Override public Resource getStreamResource(String path, final byte[] bytes) { Resource res = new StreamResource(new StreamResource.StreamSource() { @Override public InputStream getStream() { return new ByteArrayInputStream(bytes); } }, path, application); cacheResource(path, res); return res; } @Override public void onClick() { ProcessListPane.this.onClick(this); } }; } protected TaskItemProviderParams getTaskItemProviderParams(ProcessToolContext ctx, TaskTableItem tti) { TaskItemProviderParams params = createTaskItemProviderParams(); params.setCtx(ctx); params.setBpmSession(getBpmSession()); params.setI18NSource(messageSource); params.setProcessInstance(tti.getTask().getProcessInstance()); params.setTask(tti.getTask()); params.setProcessStateConfiguration(tti.getStateConfiguration()); params.setState(tti.getState()); params.setQueue(null); return params; } protected abstract void onClick(TaskItemProviderParams params); }