/******************************************************************************* | |
* 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); | |
} | |
} |