blob: cdc3de7221aadde5f3299c60712d343664a65dfe [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.bpel.ui.properties;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.bpel.common.ui.details.IDetailsAreaConstants;
import org.eclipse.bpel.common.ui.details.viewers.CComboViewer;
import org.eclipse.bpel.common.ui.details.viewers.ComboViewerCellEditor;
import org.eclipse.bpel.common.ui.flatui.FlatFormAttachment;
import org.eclipse.bpel.common.ui.flatui.FlatFormData;
import org.eclipse.bpel.model.BPELFactory;
import org.eclipse.bpel.model.BPELPackage;
import org.eclipse.bpel.model.Correlation;
import org.eclipse.bpel.model.CorrelationPattern;
import org.eclipse.bpel.model.CorrelationSet;
import org.eclipse.bpel.model.Correlations;
import org.eclipse.bpel.model.Invoke;
import org.eclipse.bpel.model.OnEvent;
import org.eclipse.bpel.model.OnMessage;
import org.eclipse.bpel.model.PartnerActivity;
import org.eclipse.bpel.ui.IHelpContextIds;
import org.eclipse.bpel.ui.Messages;
import org.eclipse.bpel.ui.commands.AddCorrelationCommand;
import org.eclipse.bpel.ui.commands.RemoveCorrelationCommand;
import org.eclipse.bpel.ui.commands.SetCommand;
import org.eclipse.bpel.ui.commands.SetCorrelationInitiateCommand;
import org.eclipse.bpel.ui.commands.SetCorrelationSetRefCommand;
import org.eclipse.bpel.ui.details.providers.AbstractContentProvider;
import org.eclipse.bpel.ui.details.providers.AddNullFilter;
import org.eclipse.bpel.ui.details.providers.ColumnTableProvider;
import org.eclipse.bpel.ui.details.providers.CorrelationContentProvider;
import org.eclipse.bpel.ui.details.providers.ModelLabelProvider;
import org.eclipse.bpel.ui.details.providers.ModelViewerSorter;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.ModelHelper;
import org.eclipse.bpel.ui.util.MultiObjectAdapter;
import org.eclipse.bpel.ui.util.TableCursor;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.commands.Command;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;
/**
* Details section for the incoming/outgoing correlation sets used by an
* Invoke/Receive/Reply activity.
*/
public class CorrelationSection extends BPELPropertySection {
public static final String YES = "yes"; //$NON-NLS-1$
public static final String NO = "no"; //$NON-NLS-1$
public static final String JOIN = "join"; //$NON-NLS-1$
protected Table correlationTable;
protected TableViewer correlationViewer;
protected ColumnTableProvider tableProvider;
protected TableCursor tableCursor = null;
protected Button addButton;
protected Button removeButton;
protected boolean allowOutgoing;
protected boolean allowIncoming;
public class DirectionColumn extends ColumnTableProvider.Column implements ILabelProvider, ICellModifier {
@Override
public String getHeaderText() { return Messages.CorrelationDetails_Direction_1; }
@Override
public String getProperty() { return "direction"; } //$NON-NLS-1$
@Override
public int getInitialWeight() { return 15; }
// TODO: convert DirectionColumn to use images instead of text?
protected final String[] oneWayStrings = { Messages.CorrelationDetails_Send_5, Messages.CorrelationDetails_Receive_4 };
protected final String[] twoWayStrings = { Messages.CorrelationDetails_Send_5, Messages.CorrelationDetails_Receive_6, Messages.CorrelationDetails_Both_7 };
@Override
public CellEditor createCellEditor(Composite parent) {
return new ComboBoxCellEditor(parent, twoWayStrings);
}
protected int patternIndex(CorrelationPattern pattern) {
if (pattern == CorrelationPattern.RESPONSE_LITERAL) return 0;
if (pattern == CorrelationPattern.REQUEST_LITERAL) return 1;
if (pattern == CorrelationPattern.REQUESTRESPONSE_LITERAL) return 2;
return allowOutgoing? 0 : 1;
}
protected CorrelationPattern indexPattern(int index) {
switch (index) {
case 0: return CorrelationPattern.RESPONSE_LITERAL;
case 1: return CorrelationPattern.REQUEST_LITERAL;
case 2: return CorrelationPattern.REQUESTRESPONSE_LITERAL;
}
throw new IllegalArgumentException();
}
@Override
public Image getImage(Object element) {
return null;
}
public String getText(Object element) {
if (allowOutgoing && allowIncoming) {
return twoWayStrings[patternIndex(((Correlation)element).getPattern())];
}
return oneWayStrings[allowOutgoing? 0 : 1];
}
public boolean canModify(Object element, String property) {
return allowOutgoing && allowIncoming;
}
public Object getValue(Object element, String property) {
return Integer.valueOf( patternIndex(((Correlation)element).getPattern()));
}
public void modify(Object element, String property, Object value) {
int index = ((Integer)value).intValue();
CorrelationPattern pattern = indexPattern(index);
Command cmd = new SetCommand((EObject)element, pattern, BPELPackage.eINSTANCE.getCorrelation_Pattern());
getCommandFramework().execute(wrapInShowContextCommand(cmd));
}
}
public class InitiationColumn extends ColumnTableProvider.Column implements ILabelProvider, ICellModifier {
@Override
public String getHeaderText() { return Messages.CorrelationDetails_Initiation_8; }
@Override
public String getProperty() { return "initiation"; } //$NON-NLS-1$
@Override
public int getInitialWeight() { return 10; }
protected final String[] strings = {
Messages.CorrelationDetails_No_10,
Messages.CorrelationDetails_Yes_11,
Messages.CorrelationDetails_Join_11
};
@Override
public CellEditor createCellEditor(Composite parent) {
ComboBoxCellEditor result = new ComboBoxCellEditor();
result.setStyle(SWT.READ_ONLY);
result.create(parent);
result.setItems(strings);
return result;
}
protected int initiationIndex(String initiation) {
if (YES.equals(initiation))
return 1;
if (JOIN.equals(initiation))
return 2;
return 0;
}
public String getText(Object element) {
return strings[initiationIndex(((Correlation)element).getInitiate())];
}
public boolean canModify(Object element, String property) {
return true;
}
public Object getValue(Object element, String property) {
return Integer.valueOf( initiationIndex(((Correlation)element).getInitiate()));
}
public void modify(Object element, String property, Object value) {
int index = ((Integer)value).intValue();
String initiation = NO;
switch (index) {
case 0:
initiation = NO;
break;
case 1:
initiation = YES;
break;
case 2:
initiation = JOIN;
break;
}
Command cmd = new SetCorrelationInitiateCommand((Correlation)element, initiation);
getCommandFramework().execute(wrapInShowContextCommand(cmd));
}
}
public class NameColumn extends ColumnTableProvider.Column implements ILabelProvider, ICellModifier {
@Override
public String getHeaderText() { return Messages.CorrelationDetails_Correlation_Set_12; }
@Override
public String getProperty() { return "setName"; } //$NON-NLS-1$
@Override
public int getInitialWeight() { return 30; }
ComboViewerCellEditor cellEditor;
ModelLabelProvider labelProvider;
@Override
public CellEditor createCellEditor(Composite parent) {
cellEditor = new ComboViewerCellEditor();
cellEditor.setStyle(SWT.READ_ONLY);
cellEditor.create(parent);
labelProvider = new ModelLabelProvider();
CComboViewer viewer = cellEditor.getViewer();
viewer.addFilter(AddNullFilter.getInstance());
viewer.setContentProvider(new AbstractContentProvider(){
@Override
public Object[] getElements(Object input) {
if (input instanceof EObject)
return BPELUtil.getVisibleCorrelationSets((EObject)input);
return EMPTY_ARRAY;
}
});
viewer.setLabelProvider(labelProvider);
viewer.setSorter(ModelViewerSorter.getInstance());
viewer.setInput(ModelHelper.getContainingScope(getInput()));
return cellEditor;
}
public String getText(Object element) {
return labelProvider.getText(((Correlation)element).getSet());
}
public boolean canModify(Object element, String property) {
return true;
}
public Object getValue(Object element, String property) {
return ((Correlation)element).getSet();
}
public void modify(Object element, String property, Object value) {
Command cmd = new SetCorrelationSetRefCommand((Correlation)element, (CorrelationSet)value);
getCommandFramework().execute(wrapInShowContextCommand(cmd));
}
}
@Override
public boolean shouldUseExtraSpace() { return true; }
protected boolean isCorrelationListAffected(Notification n) {
if (n.getNotifier() instanceof Correlations) return true;
if (n.getNotifier() instanceof PartnerActivity) {
return (n.getFeatureID(PartnerActivity.class) ==
BPELPackage.PARTNER_ACTIVITY__CORRELATIONS);
}
if (n.getNotifier() instanceof OnMessage) {
return (n.getFeatureID(OnMessage.class) == BPELPackage.ON_MESSAGE__CORRELATIONS);
}
if (n.getNotifier() instanceof OnEvent) {
return (n.getFeatureID(OnEvent.class) == BPELPackage.ON_EVENT__CORRELATIONS);
}
return false;
}
@Override
protected MultiObjectAdapter[] createAdapters() {
return new MultiObjectAdapter[] {
/* model object and Correlations object */
new MultiObjectAdapter() {
@Override
public void notify(Notification n) {
if (isCorrelationListAffected(n)) {
updateCorrelationWidgets(null);
refreshAdapters();
}
}
},
/* correlation(s) and correlation set(s) */
new MultiObjectAdapter() {
@Override
public void notify(Notification n) {
if (n.getNotifier() instanceof Correlation) {
updateCorrelationWidgets((Correlation)n.getNotifier());
refreshAdapters();
} else if (n.getNotifier() instanceof CorrelationSet) {
Correlations c = ModelHelper.getCorrelations(getInput());
if (c != null) {
for (Iterator it = c.getChildren().iterator(); it.hasNext(); ) {
Correlation corr = (Correlation)it.next();
fAdapters[1].addToObject(corr);
if (n.getNotifier() == corr.getSet()) {
updateCorrelationWidgets(corr);
refreshAdapters();
break;
}
}
}
}
}
}
};
}
@Override
protected void addAllAdapters() {
super.addAllAdapters();
Correlations c = ModelHelper.getCorrelations(getInput());
if (c != null) {
fAdapters[0].addToObject(c);
for (Iterator it = c.getChildren().iterator(); it.hasNext(); ) {
Correlation corr = (Correlation)it.next();
fAdapters[1].addToObject(corr);
if (corr.getSet() != null) fAdapters[1].addToObject(corr.getSet());
}
}
}
protected Correlation newDefaultCorrelation() {
Correlation correlation = BPELFactory.eINSTANCE.createCorrelation();
correlation.setInitiate(NO);
if (getInput() instanceof Invoke) {
correlation.setPattern(CorrelationPattern.RESPONSE_LITERAL);
}
// Try to select a correlation set that isn't already in the table.
CorrelationSet firstUnusedSet = null;
Correlations c = ModelHelper.getCorrelations(getInput());
List corrList = (c == null)? Collections.EMPTY_LIST : c.getChildren();
HashSet usedSets = new HashSet(corrList.size());
for (Iterator it = corrList.iterator(); it.hasNext(); ) {
usedSets.add(((Correlation)it.next()).getSet());
}
for (Iterator it = getProcess().getCorrelationSets().getChildren().iterator(); it.hasNext(); ) {
CorrelationSet set = (CorrelationSet)it.next();
if (!usedSets.contains(set)) {
// found one we're not using.
firstUnusedSet = set; break;
}
}
// note: it's okay if firstUnusedSet is still null here (we'll show "-- none --").
correlation.setSet(firstUnusedSet);
return correlation;
}
protected void createCorrelationSetWidgets(Composite composite) {
FlatFormData data;
addButton = fWidgetFactory.createButton(composite, Messages.CorrelationDetails_Add_18, SWT.PUSH);
removeButton = fWidgetFactory.createButton(composite, Messages.CorrelationDetails_Remove_19, SWT.PUSH);
Label correlationSetLabel = fWidgetFactory.createLabel(composite, Messages.CorrelationDetails_Correlation_Sets__20);
correlationTable = fWidgetFactory.createTable(composite, SWT.FULL_SELECTION | SWT.V_SCROLL);
data = new FlatFormData();
data.left = new FlatFormAttachment(0, 0);
data.top = new FlatFormAttachment(0, 0);
correlationSetLabel.setLayoutData(data);
data = new FlatFormData();
data.width = BPELUtil.calculateButtonWidth(addButton, STANDARD_BUTTON_WIDTH);
data.right = new FlatFormAttachment(removeButton, -IDetailsAreaConstants.HSPACE);
data.top = new FlatFormAttachment(0, 0);
addButton.setLayoutData(data);
data = new FlatFormData();
data.width = BPELUtil.calculateButtonWidth(removeButton, STANDARD_BUTTON_WIDTH);
data.right = new FlatFormAttachment(100, 0);
data.top = new FlatFormAttachment(0, 0);
removeButton.setLayoutData(data);
removeButton.setEnabled(false);
addButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Correlation correlation = newDefaultCorrelation();
Command cmd = new AddCorrelationCommand(getInput(), correlation);
getCommandFramework().execute(wrapInShowContextCommand(cmd));
correlationViewer.setSelection(new StructuredSelection(correlation));
removeButton.setEnabled(true);
if (tableCursor != null)
tableCursor.refresh();
}
public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); }
});
Listener removeListener = new Listener() {
public void handleEvent(Event e) {
if (e.type == SWT.KeyUp && e.character != SWT.DEL) return;
IStructuredSelection sel = (IStructuredSelection)correlationViewer.getSelection();
Correlation correlation = (Correlation)sel.getFirstElement();
int selectionIndex = correlationTable.getSelectionIndex();
if (correlation != null) {
Command cmd = new RemoveCorrelationCommand(getInput(), correlation);
getCommandFramework().execute(wrapInShowContextCommand(cmd));
}
// selects the element at the deleted element position
int items = correlationTable.getItemCount();
if (items > 0) {
selectionIndex = (selectionIndex < items) ? selectionIndex : 0;
correlationTable.setSelection(selectionIndex);
}
if (tableCursor != null)
tableCursor.refresh();
updateButtonEnablement();
}
};
correlationTable.addListener(SWT.KeyUp, removeListener);
removeButton.addListener(SWT.Selection, removeListener);
removeButton.addListener(SWT.DefaultSelection, removeListener);
data = new FlatFormData();
data.left = new FlatFormAttachment(0, 0);
data.right = new FlatFormAttachment(100, 0);
data.top = new FlatFormAttachment(addButton, IDetailsAreaConstants.VSPACE);
data.bottom = new FlatFormAttachment(100, 0);
correlationTable.setLayoutData(data);
correlationTable.setLinesVisible(true);
correlationTable.setHeaderVisible(true);
tableProvider = new ColumnTableProvider();
tableProvider.add(new DirectionColumn());
tableProvider.add(new InitiationColumn());
tableProvider.add(new NameColumn());
correlationTable.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
removeButton.setEnabled(!correlationViewer.getSelection().isEmpty());
}
public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); }
});
correlationViewer = new TableViewer(correlationTable);
tableProvider.createTableLayout(correlationTable);
correlationViewer.setLabelProvider(tableProvider);
correlationViewer.setCellModifier(tableProvider);
correlationViewer.setContentProvider(new CorrelationContentProvider());
// TODO: should this have a sorter?
correlationViewer.setColumnProperties(tableProvider.getColumnProperties());
correlationViewer.addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event) {
updateButtonEnablement();
}
});
tableCursor = BPELUtil.createTableCursor(correlationTable, correlationViewer);
}
@Override
protected void createClient(Composite parent) {
Composite composite = createFlatFormComposite(parent);
createCorrelationSetWidgets(composite);
PlatformUI.getWorkbench().getHelpSystem().setHelp(
composite, IHelpContextIds.PROPERTY_PAGE_CORRELATION);
}
protected void updateCorrelationWidgets(Correlation corr) {
Object input = getInput();
if (input == null) throw new IllegalStateException();
allowOutgoing = ModelHelper.isMessageActivity(input, ModelHelper.OUTGOING);
allowIncoming = ModelHelper.isMessageActivity(input, ModelHelper.INCOMING);
correlationViewer.setInput(getInput());
if (corr != null) {
correlationViewer.refresh(corr, true);
} else {
correlationViewer.refresh();
}
if (tableCursor != null)
tableCursor.refresh();
}
@Override
public void refresh() {
super.refresh();
updateCorrelationWidgets(null);
}
@Override
public Object getUserContext() {
return ((StructuredSelection)correlationViewer.getSelection()).getFirstElement();
}
@Override
public void restoreUserContext(Object userContext) {
correlationTable.setFocus();
if (userContext != null) {
correlationViewer.setSelection(new StructuredSelection(userContext));
}
}
@Override
protected void basicSetInput(EObject newInput) {
super.basicSetInput(newInput);
correlationViewer.setCellEditors(tableProvider.createCellEditors(correlationTable));
}
protected void updateButtonEnablement(){
boolean hasSelection = !correlationViewer.getSelection().isEmpty();
removeButton.setEnabled(hasSelection);
}
}