package pl.net.bluesoft.rnd.processtool.ui.queues;
import com.vaadin.data.Container;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Table.ColumnGenerator;
import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.ProcessToolContextCallback;
import pl.net.bluesoft.rnd.processtool.bpm.BpmEvent;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession;
import pl.net.bluesoft.rnd.processtool.model.BpmTask;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessQueueConfig;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessQueueRight;
import pl.net.bluesoft.rnd.processtool.model.nonpersistent.ProcessQueue;
import pl.net.bluesoft.rnd.processtool.ui.process.ProcessDataPane;
import pl.net.bluesoft.rnd.processtool.ui.process.WindowProcessDataDisplayContext;
import pl.net.bluesoft.rnd.util.i18n.I18NSource;
import org.aperteworkflow.util.vaadin.GenericVaadinPortlet2BpmApplication;
import org.aperteworkflow.util.vaadin.VaadinUtility;
import org.aperteworkflow.util.vaadin.VaadinUtility.Refreshable;
import pl.net.bluesoft.util.eventbus.EventListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Logger;
import static org.aperteworkflow.util.vaadin.VaadinExceptionHandler.Util.withErrorHandling;
import static org.aperteworkflow.util.vaadin.VaadinUtility.horizontalLayout;
import static org.aperteworkflow.util.vaadin.VaadinUtility.refreshIcon;
public class QueuesMainPane extends VerticalLayout implements Refreshable {
private I18NSource i18NSource;
private ProcessToolBpmSession session;
private EventListener<BpmEvent> bpmEventSubScriber;
private GenericVaadinPortlet2BpmApplication application;
private Table table;
private BeanItemContainer<ProcessQueue> bic;
private Window addQueueWindow;
public QueuesMainPane(I18NSource i18nSource, ProcessToolBpmSession bpmSession, GenericVaadinPortlet2BpmApplication application) {
this.i18NSource = i18nSource;
this.session = bpmSession;
this.application = application;
initUI();
}
private void initUI() {
final ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
final Table table = getUserTasksTable(ctx);
Button addButton = new Button(getMessage("queues.add"));
Button removeButton = new Button(getMessage("queues.remove"));
Component refreshButton = refreshIcon(application, this);
addComponent(horizontalLayout(new Label(getMessage("queues.help.short")), refreshButton));
addComponent(table);
HorizontalLayout hl = new HorizontalLayout();
hl.setSpacing(true);
hl.addComponent(addButton);
hl.addComponent(removeButton);
addComponent(hl);
setSpacing(true);
addButton.addListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
VerticalLayout pane = new VerticalLayout();
pane.setMargin(true);
pane.setWidth("500px");
Form form = getAddQueueForm();
pane.addComponent(form);
addQueueWindow = new Window(getMessage("queues.add.title"), pane);
addQueueWindow.setClosable(true);
addQueueWindow.setModal(true);
addQueueWindow.setSizeUndefined();
addQueueWindow.setResizable(false);
getApplication().getMainWindow().addWindow(addQueueWindow);
}
});
removeButton.addListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
if (table.getValue() == null)
return;
ProcessQueue pq = (ProcessQueue)table.getValue();
if (pq.getUserAdded() == null || pq.getUserAdded() == false) {
getWindow().showNotification(getMessage("queues.remove.forbidden"));
return;
}
final Collection<ProcessQueueConfig> queues = new ArrayList<ProcessQueueConfig>();
ProcessQueueConfig config = new ProcessQueueConfig();
config.setName(pq.getName());
queues.add(config);
withErrorHandling(getApplication(), new Runnable() {
@Override
public void run() {
ProcessToolContext.Util.getThreadProcessToolContext().getRegistry().withProcessToolContext(new ProcessToolContextCallback() {
@Override
public void withContext(ProcessToolContext ctx) {
ctx.getProcessDefinitionDAO().removeQueueConfigs(queues);
}
});
}
});
refreshData();
getWindow().showNotification(getMessage("queues.remove.succeed"));
}
});
}
private Table getUserTasksTable(ProcessToolContext ctx) {
table = new Table();
table.setWidth("100%");
table.setHeight("200px");
table.setImmediate(true); // react at once when something is selected
table.setSelectable(true);
table.setEditable(!isReadOnly());
bic = new BeanItemContainer<ProcessQueue>(ProcessQueue.class);
for (ProcessQueue pq : session.getUserAvailableQueues(ctx)) {
bic.addBean(pq);
}
table.setContainerDataSource(bic);
table.setTableFieldFactory(new DefaultFieldFactory() {
@Override
public Field createField(Container container, Object itemId,
Object propertyId, Component uiContext) {
Field field;
if ("browsable".equals(propertyId) || "userAdded".equals(propertyId)) {
field = new CheckBox();
field.setWidth("16px");
}
else {
field = super.createField(container, itemId, propertyId, uiContext);
field.setWidth("100%");
}
field.setReadOnly(true);
return field;
}
});
table.addGeneratedColumn("translation", new ColumnGenerator() {
@Override
public Object generateCell(Table source, Object itemId, Object columnId) {
ProcessQueue queue = (ProcessQueue) itemId;
String translation = getMessage(queue.getDescription());
return translation != null ? translation : "";
}
});
table.setVisibleColumns(new Object[] { "description", "translation", "processCount", "name", "browsable", "userAdded" });
for (Object o : table.getVisibleColumns()) {
table.setColumnHeader(o, getMessage("queues." + o));
}
table.addListener(
new ItemClickEvent.ItemClickListener() {
public void itemClick(final ItemClickEvent event) {
withErrorHandling(getApplication(), new Runnable() {
public void run() {
if (event.isDoubleClick()) {
ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
BeanItem<ProcessQueue> beanItem = bic.getItem(event.getItemId());
BpmTask task = session.assignTaskFromQueue(beanItem.getBean(), ctx);
if (task != null) {
getWindow().executeJavaScript("Liferay.trigger('processtool.bpm.assignProcess', '"
+ task.getProcessInstance().getInternalId() + "');");
getWindow().executeJavaScript("vaadin.forceSync();");
Window w = new Window(task.getProcessInstance().getInternalId());
w.setContent(new ProcessDataPane(getApplication(), session, i18NSource, task, new WindowProcessDataDisplayContext(w)));
w.center();
getWindow().addWindow(w);
w.focus();
}
}
}});
}
});
if (bpmEventSubScriber == null) {
session.getEventBusManager().subscribe(BpmEvent.class, bpmEventSubScriber = new MyBpmEventEventListener());
}
return table;
}
public void refreshData() {
bic.removeAllItems();
ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
for (ProcessQueue pq : session.getUserAvailableQueues(ctx)) {
bic.addBean(pq);
}
}
private String getMessage(String key) {
return i18NSource.getMessage(key);
}
private Form getAddQueueForm() {
final QueueForm form = new QueueForm(ProcessToolContext.Util.getThreadProcessToolContext(), i18NSource, application);
final QueueBean queue = new QueueBean();
BeanItem<QueueBean> item = new BeanItem<QueueBean>(queue);
form.setItemDataSource(item, Arrays.asList("process", "name", "description", "rights"));
form.setWriteThrough(false);
form.setWidth(100, Sizeable.UNITS_PERCENTAGE);
Button saveButton = new Button(getMessage("queues.add.save"));
saveButton.addListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
if (form.isValid()) {
form.commit();
final ProcessQueueConfig config = new ProcessQueueConfig();
config.setDescription(queue.getDescription());
config.setName(queue.getName());
config.setUserAdded(true);
config.getRights().addAll(queue.getRights());
final Collection<ProcessQueueConfig> queues = new ArrayList<ProcessQueueConfig>();
queues.add(config);
withErrorHandling(getApplication(), new Runnable() {
@Override
public void run() {
ProcessToolContext.Util.getThreadProcessToolContext().getRegistry().withProcessToolContext(new ProcessToolContextCallback() {
@Override
public void withContext(ProcessToolContext ctx) {
//no way!
// for (ProcessQueueRight r : config.getRights()) {
// if (ctx.getRegistry().createRoleIfNotExists(r.getRoleName(), "Role generated by queue portlet"))
// logger.info("Created new role " + r.getRoleName());
// }
ctx.getProcessDefinitionDAO().updateOrCreateQueueConfigs(queues);
getApplication().getMainWindow().removeWindow(addQueueWindow);
}
});
}
});
refreshData();
}
else {
StringBuilder sb = new StringBuilder("<ul>");
for (Object propertyId : form.getItemPropertyIds()) {
Field field = form.getField(propertyId);
if (!field.isValid() && field.isRequired()) {
sb.append("<li>").append(field.getRequiredError()).append("</li>");
}
}
sb.append("</ul>");
VaadinUtility.validationNotification(application, i18NSource, sb.toString());
}
}
});
form.getFooter().addComponent(saveButton);
return form;
}
private class MyBpmEventEventListener implements EventListener<BpmEvent>, Serializable {
@Override
public void onEvent(BpmEvent e) {
if (QueuesMainPane.this.isVisible() && QueuesMainPane.this.getApplication() != null) {
refreshData();
}
}
}
}