package org.jbpm.ui.custom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.jbpm.ui.DesignerLogger;
import org.jbpm.ui.SharedImages;
import org.jbpm.ui.common.model.Delegable;
import org.jbpm.ui.common.model.GraphElement;
import org.jbpm.ui.common.model.ProcessDefinition;
import org.jbpm.ui.common.model.Variable;
import org.jbpm.ui.resource.Messages;
import org.jbpm.ui.util.TypeNameMapping;
import org.jbpm.ui.validation.FormatMapping;
import org.jbpm.ui.validation.FormatMappingParser;
public abstract class ParamBasedProvider extends DelegableProvider {
protected abstract List<ParamDef> getParamDefinitions(Delegable delegable);
protected ImageDescriptor getLogo() {
return SharedImages.getImageDescriptor("/icons/logo.gif");
}
@Override
public final String showConfigurationDialog(Delegable delegable) {
Map<String, String> variableNames = new HashMap<String, String>();
ProcessDefinition definition = ((GraphElement) delegable).getProcessDefinition();
for (Variable variable : definition.getVariablesList()) {
variableNames.put(variable.getName(), variable.getFormat());
}
for (String swimlaneName : definition.getSwimlaneNames()) {
variableNames.put(swimlaneName, "ru.runa.wf.web.forms.format.StringFormat");
}
ConfigurationWizardPage page = new ConfigurationWizardPage(
variableNames,
getParamDefinitions(delegable),
TypeNameMapping.getTypeName(delegable.getDelegationClassName()));
page.init(parseConfiguration(delegable.getDelegationConfiguration()));
final ConfigurationWizard wizard = new ConfigurationWizard(page);
WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard) {
@Override
protected void createButtonsForButtonBar(Composite parent) {
Button copyButton = createButton(parent, 197, Messages.getString("button.copy"), false);
copyButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Clipboard clipboard = new Clipboard(Display.getCurrent());
clipboard.setContents(
new String[]{ wizard.getWizardPage().getConfiguration() },
new Transfer[]{ TextTransfer.getInstance() });
clipboard.dispose();
}
});
super.createButtonsForButtonBar(parent);
}
};
if (dialog.open() == IDialogConstants.OK_ID) {
return wizard.getConfiguration();
}
return null;
}
protected Map<String, String> parseConfiguration(String configuration) {
Map<String, String> properties = new HashMap<String, String>();
if (configuration.trim().length() == 0) {
return properties;
}
try {
Document doc = DocumentHelper.parseText(configuration);
Element inputElement = doc.getRootElement().element("input");
if (inputElement != null) {
List<Element> inputParamElements = inputElement.elements("param");
for (Element element : inputParamElements) {
String value;
if (element.attributeValue("variable") != null) {
value = element.attributeValue("variable");
} else {
value = element.attributeValue("value");
}
properties.put(element.attributeValue("name"), value);
}
}
Element outputElement = doc.getRootElement().element("output");
if (outputElement != null) {
List<Element> outputParamElements = outputElement.elements("param");
for (Element element : outputParamElements) {
String value;
if (element.attributeValue("variable") != null) {
value = element.attributeValue("variable");
} else {
value = element.attributeValue("value");
}
properties.put(element.attributeValue("name"), value);
}
}
return properties;
} catch (Exception e) {
DesignerLogger.logErrorWithoutDialog("Invalid configuration " + configuration, e);
return null;
}
}
@Override
public boolean validateValue(Delegable delegable) {
try {
Map<String, String> props = parseConfiguration(delegable.getDelegationConfiguration());
if (props == null) {
return false;
}
for (ParamDef paramDef : getParamDefinitions(delegable)) {
if (!paramDef.optional && !isValid(props.get(paramDef.name))) {
return false;
}
}
return true;
} catch (Exception e) {
DesignerLogger.logErrorWithoutDialog("validation of " + delegable, e);
return false;
}
}
protected boolean isValid(String value) {
return value != null && value.trim().length() > 0;
}
public class ConfigurationWizard extends Wizard {
private final ConfigurationWizardPage wizardPage;
private String configuration;
public ConfigurationWizard(ConfigurationWizardPage wizardPage) {
this.wizardPage = wizardPage;
setNeedsProgressMonitor(true);
setWindowTitle(Messages.getString("property.delegation.configuration"));
}
@Override
public void addPages() {
addPage(wizardPage);
}
public String getConfiguration() {
return configuration;
}
public ConfigurationWizardPage getWizardPage() {
return wizardPage;
}
@Override
public boolean performFinish() {
configuration = wizardPage.getConfiguration();
return true;
}
}
public class ConfigurationWizardPage extends WizardPage {
private Composite clientArea;
private Map<String, String> properties;
protected Combo loginModeCombo;
private final Map<String, String> variableNames;
protected final List<ParamDef> paramDefs;
protected ConfigurationWizardPage(Map<String, String> variableNames, List<ParamDef> paramDefs, String headerText) {
super("config", headerText, getLogo());
this.variableNames = variableNames;
this.paramDefs = paramDefs;
}
public void init(Map<String, String> properties) {
this.properties = properties;
}
protected Text addTextField(final ParamDef paramDef) {
Label label = new Label(clientArea, SWT.NONE);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.minimumWidth = 200;
label.setLayoutData(gridData);
label.setText(getLabelText(paramDef));
Text textInput = new Text(clientArea, SWT.BORDER);
textInput.setData(paramDef.name);
textInput.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
setErrorMessage(null);
setMessage(paramDef.help != null ? paramDef.help : "");
}
});
GridData typeComboData = new GridData(GridData.FILL_HORIZONTAL);
typeComboData.minimumWidth = 200;
textInput.setLayoutData(typeComboData);
String savedValue = properties.get(paramDef.name);
textInput.setText(savedValue != null ? savedValue : "");
return textInput;
}
protected void addSeparator(String header) {
Label label = new Label(clientArea, SWT.SEPARATOR | SWT.HORIZONTAL);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
label.setLayoutData(gridData);
label.setText(header);
}
private Map<String, List<String>> comboItems = new HashMap<String, List<String>>();
private List<String> getVariableNames(Set<String> formatFilters) {
if (formatFilters.size() == 0) {
return new ArrayList<String>(variableNames.keySet());
}
List<String> result = new ArrayList<String>();
for (String varName : variableNames.keySet()) {
String varType = variableNames.get(varName);
FormatMapping mapping = FormatMappingParser.getFormatMappings().get(varType);
if (mapping == null || formatFilters.contains(mapping.getName())) {
result.add(varName);
}
}
return result;
}
protected Combo addComboField(final ParamDef paramDef) {
List<String> variableNames = new ArrayList<String>();
if (paramDef.useVariable) {
variableNames.addAll(getVariableNames(paramDef.formatFilters));
}
for (String string : paramDef.comboItems) {
variableNames.add(string);
}
Collections.sort(variableNames);
if (paramDef.optional) {
variableNames.add(0, "");
}
comboItems.put(paramDef.name, variableNames);
Label label = new Label(clientArea, SWT.NONE);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.minimumWidth = 200;
label.setLayoutData(gridData);
label.setText(getLabelText(paramDef));
Combo combo = new Combo(clientArea, SWT.BORDER | SWT.READ_ONLY);
combo.setData(paramDef.name);
combo.setVisibleItemCount(10);
for (String item : variableNames) {
combo.add(item);
}
combo.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
setErrorMessage(null);
setMessage(paramDef.help != null ? paramDef.help : "");
}
});
GridData typeComboData = new GridData(GridData.FILL_HORIZONTAL);
typeComboData.minimumWidth = 200;
combo.setLayoutData(typeComboData);
String selectedValue = properties.get(paramDef.name);
if (selectedValue != null) {
combo.setText(selectedValue);
}
return combo;
}
private String getLabelText(ParamDef aParam) {
String labelText = aParam.label;
if (!aParam.optional) {
labelText += " *";
}
return labelText;
}
protected void changeStateForInputControls(List<String> propertyNames, boolean enabled) {
for (Control control : clientArea.getChildren()) {
if (control.getData() != null) {
String propertyName = (String) control.getData();
if (propertyNames.contains(propertyName)) {
control.setEnabled(enabled);
}
}
}
}
protected Map<String, String> readUserInput() {
Map<String, String> properties = new HashMap<String, String>();
Control[] controls = clientArea.getChildren();
for (Control control : controls) {
if (control.getData() != null) {
String propertyName = (String) control.getData();
String propertyValue;
if (control instanceof Text) {
propertyValue = ((Text) control).getText();
} else { // Combo
propertyValue = ((Combo) control).getText();
}
properties.put(propertyName, propertyValue);
}
}
return properties;
}
public void createControl(Composite parent) {
clientArea = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
clientArea.setLayout(layout);
setControl(clientArea);
if (properties == null) {
setErrorMessage(Messages.getString("ParamBasedProvider.parseError"));
properties = new HashMap<String, String>();
}
boolean outputStarted = false;
for (ParamDef aParam : paramDefs) {
if (!aParam.isInput && !outputStarted) {
addSeparator(Messages.getString("ParamBasedProvider.result"));
outputStarted = true;
}
if (aParam.determineType() == ParamDef.TYPE_COMBO) {
addComboField(aParam);
} else {
addTextField(aParam);
}
}
}
public String getConfiguration() {
Map<String, String> properties = readUserInput();
StringBuffer buffer = new StringBuffer();
buffer.append("<config>\n");
buffer.append(" <input>\n");
boolean outputStarted = false;
for (ParamDef aParam : paramDefs) {
if (!aParam.isInput && !outputStarted) {
buffer.append(" </input>\n");
buffer.append(" <output>\n");
outputStarted = true;
}
buffer.append(" <param name=\"").append(aParam.name).append("\"");
String value = properties.get(aParam.name);
if (aParam.useVariable) {
buffer.append(" variable=\"").append(value).append("\"");
} else {
buffer.append(" value=\"").append(value).append("\"");
}
buffer.append(" />\n");
}
if (outputStarted) {
buffer.append(" </output>\n");
} else {
buffer.append(" </input>\n");
}
buffer.append("</config>");
return buffer.toString();
}
}
}