package pl.net.bluesoft.rnd.processtool.ui.newprocess;
import static org.aperteworkflow.util.vaadin.VaadinExceptionHandler.Util.withErrorHandling;
import static org.aperteworkflow.util.vaadin.VaadinUtility.refreshIcon;
import static pl.net.bluesoft.util.lang.Formats.nvl;
import static pl.net.bluesoft.util.lang.cquery.CQuery.from;
import com.vaadin.Application;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.ShortcutAction;
import com.vaadin.service.ApplicationContext.TransactionListener;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.themes.ChameleonTheme;
import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession;
import pl.net.bluesoft.rnd.processtool.model.BpmTask;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstance;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessDefinitionConfig;
import pl.net.bluesoft.rnd.processtool.ui.activity.ActivityMainPane;
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.VaadinUtility;
import org.aperteworkflow.util.vaadin.VaadinUtility.Refreshable;
import pl.net.bluesoft.util.lang.cquery.func.F;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author tlipski@bluesoft.net.pl
*/
public class NewProcessExtendedPane extends VerticalLayout implements Refreshable, ClickListener, ValueChangeListener {
public class ProcessStartListener implements ClickListener {
@Override
public void buttonClick(ClickEvent event) {
if(processesSelect.getValue() == null)
return;
}
}
private ProcessToolBpmSession session;
private ActivityMainPane activityMainPane;
private I18NSource i18NSource;
private ListSelect processesSelect;
private Label title;
private IndexedContainer processesContainer;
private Window processesPopup;
private Button firstButton;
private Button secondButton;
private VerticalLayout descriptionPanel;
private Map<ProcessDefinitionConfig, Embedded> logoEmbeddedCache = new HashMap<ProcessDefinitionConfig, Embedded>();
private Map<ProcessDefinitionConfig, Resource> logoResourceCache = new HashMap<ProcessDefinitionConfig, Resource>();
private VerticalLayout processesPopupLayout;
private Panel processesPopupPanel;
private Embedded defaultLogoEmbedded;
private Resource defaultLogoResource;
private Label selectedTitleLabel;
private HorizontalLayout logoWrapper;
private Label descriptionLabel;
private Embedded previousLogo;
private Label attachListener;
private Label attachHandler;
private ProgressIndicator progressBar;
public NewProcessExtendedPane(final ProcessToolBpmSession session,
final I18NSource i18NSource,
final ActivityMainPane activityMainPane) {
this.activityMainPane = activityMainPane;
this.session = session;
this.i18NSource = i18NSource;
firstButton = new Button(getMessage("newProcess.start-simple"), this);
firstButton.setWidth("100%");
// firstButton.addStyleName("default");
// button.addStyleName("default");
addComponent(firstButton);
setComponentAlignment(firstButton, Alignment.MIDDLE_CENTER);
processesPopup = new Window();
processesPopup.setModal(true);
processesPopup.setBorder(0);
processesPopup.setClosable(true);
processesPopup.setWidth(600, Sizeable.UNITS_PIXELS);
processesPopup.setCloseShortcut(ShortcutAction.KeyCode.ESCAPE);
processesPopup.setImmediate(true);
processesSelect = new ListSelect();
processesSelect.setRows(7);
// processesSelect.setHeight(40, Sizeable.UNITS_PIXELS);
processesSelect.setNullSelectionAllowed(false);
processesSelect.setWidth("100%");
processesSelect.setImmediate(true);
processesSelect.addListener(this);
descriptionPanel = new VerticalLayout();
processesPopupPanel = new Panel();
// processesPopupPanel.addStyleName(ChameleonTheme.PANEL_BORDERLESS);
processesPopupPanel.addStyleName(ChameleonTheme.PANEL_LIGHT);
processesPopup.addComponent(processesPopupPanel);
processesPopupLayout = new VerticalLayout();
processesPopupLayout.setSpacing(true);
processesPopupLayout.addComponent(VaadinUtility.horizontalLayout(new Label(getMessage("newProcess.caption-simple"), Label.CONTENT_XHTML), refreshIcon(activityMainPane.getApplication(), this)));
processesPopupLayout.addComponent(processesSelect);
processesPopupLayout.addComponent(descriptionPanel);
processesPopupPanel.addComponent(processesPopupLayout);
processesContainer = new IndexedContainer();
processesContainer.addContainerProperty("name", String.class, "");
processesContainer.addContainerProperty("logo", Resource.class, defaultLogoResource);
processesSelect.setContainerDataSource(processesContainer);
processesSelect.setItemIconPropertyId("logo");
processesSelect.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY);
processesSelect.setItemCaptionPropertyId("name");
defaultLogoResource = VaadinUtility.imageResource(activityMainPane.getApplication(), "aperte-logo.png");
defaultLogoEmbedded = new Embedded(null, defaultLogoResource);
setSpacing(true);
setMargin(new MarginInfo(true, false, true, false));
refreshData();
}
@Override
public void refreshData() {
processesContainer.removeAllItems();
processesSelect.setVisible(true);
processesSelect.setValue(null);
logoEmbeddedCache.clear();
// title.setValue(getMessage("newProcess.caption-simple"));
ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
List<ProcessDefinitionConfig> orderedByProcessDescr = from(session.getAvailableConfigurations(ctx))
.orderBy(new F<ProcessDefinitionConfig, String>() {
@Override
public String invoke(ProcessDefinitionConfig pdc) {
return getMessage(pdc.getDescription()).toLowerCase(i18NSource.getLocale());
}
})
.toList();
for (final ProcessDefinitionConfig definition : orderedByProcessDescr) {
if (session.hasPermissionsForDefinitionConfig(definition)) {
if(!logoResourceCache.containsKey(definition)){
logoResourceCache.put(definition, definition.getProcessLogo() == null ? defaultLogoResource
: new StreamResource(new StreamSource() {
@Override
public InputStream getStream() {
return new ByteArrayInputStream(definition.getProcessLogo());
}
}, definition.getBpmDefinitionKey() + "_logo.png", activityMainPane.getApplication())
);
}
processesContainer.addItem(definition);
processesContainer.getItem(definition).getItemProperty("name").setValue(getMessage(definition.getDescription()));
processesContainer.getItem(definition).getItemProperty("logo").setValue(logoResourceCache.get(definition));
if(processesSelect.getValue() == null){
processesSelect.setValue(definition);
}
}
}
}
private String getMessage(String s) {
return i18NSource.getMessage(s);
}
@Override
public void buttonClick(ClickEvent event) {
if (event.getButton() == firstButton){
if(!getApplication().getMainWindow().getChildWindows().contains(processesPopup))
getApplication().getMainWindow().addWindow(processesPopup);
if(progressBar != null)
processesPopup.removeComponent(progressBar);
processesSelect.setVisible(true);
processesPopup.setVisible(true);
processesPopup.setEnabled(true);
processesPopup.focus();
processesSelect.focus();
} else if (event.getButton() == secondButton){
if(processesSelect.getValue() == null)
return;
progressBar = new ProgressIndicator();
processesSelect.setVisible(false);
progressBar.setCaption(i18NSource.getMessage("activity.starting"));
progressBar.setIndeterminate(true);
progressBar.setPollingInterval(500);
processesPopup.addComponent(progressBar);
getApplication().getContext().addTransactionListener(new TransactionListener() {
private boolean started = false;
private int counter = 2;
@Override
public void transactionStart(Application application, Object transactionData) {
}
@Override
synchronized public void transactionEnd(Application application, Object transactionData) {
if (!started) {
counter--;
if(counter == 0){
processesPopup.removeComponent(progressBar);
processesPopup.setVisible(false);
processesPopup.setEnabled(false);
runProcess(getSelectedDefinition().getBpmDefinitionKey());
started = true;
getApplication().getContext().removeTransactionListener(this);
}
}
}
});
}
}
protected ProcessDefinitionConfig getSelectedDefinition() {
return (ProcessDefinitionConfig)processesSelect.getValue();
}
private void runProcess(final String bpmDefinitionId) {
withErrorHandling(getApplication(), new Runnable() {
@Override
public void run() {
ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
ProcessDefinitionConfig cfg = ctx.getProcessDefinitionDAO().getActiveConfigurationByKey(bpmDefinitionId);
ProcessInstance instance = session.createProcessInstance(cfg, null, ctx, null, null, "portlet", null);
VaadinUtility.informationNotification(activityMainPane.getApplication(), getMessage("newProcess.started"), 1000);
getWindow().executeJavaScript("Liferay.trigger('processtool.bpm.newProcess', '" + instance.getInternalId() + "');");
getWindow().executeJavaScript("vaadin.forceSync();");
List<BpmTask> tasks = session.findUserTasks(instance, ctx);
if (!tasks.isEmpty()) {
BpmTask task = tasks.get(0);
if (activityMainPane != null) {
activityMainPane.displayProcessData(task, session);
}
else {
Window w = new Window(instance.getInternalId());
w.setContent(new ProcessDataPane(getApplication(), session, i18NSource, task, new WindowProcessDataDisplayContext(w)));
w.center();
getWindow().addWindow(w);
w.focus();
}
}
else if (activityMainPane != null) {
activityMainPane.reloadCurrentViewData();
}
}
});
}
@Override
public void valueChange(ValueChangeEvent event) {
if(processesSelect.getValue() == null)
return;
final ProcessDefinitionConfig definition = getSelectedDefinition();
if(!logoEmbeddedCache.containsKey(definition)){
logoEmbeddedCache.put(definition, new Embedded(null, logoResourceCache.get(definition)));
}
Embedded logo = logoEmbeddedCache.get(definition);
if(descriptionPanel.getComponentCount() == 0){
secondButton = VaadinUtility.link(getMessage("newProcess.start-task"), this);
secondButton.setImmediate(true);
secondButton.addListener(new ProcessStartListener());
selectedTitleLabel = new Label(getMessage(definition.getDescription()));
selectedTitleLabel.addStyleName("h3 color");
descriptionPanel.addComponent(logoWrapper = VaadinUtility.horizontalLayout(Alignment.MIDDLE_LEFT, logo, selectedTitleLabel));
logoWrapper.setHeight(36, Sizeable.UNITS_PIXELS);
HorizontalLayout hl = new HorizontalLayout();
hl.addComponent(descriptionLabel = new Label(nvl(getMessage(definition.getComment()), ""), Label.CONTENT_XHTML) {{
setWidth("100%");
}});
hl.addComponent(secondButton);
hl.setExpandRatio(hl.getComponent(0), 1.0f);
hl.setSpacing(true);
hl.setWidth("100%");
hl.setComponentAlignment(secondButton, Alignment.BOTTOM_RIGHT);
descriptionPanel.addComponent(hl);
} else {
logoWrapper.addComponentAsFirst(logo);
logoWrapper.removeComponent(previousLogo);
selectedTitleLabel.setValue(getMessage(definition.getDescription()));
// selectedTitleLabel.setIcon(logoResourceCache.get(definition));
descriptionLabel.setValue(nvl(getMessage(definition.getComment()), ""));
}
previousLogo = logo;
}
}