/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.workflow.execute; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.SimpleContentProposalProvider; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TreeEditor; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; 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.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; import de.rcenvironment.core.component.api.ComponentUtils; import de.rcenvironment.core.component.model.configuration.api.ConfigurationDescription; import de.rcenvironment.core.component.model.configuration.api.PlaceholdersMetaDataConstants; import de.rcenvironment.core.component.model.configuration.api.PlaceholdersMetaDataDefinition; import de.rcenvironment.core.component.workflow.execution.api.WorkflowPlaceholderHandler; import de.rcenvironment.core.component.workflow.model.api.WorkflowDescription; import de.rcenvironment.core.component.workflow.model.api.WorkflowNode; import de.rcenvironment.core.gui.utils.common.components.PropertyTabGuiHelper; import de.rcenvironment.core.gui.utils.incubator.NumericalTextConstraintListener; import de.rcenvironment.core.gui.utils.incubator.WidgetGroupFactory; import de.rcenvironment.core.gui.workflow.Activator; import de.rcenvironment.core.utils.common.StringUtils; /** * Wizard page for managing placeholders. * * @author Sascha Zur * @author Brigitte Boden */ @SuppressWarnings("boxing") public class PlaceholderPage extends WizardPage { private static final Color COLOR_WHITE = Display.getCurrent() .getSystemColor(SWT.COLOR_WHITE); private static final Color COLOR_RED = Display.getCurrent().getSystemColor( SWT.COLOR_RED); private static final int HUNDRED = 100; private static final Log LOGGER = LogFactory.getLog(PlaceholderPage.class); protected final WorkflowDescription workflowDescription; protected WorkflowPlaceholderHandler placeholderHelper; private Tree componentPlaceholderTree; // maps the hash code of a TreeItem to a control private Map<Integer, Control> controlMap; private final String dot = "."; private Map<Integer, Button> saveButtonMap; private boolean restoredPasswords = false; private Map<Integer, String> treeItemNameToPlaceholder; private Map<Integer, String> treeItemToUUIDMap; private Map<String, Set<String>> placeholderValidators; /** * The Constructor. */ public PlaceholderPage(WorkflowDescription workflowDescription) { super(Messages.workflowPageName); this.workflowDescription = workflowDescription; setTitle(Messages.workflowPageTitle); setDescription(Messages.configure); } @Override public void createControl(Composite parent) { Composite comp = new Composite(parent, SWT.NONE); comp.setLayout(new GridLayout(1, false)); setControl(comp); IPreferenceStore prefs = Activator.getInstance().getPreferenceStore(); String placeholderPersistentSettingsUUID = prefs .getString(WorkflowPlaceholderHandler.PLACEHOLDER_PREFERENCES_KEY); if (placeholderPersistentSettingsUUID.isEmpty()) { placeholderPersistentSettingsUUID = UUID.randomUUID().toString(); prefs.putValue(WorkflowPlaceholderHandler.PLACEHOLDER_PREFERENCES_KEY, placeholderPersistentSettingsUUID); } placeholderHelper = WorkflowPlaceholderHandler.createPlaceholderDescriptionFromWorkflowDescription( workflowDescription, placeholderPersistentSettingsUUID); addPlaceholderGroup(comp); Button clearHistoryButton = new Button(comp, SWT.NONE); clearHistoryButton.setText(Messages.clearHistoryButton); clearHistoryButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { WorkflowPageClearHistoryDialog chd = new WorkflowPageClearHistoryDialog( getShell(), Messages.clearHistoryDialogTitle, placeholderHelper, workflowDescription); chd.open(); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); if (placeholderHelper.getIdentifiersOfPlaceholderContainingComponents() .size() == 0) { clearHistoryButton.setEnabled(false); } } private void addPlaceholderGroup(Composite container) { controlMap = new HashMap<>(); saveButtonMap = new HashMap<>(); // guiNameToPlaceholder = new HashMap<String, String>(); treeItemNameToPlaceholder = new HashMap<>(); treeItemToUUIDMap = new HashMap<>(); Group placeholderInformationGroup = new Group(container, SWT.NONE); placeholderInformationGroup .setText(Messages.placeholderInformationHeader); placeholderInformationGroup.setLayout(new GridLayout(1, false)); GridData gridData = new GridData(); gridData.verticalAlignment = GridData.FILL; gridData.grabExcessVerticalSpace = true; gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; placeholderInformationGroup.setLayoutData(gridData); componentPlaceholderTree = new Tree(placeholderInformationGroup, SWT.MULTI); componentPlaceholderTree.setLayoutData(gridData); componentPlaceholderTree.setHeaderVisible(false); componentPlaceholderTree.setLinesVisible(true); // resize the row height using a MeasureItem listener componentPlaceholderTree.addListener(SWT.MeasureItem, new Listener() { @Override public void handleEvent(Event event) { event.height = 2 * 10 + 2; } }); fillTree(); Listener listener = new Listener() { @Override public void handleEvent(Event e) { final TreeItem treeItem = (TreeItem) e.item; getShell().getDisplay().asyncExec(new Runnable() { @Override public void run() { treeItem.getParent().getColumn(0).pack(); treeItem.getParent() .getColumn(0) .setWidth( treeItem.getParent().getColumn(0) .getWidth() + 10); } }); } }; componentPlaceholderTree.addListener(SWT.Collapse, listener); componentPlaceholderTree.addListener(SWT.Expand, listener); deleteEmptyTreeItems(); openItems(); componentPlaceholderTree.getColumn(0).pack(); componentPlaceholderTree.getColumn(0).setWidth( componentPlaceholderTree.getColumn(0).getWidth() + 10); } private void deleteEmptyTreeItems() { for (TreeItem tItem : componentPlaceholderTree.getItems()) { int itemCount = 0; for (TreeItem childItem : tItem.getItems()) { itemCount++; if (childItem.getItemCount() > 0) { itemCount += childItem.getItemCount(); } else { if (treeItemNameToPlaceholder.containsKey(tItem.hashCode())) { itemCount++; } else { childItem.dispose(); itemCount--; } } } if (itemCount <= 1) { tItem.dispose(); } } } private void openItems() { for (TreeItem parent : componentPlaceholderTree.getItems()) { for (TreeItem secondLevel : parent.getItems()) { if (secondLevel.getItemCount() == 0) { Control control = controlMap.get(secondLevel.hashCode()); if (control instanceof Text) { Text current = (Text) control; parent.setExpanded(true); // Always expand. Copy into if // branch, if it // should // only open when nothing is in it if ((current.getText().equals("") || current.getText() == null)) { current.setBackground(COLOR_RED); } } } else { for (TreeItem thirdLevel : secondLevel.getItems()) { Control control = controlMap.get(thirdLevel.hashCode()); if (control instanceof Text) { Text current = (Text) control; parent.setExpanded(true); // Always expand. Copy // into if branch, if it // should only open when nothing is in it secondLevel.setExpanded(true); if (current.getText().equals("") || current.getText() == null) { current.setBackground(COLOR_RED); } } else if (control instanceof Combo) { Combo current = (Combo) control; parent.setExpanded(true); secondLevel.setExpanded(true); if (current.getText().equals("") || current.getText() == null) { current.setBackground(COLOR_RED); } } } } } } } private void fillTree() { TreeColumn column1 = new TreeColumn(componentPlaceholderTree, SWT.LEFT); column1.setText(""); TreeColumn column2 = new TreeColumn(componentPlaceholderTree, SWT.CENTER); column2.setText(""); column2.setWidth(HUNDRED + 5); TreeColumn column3 = new TreeColumn(componentPlaceholderTree, SWT.CENTER); column3.setText(""); column3.setWidth(HUNDRED / 2); TreeColumn column4 = new TreeColumn(componentPlaceholderTree, SWT.CENTER); column4.setText(""); column4.setWidth(HUNDRED); placeholderValidators = new HashMap<>(); Set<String> componentTypesWithPlaceholder = placeholderHelper.getIdentifiersOfPlaceholderContainingComponents(); String[] componentTypesWithPlaceholderArray = componentTypesWithPlaceholder .toArray(new String[componentTypesWithPlaceholder.size()]); Arrays.sort(componentTypesWithPlaceholderArray); for (String componentID : componentTypesWithPlaceholderArray) { TreeItem componentIDTreeItem = new TreeItem(componentPlaceholderTree, 0); String componentName = workflowDescription.getWorkflowNode(placeholderHelper .getComponentInstances(componentID).get(0)).getName(); String abstractComponentName = workflowDescription.getWorkflowNode(placeholderHelper .getComponentInstances(componentID).get(0)).getComponentDescription().getName(); componentIDTreeItem.setText(0, abstractComponentName); componentIDTreeItem.setImage(getImage(workflowDescription .getWorkflowNode(placeholderHelper.getComponentInstances(componentID).get(0)))); PlaceholdersMetaDataDefinition placeholderMetaData = getPlaceholderAttributes(componentName); List<String> globalPlaceholderOrder = PlaceholderSortUtils .getPlaceholderOrder(placeholderHelper.getPlaceholderNameSetOfComponentID(componentID), placeholderMetaData); if (globalPlaceholderOrder == null) { globalPlaceholderOrder = new LinkedList<>(); } for (String componentPlaceholder : globalPlaceholderOrder) { TreeItem compPHTreeItem = new TreeItem(componentIDTreeItem, 0); String guiName = placeholderMetaData.getGuiName(componentPlaceholder); if (guiName == null) { guiName = ""; } treeItemNameToPlaceholder.put(compPHTreeItem.hashCode(), componentPlaceholder); compPHTreeItem.setText(0, guiName); String currentPlaceholder = componentID + dot + componentPlaceholder; controlMap.put(compPHTreeItem.hashCode(), addSWTHandler(compPHTreeItem, componentName + dot + componentPlaceholder, guiName, ComponentUtils .isEncryptedPlaceholder(currentPlaceholder, WorkflowPlaceholderHandler.getEncryptedPlaceholder()), true)); } List<String> instancesWithPlaceholder = placeholderHelper.getComponentInstances(componentID); instancesWithPlaceholder = PlaceholderSortUtils .sortInstancesWithPlaceholderByName( instancesWithPlaceholder, workflowDescription); for (String compInstances : instancesWithPlaceholder) { ConfigurationDescription configDesc = workflowDescription.getWorkflowNode(compInstances).getComponentDescription() .getConfigurationDescription(); boolean hasPlaceholderWithGUIName = false; for (String instancePlaceholder : placeholderHelper.getPlaceholderNameSetOfComponentInstance(compInstances)) { boolean isActivePlaceholder = WorkflowPlaceholderHandler.isActivePlaceholder(instancePlaceholder, configDesc); if (isActivePlaceholder) { if ((placeholderMetaData.getGuiName(instancePlaceholder) != null && !placeholderMetaData.getGuiName(instancePlaceholder).isEmpty() || placeholderMetaData.getGuiName("*") != null)) { hasPlaceholderWithGUIName = true; } else { for (Entry<String, String> entry : configDesc.getConfiguration().entrySet()) { if (ConfigurationDescription.isPlaceholder(entry.getValue()) && WorkflowPlaceholderHandler.getNameOfPlaceholder(entry.getValue()) .equals(instancePlaceholder)) { hasPlaceholderWithGUIName = true; } } if (!hasPlaceholderWithGUIName) { LOGGER .warn(StringUtils.format("Placeholder %s of component %s has no GUI name defined and will be ignored.", instancePlaceholder, workflowDescription.getWorkflowNode(compInstances) .getComponentDescription().getName())); } } } } if (hasPlaceholderWithGUIName) { TreeItem instanceTreeItem = new TreeItem(componentIDTreeItem, 0); String instanceName = workflowDescription.getWorkflowNode(compInstances).getName(); instanceTreeItem.setText(0, instanceName); instanceTreeItem.setImage(getImage(workflowDescription.getWorkflowNode(placeholderHelper .getComponentInstances(componentID).get(0)))); List<String> orderedIinstancePlaceholder = PlaceholderSortUtils .getPlaceholderOrder(placeholderHelper.getPlaceholderNameSetOfComponentInstance(compInstances), placeholderMetaData); for (String instancePlaceholder : orderedIinstancePlaceholder) { // active configuration only considers declarative keys // it is needed to consider configuration entries added // at runtime as well as // long as the input provider component adds some // thus, it is checked if either the key is active or it // is not part of the // declarative keys and was added at runtime. those // entries are active per default boolean isActivePlaceholder = WorkflowPlaceholderHandler.isActivePlaceholder(instancePlaceholder, configDesc); if (isActivePlaceholder) { TreeItem instancePHTreeItem = new TreeItem(instanceTreeItem, 0); treeItemToUUIDMap.put(instancePHTreeItem.hashCode(), compInstances); String guiName = placeholderMetaData.getGuiName(instancePlaceholder); if (guiName == null) { guiName = instancePlaceholder; } treeItemNameToPlaceholder.put(instancePHTreeItem.hashCode(), instancePlaceholder); instancePHTreeItem.setText(0, guiName); String currentPlaceholder = componentID + dot + instancePlaceholder; controlMap.put(instancePHTreeItem.hashCode(), addSWTHandler( instancePHTreeItem, instanceName + dot + instancePlaceholder, guiName, ComponentUtils.isEncryptedPlaceholder(currentPlaceholder, WorkflowPlaceholderHandler.getEncryptedPlaceholder()), false)); } } } } } placeApplyToAllButtonsWhereNecessary(componentPlaceholderTree); column1.pack(); } private Control addSWTHandler(TreeItem item, final String placeholderName, final String guiName, boolean isEncrypted, boolean isGlobal) { TreeEditor textEditor = new TreeEditor(item.getParent()); Combo booleanCombo = null; String finalProposal = null; textEditor.horizontalAlignment = SWT.LEFT; textEditor.grabHorizontal = true; int style = SWT.BORDER; boolean isPathField = false; boolean isBoolean = false; boolean isInteger = false; boolean isFloat = false; String dataType = placeholderHelper.getPlaceholdersDataType().get( placeholderName); final String componentName = placeholderName.split("\\" + dot)[0]; if (dataType != null) { if (dataType.equals(PlaceholdersMetaDataConstants.TYPE_FILE) || dataType.equals(PlaceholdersMetaDataConstants.TYPE_DIR)) { isPathField = true; } else if (dataType.equals(PlaceholdersMetaDataConstants.TYPE_BOOL)) { booleanCombo = addBooleanCombo(item); isBoolean = true; } else if (dataType.equals(PlaceholdersMetaDataConstants.TYPE_INT)) { isInteger = true; } else if (dataType .equals(PlaceholdersMetaDataConstants.TYPE_FLOAT)) { isFloat = true; } } if (isEncrypted) { style |= SWT.PASSWORD; } final Text placeholderText = new Text(item.getParent(), style); placeholderText.setMessage("No value entered."); ModifyListener modifyListener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { validateInput((Text) e.getSource(), componentName, guiName); } }; placeholderText.addModifyListener(modifyListener); if (!restoredPasswords && isEncrypted) { WorkflowPlaceholderHandler.restorePasswords(placeholderHelper .getComponentInstanceHistory()); WorkflowPlaceholderHandler.restorePasswords(placeholderHelper .getComponentTypeHistory()); restoredPasswords = true; } String[] allProposals = {}; if (!isGlobal) { allProposals = placeholderHelper.getInstancePlaceholderHistory( treeItemNameToPlaceholder.get(item.hashCode()), treeItemToUUIDMap.get(item.hashCode())); } else { allProposals = placeholderHelper.getComponentPlaceholderHistory( treeItemNameToPlaceholder.get(item.hashCode()), getComponentIDByName(item.getParentItem().getText()), workflowDescription.getIdentifier()); } if (allProposals.length > 0) { if (isEncrypted) { byte[] decoded = new Base64() .decode(allProposals[allProposals.length - 1]); try { allProposals[allProposals.length - 1] = new String(decoded, "UTF-8"); } catch (UnsupportedEncodingException e) { LOGGER.warn("Could not decode placeholder " + placeholderName, e); } } finalProposal = allProposals[allProposals.length - 1]; // set default value to recent one } String[] additionalProposals = placeholderHelper .getOtherPlaceholderHistoryValues(treeItemNameToPlaceholder .get(item.hashCode())); if (allProposals.length == 0) { allProposals = additionalProposals; if (!isEncrypted && allProposals.length > 0) { String valueFromOtherComponentInWorkflow = placeholderHelper .getValueFromOtherComponentInWorkflow( treeItemNameToPlaceholder.get(item.hashCode()), workflowDescription.getIdentifier()); if (valueFromOtherComponentInWorkflow != null) { finalProposal = valueFromOtherComponentInWorkflow; } else { finalProposal = allProposals[allProposals.length - 1]; } } } else { allProposals = additionalProposals; } if (finalProposal != null && !finalProposal.equals("")) { if (!isBoolean) { placeholderText.setText(finalProposal); } else if (booleanCombo != null) { booleanCombo.setText(finalProposal); } } if (isEncrypted) { allProposals = new String[0]; // Passwords should not be visible } SimpleContentProposalProvider scp = new SimpleContentProposalProvider( allProposals); scp.setFiltering(true); ContentProposalAdapter adapter = null; adapter = new ContentProposalAdapter(placeholderText, new TextContentAdapter(), scp, KeyStroke.getInstance(SWT.ARROW_DOWN), null); adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); adapter.setAutoActivationDelay(1); adapter.setPropagateKeys(true); if (isPathField) { addFileChooser(item, dataType, placeholderText); } if (isBoolean) { textEditor.setEditor(booleanCombo, item, 1); return booleanCombo; } if (isTextEmpty(placeholderText)) { addPlaceholderValidator(componentName, guiName); } textEditor.setEditor(placeholderText, item, 1); if (isEncrypted) { TreeEditor checkButton = new TreeEditor(item.getParent()); checkButton.horizontalAlignment = SWT.LEFT; checkButton.grabHorizontal = true; Button checkForSaveButton = new Button(item.getParent(), SWT.CHECK); checkForSaveButton.setText("Save"); checkButton.minimumWidth = checkForSaveButton.getSize().x; checkButton.setEditor(checkForSaveButton, item, 2); saveButtonMap.put(item.hashCode(), checkForSaveButton); if (placeholderText.getText() != null && !placeholderText.getText().equals("")) { checkForSaveButton.setSelection(true); } } // componentPlaceholderCount.get(placeholderName) > 1 if (isFloat) { NumericalTextConstraintListener floatListener = new NumericalTextConstraintListener( placeholderText, WidgetGroupFactory.ONLY_FLOAT); placeholderText.addVerifyListener(floatListener); } if (isInteger) { NumericalTextConstraintListener integerListener = new NumericalTextConstraintListener( placeholderText, WidgetGroupFactory.ONLY_INTEGER); placeholderText.addVerifyListener(integerListener); } return placeholderText; } private void placeApplyToAllButtonsWhereNecessary(Tree baseTree) { // put all Items of one ComponentID in one List Map<String, String> placeholderDataTypes = placeholderHelper.getPlaceholdersDataType(); for (TreeItem componentTree : baseTree.getItems()) { List<ExtendedTreeItem> componentKeyValues = new ArrayList<>(); List<ExtendedTreeItem> fullComponentKeyValues = new ArrayList<>(); for (TreeItem instanceItem : componentTree.getItems()) { for (TreeItem keyValue : instanceItem.getItems()) { String dataType = placeholderDataTypes.get(instanceItem.getText() + "." + treeItemNameToPlaceholder.get(keyValue.hashCode())); componentKeyValues.add(new ExtendedTreeItem(keyValue, dataType)); fullComponentKeyValues.add(new ExtendedTreeItem(keyValue, dataType)); } } for (int i = 0; i < componentKeyValues.size(); i++) { boolean buttonForIElementCreated = false; for (int j = i + 1; j < componentKeyValues.size(); j++) { if (componentKeyValues.get(i).treeItem.getText().equals(componentKeyValues.get(j).treeItem.getText())) { if (componentKeyValues.get(i).dataType == null || componentKeyValues.get(j).dataType == null) { if (componentKeyValues.get(i).dataType == null && componentKeyValues.get(i).dataType == null) { if (!buttonForIElementCreated) { addApplyToAllButton(componentKeyValues.get(i), fullComponentKeyValues); buttonForIElementCreated = true; } addApplyToAllButton(componentKeyValues.get(j), fullComponentKeyValues); } } else if (componentKeyValues.get(i).dataType.equals(componentKeyValues.get(j).dataType)) { if (!buttonForIElementCreated) { addApplyToAllButton(componentKeyValues.get(i), fullComponentKeyValues); buttonForIElementCreated = true; } addApplyToAllButton(componentKeyValues.get(j), fullComponentKeyValues); } } } } } } /** * More like an Object that clues together an Item with a dataType. * * @author Jascha Riedel */ private final class ExtendedTreeItem { public final TreeItem treeItem; public final String dataType; ExtendedTreeItem(TreeItem treeItem, String dataType) { this.treeItem = treeItem; this.dataType = dataType; } } private void addPlaceholderValidator(final String componentName, String placeholderName) { Set<String> placeholderNames = placeholderValidators.get(componentName); if (placeholderNames == null) { placeholderNames = new HashSet<>(); } placeholderNames.add(placeholderName); placeholderValidators.put(componentName, placeholderNames); } private void removePlaceholderValidator(final String componentName, final String placeholderName) { Set<String> placeholderNames = placeholderValidators.get(componentName); placeholderNames.remove(placeholderName); if (placeholderNames.isEmpty()) { placeholderValidators.remove(componentName); } } private void addApplyToAllButton(ExtendedTreeItem extendedTreeItem, List<ExtendedTreeItem> allItems) { TreeEditor buttonEditor = new TreeEditor(extendedTreeItem.treeItem.getParent()); buttonEditor.horizontalAlignment = SWT.LEFT; buttonEditor.grabHorizontal = true; Button placeholderButton = new Button(extendedTreeItem.treeItem.getParent(), SWT.PUSH); placeholderButton.setToolTipText(Messages.applyToAllToolTip); placeholderButton.setText(Messages.applyToAll); placeholderButton.setSize(placeholderButton.getText().length() * 6, 0); placeholderButton.computeSize(SWT.DEFAULT, extendedTreeItem.treeItem.getParent() .getItemHeight()); placeholderButton.addSelectionListener(new ButtonListener(extendedTreeItem, allItems)); buttonEditor.minimumWidth = placeholderButton.getSize().x; buttonEditor.setEditor(placeholderButton, extendedTreeItem.treeItem, 3); } private void addFileChooser(TreeItem item, final String dataType, final Text placeholderText) { TreeEditor pathButtonEditor = new TreeEditor(item.getParent()); pathButtonEditor.horizontalAlignment = SWT.LEFT; pathButtonEditor.grabHorizontal = true; Button pathChooserButton = new Button(item.getParent(), SWT.PUSH); pathChooserButton.setText("..."); pathChooserButton.setSize(pathChooserButton.getText().length() * 6, 0); pathChooserButton.computeSize(SWT.DEFAULT, item.getParent() .getItemHeight()); pathButtonEditor.minimumWidth = pathChooserButton.getSize().x; pathChooserButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent arg0) { final String selectedPath; if (dataType.equals(PlaceholdersMetaDataConstants.TYPE_DIR)) { selectedPath = PropertyTabGuiHelper .selectDirectoryFromFileSystem(getShell(), "Open path..."); } else { selectedPath = PropertyTabGuiHelper .selectFileFromFileSystem(getShell(), new String[] {}, "Open path..."); } if (selectedPath != null) { placeholderText.setText(selectedPath); } } @Override public void widgetDefaultSelected(SelectionEvent arg0) {} }); pathButtonEditor.setEditor(pathChooserButton, item, 2); } private static Combo addBooleanCombo(TreeItem item) { final Combo combo = new Combo(item.getParent(), SWT.READ_ONLY); combo.add(Boolean.TRUE.toString().toLowerCase()); combo.add(Boolean.FALSE.toString().toLowerCase()); combo.setText(Boolean.TRUE.toString().toLowerCase()); return combo; } private static Image getImage(WorkflowNode element) { byte[] icon = element.getComponentDescription().getIcon16(); Image image; if (icon != null) { image = new Image(Display.getCurrent(), new ByteArrayInputStream( icon)); } else { image = Activator.getInstance().getImageRegistry() .get(Activator.IMAGE_RCE_ICON_16); } return image; } private String getControlText(int id) { Control control = controlMap.get(id); String text = null; if (control instanceof Text) { Text current = (Text) control; text = current.getText(); } else if (control instanceof Combo) { Combo current = (Combo) control; text = current.getText(); } return text; } protected Control getControl(int id) { Control control = controlMap.get(id); return control; } private static boolean isTextEmpty(Text source) { return source.getText() == null || source.getText().equals(""); } protected void validateInput(Text source, String componentName, String placeholderName) { if (!isTextEmpty(source)) { if (source.getBackground().equals(COLOR_RED)) { source.setBackground(COLOR_WHITE); removePlaceholderValidator(componentName, placeholderName); } } else { source.setBackground(COLOR_RED); addPlaceholderValidator(componentName, placeholderName); } } /** * * Verify placeholderPage for errors. Missing input is defined as an error. * * @return whether errors exist or not. */ public boolean validateErrors() { return !placeholderValidators.isEmpty(); } /** * @return amount of errors */ public int getErrorAmount() { return placeholderValidators.size(); } /** * * Retrieve the component names which have an error. * * @param indicator when its true {@link Messages#missingPlaceholder} is placed behind the name * @return set of component names */ public Map<String, String> getComponentNamesWithError(boolean indicator) { Set<String> componentNames = placeholderValidators.keySet(); Map<String, String> newComponentNames = new HashMap<>(); for (String name : componentNames) { String additionalInfos = ""; if (indicator) { additionalInfos = " " + Messages.missingPlaceholder; } newComponentNames.put(name, additionalInfos); } return newComponentNames; } /** * Performs all actions to be done when 'Finish' is clicked. * * @return placeholder map for each {@link WorkflowNode} */ protected void performFinish() { for (TreeItem componentItems : componentPlaceholderTree.getItems()) { for (TreeItem componentIDItems : componentItems.getItems()) { if (componentIDItems.getItemCount() == 0) { // componentPlaceholder for (String fullPlaceholder : placeholderHelper .getPlaceholderOfComponent(getComponentIDByName(componentItems .getText()))) { if (WorkflowPlaceholderHandler.getNameOfPlaceholder(fullPlaceholder) .equals(treeItemNameToPlaceholder.get(componentIDItems.hashCode()))) { boolean addToHistory = true; if (saveButtonMap.get(componentIDItems.hashCode()) != null) { addToHistory = saveButtonMap.get(componentIDItems.hashCode()) .getSelection(); } placeholderHelper .setGlobalPlaceholderValue( fullPlaceholder, getComponentIDByName(componentItems .getText()), getControlText(componentIDItems .hashCode()), workflowDescription.getIdentifier(), addToHistory); } } } else { for (TreeItem instancePlaceholderItems : componentIDItems .getItems()) { // instancePlaceholder for (String fullPlaceholder : placeholderHelper .getPlaceholderNamesOfComponentInstance(treeItemToUUIDMap.get(instancePlaceholderItems.hashCode()))) { if (WorkflowPlaceholderHandler.getNameOfPlaceholder(fullPlaceholder).equals(treeItemNameToPlaceholder .get(instancePlaceholderItems.hashCode()))) { boolean addToHistory = true; if (saveButtonMap.get(instancePlaceholderItems.hashCode()) != null) { addToHistory = saveButtonMap.get( instancePlaceholderItems.hashCode()).getSelection(); } placeholderHelper.setPlaceholderValue(fullPlaceholder, getComponentIDByName(componentIDItems .getText()), treeItemToUUIDMap.get(instancePlaceholderItems.hashCode()), getControlText(instancePlaceholderItems.hashCode()), workflowDescription.getIdentifier(), addToHistory); } } } } } } /// * dispose SWT components */ // for (Integer key : controlMap.keySet()) { // controlMap.get(key).dispose(); // } // componentPlaceholderTree.dispose(); } /** * Saves the placeholder settings to persistent settings. */ protected void savePlaceholdersToPersistentSettings() { if (WorkflowPlaceholderHandler.getPlaceholderPersistentSettingsUUID() == null) { IPreferenceStore prefs = Activator.getInstance() .getPreferenceStore(); String placeholderPersistentSettingsUUID = prefs .getString(WorkflowPlaceholderHandler.PLACEHOLDER_PREFERENCES_KEY); if (placeholderPersistentSettingsUUID.isEmpty()) { WorkflowPlaceholderHandler .setPlaceholderPersistentSettingsUUID(UUID.randomUUID() .toString()); prefs.putValue( WorkflowPlaceholderHandler.PLACEHOLDER_PREFERENCES_KEY, placeholderPersistentSettingsUUID); } } placeholderHelper.saveHistory(); } protected Map<String, Map<String, String>> getPlaceholders() { Map<String, Map<String, String>> placeholdersMap = new HashMap<>(); for (WorkflowNode wn : workflowDescription.getWorkflowNodes()) { Map<String, String> placeholders = new HashMap<>(); Map<String, String> compTypePlaceholders = placeholderHelper.getPlaceholdersOfComponentType(wn .getComponentDescription().getIdentifier()); if (compTypePlaceholders != null) { placeholders.putAll(compTypePlaceholders); } Map<String, String> compInstPlaceholders = placeholderHelper.getPlaceholdersOfComponentInstance(wn.getIdentifier()); if (compInstPlaceholders != null) { placeholders.putAll(compInstPlaceholders); } placeholdersMap.put(wn.getIdentifier(), placeholders); } return placeholdersMap; } private String getComponentIDByName(String name) { for (WorkflowNode wn : workflowDescription.getWorkflowNodes()) { if (wn.getName().equals(name)) { return wn.getComponentDescription().getIdentifier(); } } return null; } private PlaceholdersMetaDataDefinition getPlaceholderAttributes(String name) { for (WorkflowNode wn : workflowDescription.getWorkflowNodes()) { if (wn.getName().equals(name)) { return wn.getComponentDescription() .getConfigurationDescription() .getComponentConfigurationDefinition() .getPlaceholderMetaDataDefinition(); } } return null; } public Map<String, Set<String>> getPlaceholderValidators() { return placeholderValidators; } protected boolean canFinish() { if (componentPlaceholderTree != null) { return componentPlaceholderTree.getItemCount() == 0; } return false; } @Override public void dispose() { /* dispose SWT components */ for (Integer key : controlMap.keySet()) { controlMap.get(key).dispose(); } componentPlaceholderTree.dispose(); super.dispose(); } /** * New Button Listener behaving as follows: if item Name and item DataType are the same, value of that Item/Field/Parameter is replaced. * * @author Jascha Riedel */ private class ButtonListener extends SelectionAdapter { private ExtendedTreeItem extendedTreeItem; private List<ExtendedTreeItem> allItems; ButtonListener(ExtendedTreeItem extendedTreeItem, List<ExtendedTreeItem> allItems) { this.extendedTreeItem = extendedTreeItem; this.allItems = allItems; } @Override public void widgetSelected(SelectionEvent event) { Control treeItemControl = getControl(extendedTreeItem.treeItem.hashCode()); Object valueToBeCoppied = null; if (treeItemControl instanceof Text) { valueToBeCoppied = ((Text) treeItemControl).getText(); } else if (treeItemControl instanceof Combo) { valueToBeCoppied = ((Combo) treeItemControl).getText(); } if (valueToBeCoppied != null && !((String) valueToBeCoppied).isEmpty()) { for (int i = 0; i < allItems.size(); i++) { if (extendedTreeItem.treeItem.getText().equals(allItems.get(i).treeItem.getText())) { if (extendedTreeItem.dataType == null && allItems.get(i).dataType == null) { Control toReplaceItem = getControl(allItems.get(i).treeItem.hashCode()); if (toReplaceItem instanceof Text) { ((Text) toReplaceItem).setText((String) valueToBeCoppied); } else if (toReplaceItem instanceof Combo) { ((Combo) toReplaceItem).select(((Combo) treeItemControl).indexOf((String) valueToBeCoppied)); } } else if (extendedTreeItem.dataType.equals(allItems.get(i).dataType)) { Control toReplaceItem = getControl(allItems.get(i).treeItem.hashCode()); if (toReplaceItem instanceof Text) { ((Text) toReplaceItem).setText((String) valueToBeCoppied); } else if (toReplaceItem instanceof Combo) { ((Combo) toReplaceItem).select(((Combo) treeItemControl).indexOf((String) valueToBeCoppied)); } } } } } } } }