/******************************************************************************* * 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.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import javax.xml.namespace.QName; import org.eclipse.bpel.common.ui.details.IDetailsAreaConstants; import org.eclipse.bpel.common.ui.details.IOngoingChange; import org.eclipse.bpel.common.ui.flatui.FlatFormAttachment; import org.eclipse.bpel.common.ui.flatui.FlatFormData; import org.eclipse.bpel.model.Activity; import org.eclipse.bpel.model.BPELFactory; import org.eclipse.bpel.model.BPELPackage; import org.eclipse.bpel.model.Catch; import org.eclipse.bpel.model.CatchAll; import org.eclipse.bpel.model.ElseIf; import org.eclipse.bpel.model.FaultHandler; import org.eclipse.bpel.model.Flow; import org.eclipse.bpel.model.If; import org.eclipse.bpel.model.Import; import org.eclipse.bpel.model.Invoke; import org.eclipse.bpel.model.OnAlarm; import org.eclipse.bpel.model.OnMessage; import org.eclipse.bpel.model.PartnerLink; import org.eclipse.bpel.model.Pick; import org.eclipse.bpel.model.Process; import org.eclipse.bpel.model.RepeatUntil; import org.eclipse.bpel.model.Scope; import org.eclipse.bpel.model.Sequence; import org.eclipse.bpel.model.Throw; import org.eclipse.bpel.model.Variable; import org.eclipse.bpel.model.While; import org.eclipse.bpel.model.partnerlinktype.Role; import org.eclipse.bpel.model.util.BPELConstants; import org.eclipse.bpel.model.util.BPELUtils; import org.eclipse.bpel.ui.IBPELUIConstants; import org.eclipse.bpel.ui.IHelpContextIds; import org.eclipse.bpel.ui.Messages; import org.eclipse.bpel.ui.commands.CompoundCommand; import org.eclipse.bpel.ui.commands.SetFaultNameCommand; import org.eclipse.bpel.ui.commands.SetFaultNamespaceCommand; import org.eclipse.bpel.ui.commands.SetNameCommand; import org.eclipse.bpel.ui.commands.SetVariableCommand; import org.eclipse.bpel.ui.commands.SetVariableKindCommand; import org.eclipse.bpel.ui.commands.util.AutoUndoCommand; import org.eclipse.bpel.ui.dialogs.TypeSelectorDialog; import org.eclipse.bpel.ui.uiextensionmodel.VariableExtension; import org.eclipse.bpel.ui.util.BPELUtil; import org.eclipse.bpel.ui.util.BatchedMultiObjectAdapter; import org.eclipse.bpel.ui.util.ModelHelper; import org.eclipse.bpel.ui.util.MultiObjectAdapter; import org.eclipse.bpel.ui.util.NamespaceUtils; import org.eclipse.bpel.ui.util.WSDLImportHelper; import org.eclipse.core.runtime.Assert; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.gef.commands.Command; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.wst.wsdl.Definition; import org.eclipse.wst.wsdl.Fault; import org.eclipse.wst.wsdl.Message; import org.eclipse.wst.wsdl.Operation; import org.eclipse.wst.wsdl.PortType; import org.eclipse.wst.wsdl.util.WSDLConstants; import org.eclipse.xsd.XSDElementDeclaration; import org.eclipse.xsd.XSDTypeDefinition; /** * Details section for the fault name referenced in a Catch. */ public class FaultCatchNameSection extends BPELPropertySection { protected static final int NAME_BUILTIN_CONTEXT = 0; protected static final int NAMESPACE_CONTEXT = 1; protected static final int VARIABLE_CONTEXT = 2; protected static final int BUILTINRADIO_CONTEXT = 3; protected static final int USERDEFRADIO_CONTEXT = 4; protected static final int NAME_USERDEF_CONTEXT = 5; protected static final int FAULT_VARIABLE_NAME_CONTEXT = 6; protected static final int FAULT_VARIABLE_TYPE_CONTEXT = 7; protected int lastChangeContext = -1; protected VariableTypeSelector variableTypeSelector; protected boolean isCatch, isFaultTypeEnabled; protected Composite parentComposite; protected Composite faultTypeComposite, namespaceComposite, faultNameComposite, faultUserDefNameComposite, faultVariableNameComposite; protected Button builtinRadio, userdefRadio; protected Text variableNameText; protected CCombo faultNameCombo, faultUserDefCombo, faultNamespaceCombo; protected ChangeTracker faultNameTracker, faultNamespaceTracker, faultUserDefNameTracker, variableNameTracker; protected Vector<QName> faultNameQNames; public FaultCatchNameSection() { super(); } @Override protected MultiObjectAdapter[] createAdapters() { return new BatchedMultiObjectAdapter[] { /* model object */ new BatchedMultiObjectAdapter() { boolean refreshFaultName = false; boolean refreshUserDefFaultName = false; boolean refreshFaultNamespace = false; boolean refreshVariable = false; @Override public void notify(Notification n) { if (ModelHelper.isFaultNameAffected(getInput(), n) && builtinRadio.getSelection()) { refreshFaultName = true; } if (ModelHelper.isFaultNameAffected(getInput(), n) && userdefRadio.getSelection()) { refreshUserDefFaultName = true; } if (isFaultTypeEnabled && ModelHelper.isFaultNamespaceAffected(getInput(), n)) { refreshFaultNamespace = true; } if (ModelHelper.isVariableAffected(getInput(), n, ModelHelper.INCOMING)) { refreshVariable = true; } else if (n.getFeatureID(Catch.class) == BPELPackage.CATCH__FAULT_MESSAGE_TYPE) { refreshVariable = true; } } @Override public void finish() { if (refreshFaultName) updateFaultNameWidgets(); if (refreshFaultNamespace) updateFaultNamespaceWidgets(); if (refreshUserDefFaultName) updateUserDefFaultNameWidgets(); if (refreshVariable) updateVariableWidgets(); refreshFaultName = false; refreshUserDefFaultName = false; refreshFaultNamespace = false; refreshVariable = false; } }, }; } protected boolean isNamespaceUserDef() { return (!isFaultTypeEnabled) || userdefRadio.getSelection(); } protected void doChildLayout() { FlatFormData data = null; FlatFormData data1 = null; boolean isNamespaceUserDef = isNamespaceUserDef(); if (isFaultTypeEnabled) { data = (FlatFormData)namespaceComposite.getLayoutData(); data.top = new FlatFormAttachment(faultTypeComposite, IDetailsAreaConstants.VSPACE); if (isNamespaceUserDef) { data = (FlatFormData)faultUserDefNameComposite.getLayoutData(); data.top = new FlatFormAttachment(namespaceComposite, IDetailsAreaConstants.VSPACE); data1 = (FlatFormData)faultVariableNameComposite.getLayoutData(); data1.top = new FlatFormAttachment(faultUserDefNameComposite, IDetailsAreaConstants.VSPACE); } else { data = (FlatFormData)faultNameComposite.getLayoutData(); data.top = new FlatFormAttachment(faultTypeComposite, IDetailsAreaConstants.VSPACE); data1 = (FlatFormData)faultVariableNameComposite.getLayoutData(); data1.top = new FlatFormAttachment(faultNameComposite, IDetailsAreaConstants.VSPACE); } } else { data = (FlatFormData)namespaceComposite.getLayoutData(); data.top = new FlatFormAttachment(0, 0); // note: isNamespaceUserDef == true data = (FlatFormData)faultUserDefNameComposite.getLayoutData(); data.top = new FlatFormAttachment(namespaceComposite, IDetailsAreaConstants.VSPACE); data1 = (FlatFormData)faultVariableNameComposite.getLayoutData(); data1.top = new FlatFormAttachment(faultUserDefNameComposite, IDetailsAreaConstants.VSPACE); } faultTypeComposite.setVisible(isFaultTypeEnabled); namespaceComposite.setVisible(isNamespaceUserDef); faultNameComposite.setVisible(!isNamespaceUserDef); faultUserDefNameComposite.setVisible(isNamespaceUserDef); parentComposite.layout(true); parentComposite.getParent().layout(true); } @Override public boolean shouldUseExtraSpace() { return true; } @Override protected void basicSetInput(EObject input) { super.basicSetInput(input); rearrangeWidgets(); } protected void rearrangeWidgets() { isCatch = (getInput() instanceof Catch); isFaultTypeEnabled = true; if (isCatch) { FaultHandler faultHandler = (FaultHandler)getInput().eContainer(); if (faultHandler != null) { Object maybeInvoke = faultHandler.eContainer(); if (maybeInvoke instanceof Invoke) isFaultTypeEnabled = false; } } doChildLayout(); } protected void createFaultTypeWidgets(Composite parent) { FlatFormData data; Composite composite = faultTypeComposite = createFlatFormComposite(parent); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(100, 0); data.top = new FlatFormAttachment(0, 0); composite.setLayoutData(data); Label faultTypeLabel = fWidgetFactory.createLabel(composite, Messages.FaultCatchNameDetails_Fault_Type__13); builtinRadio = fWidgetFactory.createButton(composite, Messages.FaultCatchNameDetails_Built_in_14, SWT.RADIO); data = new FlatFormData(); data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth(faultTypeLabel, STANDARD_LABEL_WIDTH_SM)); // hack: fudge vertical alignment. data.top = new FlatFormAttachment(0, 2); builtinRadio.setLayoutData(data); builtinRadio.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (!builtinRadio.getSelection()) return; doChildLayout(); // hack! updateFaultNameWidgets(); updateUserDefFaultNameWidgets(); CompoundCommand command = new CompoundCommand(); String newName = faultNameCombo.getText(); Command cmd = new SetFaultNameCommand(getInput(), isEmptyMessageType(newName) ? "" : newName); if (cmd.canExecute()) command.add(cmd); cmd = new SetFaultNamespaceCommand(getInput(), BPELConstants.NAMESPACE); if (cmd.canExecute()) command.add(cmd); command.setLabel(cmd.getLabel()); if (command.canExecute()) { lastChangeContext = BUILTINRADIO_CONTEXT; getCommandFramework().execute(wrapInShowContextCommand(command)); } updateUserDefFaultNameWidgets(); updateFaultNameWidgets(); updateFaultNamespaceWidgets(); } public void widgetDefaultSelected(SelectionEvent e) { // Do nothing - widgetDefaultSelected is not called. } }); userdefRadio = fWidgetFactory.createButton(composite, Messages.FaultCatchNameDetails_User_defined_15, SWT.RADIO); data = new FlatFormData(); data.left = new FlatFormAttachment(builtinRadio, IDetailsAreaConstants.HSPACE); data.top = new FlatFormAttachment(0, 2); userdefRadio.setLayoutData(data); userdefRadio.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (!userdefRadio.getSelection()) return; doChildLayout(); // hack! String s = ""; //$NON-NLS-1$ Vector<QName> names = getFaultNames(getProcess().getTargetNamespace()); if (!names.isEmpty()) s = (names.get(0)).getLocalPart(); CompoundCommand command = new CompoundCommand(); Command cmd = new SetFaultNameCommand(getInput(), (s==null)? "" : s); //$NON-NLS-1$ if (cmd.canExecute()) command.add(cmd); // Set the namespace to the process namespace. cmd = new SetFaultNamespaceCommand(getInput(), getProcess().getTargetNamespace()); if (cmd.canExecute()) command.add(cmd); if (command.canExecute()) { lastChangeContext = USERDEFRADIO_CONTEXT; getCommandFramework().execute(wrapInShowContextCommand(command)); } updateUserDefFaultNameWidgets(); updateFaultNameWidgets(); updateFaultNamespaceWidgets(); } public void widgetDefaultSelected(SelectionEvent e) { // Do nothing - widgetDefaultSelected is not called. } }); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(builtinRadio, -IDetailsAreaConstants.HSPACE); data.top = new FlatFormAttachment(builtinRadio, 0, SWT.CENTER); faultTypeLabel.setLayoutData(data); } protected void createChangeTrackers() { IOngoingChange change = new IOngoingChange() { public String getLabel() { return IBPELUIConstants.CMD_EDIT_FAULTNAME; } public Command createApplyCommand() { String name = faultNameCombo.getText(); CompoundCommand command = new CompoundCommand(); String newName = "".equals(name)? null : name; //$NON-NLS-1$ Command newNameCommand = new SetFaultNameCommand(getInput(), isEmptyMessageType(newName) ? "" : newName); if (newNameCommand.canExecute()) command.add(newNameCommand); Command c2 = new SetFaultNamespaceCommand(getInput(), BPELConstants.NAMESPACE); if (c2.canExecute()) command.add(c2); lastChangeContext = NAME_BUILTIN_CONTEXT; return wrapInShowContextCommand(command); } public void restoreOldState() { updateFaultNameWidgets(); } }; faultNameTracker = new ChangeTracker(faultNameCombo, change, getCommandFramework()); change = new IOngoingChange() { public String getLabel() { return IBPELUIConstants.CMD_EDIT_FAULTNAME; } public Command createApplyCommand() { String s = NamespaceUtils.convertNamespaceToUri(faultNamespaceCombo.getText()); lastChangeContext = NAMESPACE_CONTEXT; CompoundCommand command = new CompoundCommand(); command.add(new SetFaultNamespaceCommand(getInput(), "".equals(s)? null : s)); //$NON-NLS-1$ Vector<QName> faultNames = getFaultNames(s); String name = null; if (!faultNames.isEmpty()) { name = (faultNames.get(0)).getLocalPart(); } command.add(new SetFaultNameCommand(getInput(), isEmptyMessageType(name) ? "" : name)); return wrapInShowContextCommand(command); } public void restoreOldState() { updateFaultNamespaceWidgets(); } }; faultNamespaceTracker = new ChangeTracker(faultNamespaceCombo, change, getCommandFramework()); change = new IOngoingChange() { public String getLabel() { return IBPELUIConstants.CMD_EDIT_FAULTNAME; } public Command createApplyCommand() { lastChangeContext = NAME_USERDEF_CONTEXT; String faultName = faultUserDefCombo.getText(); String namespace = NamespaceUtils.convertNamespaceToUri(faultNamespaceCombo.getText()); if (!validNamespaceFaultNameCombination(namespace, faultName)) { namespace = NamespaceUtils.convertUriToNamespace(getNamespaceByFaultName(faultName)); if (namespace == null) namespace = ""; //$NON-NLS-1$ } faultNamespaceCombo.setText(NamespaceUtils.convertUriToNamespace(namespace)); CompoundCommand command = new CompoundCommand(IBPELUIConstants.CMD_EDIT_FAULTNAME); command.add(new SetFaultNamespaceCommand(getInput(), "".equals(namespace) ? null : namespace)); //$NON-NLS-1$ String newName = "".equals(faultName) ? null : faultName; command.add(new SetFaultNameCommand(getInput(), isEmptyMessageType(newName) ? "" : newName)); //$NON-NLS-1$ return wrapInShowContextCommand(command); } public void restoreOldState() { updateUserDefFaultNameWidgets(); } }; faultUserDefNameTracker = new ChangeTracker(faultUserDefCombo, change, getCommandFramework()); change = new IOngoingChange() { public String getLabel() { return IBPELUIConstants.CMD_SELECT_VARIABLE; } public Command createApplyCommand() { final Catch _catch = (Catch)getInput(); String s = variableNameText.getText(); if ("".equals(s)) s = null; //$NON-NLS-1$ CompoundCommand result = new CompoundCommand(); Variable variable = _catch.getFaultVariable(); if (s != null) { if (variable == null) { variable = BPELFactory.eINSTANCE.createVariable(); result.add(new SetVariableCommand(_catch, variable, ModelHelper.INCOMING)); } result.add(new SetNameCommand(variable, s)); } else { if (variable != null) { result.add(new SetVariableCommand(_catch, null, ModelHelper.INCOMING)); } } lastChangeContext = FAULT_VARIABLE_NAME_CONTEXT; return wrapInShowContextCommand(result); } public void restoreOldState() { updateVariableWidgets(); } }; variableNameTracker = new ChangeTracker(variableNameText, change, getCommandFramework()); } protected void createFaultNameWidgets(Composite parent) { FlatFormData data; Composite composite = faultNameComposite = createFlatFormComposite(parent); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(100, 0); data.top = new FlatFormAttachment(namespaceComposite, IDetailsAreaConstants.VSPACE); composite.setLayoutData(data); faultNameCombo = fWidgetFactory.createCCombo(composite); Label faultNameLabel = fWidgetFactory.createLabel(composite, Messages.FaultCatchNameDetails_Fault_Name__16); data = new FlatFormData(); data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth(faultNameLabel, STANDARD_LABEL_WIDTH_SM)); data.right = new FlatFormAttachment(50, -SHORT_BUTTON_WIDTH-IDetailsAreaConstants.HSPACE-IDetailsAreaConstants.CENTER_SPACE); data.top = new FlatFormAttachment(0, 0); List<String> faultNames = getBuiltinFaultNames(); String[] result = faultNames.toArray(new String[faultNames.size()]); faultNameCombo.setItems(result); faultNameCombo.setLayoutData(data); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(faultNameCombo, -IDetailsAreaConstants.HSPACE); data.top = new FlatFormAttachment(faultNameCombo, 0, SWT.CENTER); faultNameLabel.setLayoutData(data); } protected void createNamespaceWidgets(Composite parent) { FlatFormData data; final Composite composite = namespaceComposite = createFlatFormComposite(parent); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(100, 0); data.top = new FlatFormAttachment(faultTypeComposite, IDetailsAreaConstants.VSPACE); composite.setLayoutData(data); faultNamespaceCombo = fWidgetFactory.createCCombo(composite); Label faultNamespaceLabel = fWidgetFactory.createLabel(composite, Messages.FaultCatchNameDetails_Namespace__21); data = new FlatFormData(); data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth(faultNamespaceLabel, STANDARD_LABEL_WIDTH_SM)); data.right = new FlatFormAttachment(50, -SHORT_BUTTON_WIDTH-IDetailsAreaConstants.HSPACE-IDetailsAreaConstants.CENTER_SPACE); data.top = new FlatFormAttachment(0, +1); faultNamespaceCombo.setLayoutData(data); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(faultNamespaceCombo, -IDetailsAreaConstants.HSPACE); data.top = new FlatFormAttachment(faultNamespaceCombo, 0, SWT.CENTER); faultNamespaceLabel.setLayoutData(data); data = new FlatFormData(); data.right = new FlatFormAttachment(100, 0); data.left = new FlatFormAttachment(100, -STANDARD_BUTTON_WIDTH); data.top = new FlatFormAttachment(faultNamespaceCombo, -1, SWT.TOP); data.bottom = new FlatFormAttachment(faultNamespaceCombo, +1, SWT.BOTTOM); } protected void createUserDefFaultNameWidgets(Composite parent) { FlatFormData data; Composite composite = faultUserDefNameComposite = createFlatFormComposite(parent); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(100, 0); data.top = new FlatFormAttachment(namespaceComposite, IDetailsAreaConstants.VSPACE); composite.setLayoutData(data); Label faultUserDefNameLabel = fWidgetFactory.createLabel(composite, Messages.FaultCatchNameDetails_Fault_Name__24); faultUserDefCombo = fWidgetFactory.createCCombo(composite, SWT.FLAT | SWT.READ_ONLY); data = new FlatFormData(); data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth(faultUserDefNameLabel, STANDARD_LABEL_WIDTH_SM)); data.right = new FlatFormAttachment(50, -SHORT_BUTTON_WIDTH - IDetailsAreaConstants.HSPACE - IDetailsAreaConstants.CENTER_SPACE); data.top = new FlatFormAttachment(0, +1); faultUserDefCombo.setLayoutData(data); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(faultUserDefCombo, -IDetailsAreaConstants.HSPACE); data.top = new FlatFormAttachment(faultUserDefCombo, 0, SWT.CENTER); faultUserDefNameLabel.setLayoutData(data); } public class FaultVariableTypeCallback implements VariableTypeSelector.Callback { protected void store(final EObject type) { final Catch _catch = (Catch)getInput(); CompoundCommand command = new CompoundCommand(); command.add(new AutoUndoCommand(getProcess()) { @Override public void doExecute() { Variable variable = _catch.getFaultVariable(); if (variable == null) { variable = BPELFactory.eINSTANCE.createVariable(); _catch.setFaultVariable(variable); } // https://issues.jboss.org/browse/JBIDE-8045 // Data caught by fault handler can be either a Message Type // or an XSD Element. if (type instanceof Message) { _catch.setFaultMessageType((Message)type); _catch.setFaultElement(null); } else if (type instanceof XSDElementDeclaration) { _catch.setFaultMessageType(null); _catch.setFaultElement((XSDElementDeclaration)type); } } }); getCommandFramework().execute(wrapInShowContextCommand(command)); } public void selectRadioButton(final int index) { final Catch _catch = (Catch)getInput(); Variable variable = _catch.getFaultVariable(); if (variable == null) { variable = BPELFactory.eINSTANCE.createVariable(); } final Variable variable2 = variable; CompoundCommand command = new CompoundCommand(); command.add(new AutoUndoCommand(getProcess()) { @Override public void doExecute() { if (_catch.getFaultVariable() != variable2) { _catch.setFaultVariable(variable2); } ModelHelper.createExtensionIfNecessary( getBPELEditor().getExtensionMap(), variable2); _catch.setFaultMessageType(null); VariableExtension varExt = (VariableExtension)ModelHelper.getExtension(variable2); if ((varExt.getVariableKind() != index)) { (new SetVariableKindCommand(varExt, index)).execute(); } } }); if (!command.isEmpty()) getCommandFramework().execute(wrapInShowContextCommand(command)); } // https://issues.jboss.org/browse/JBIDE-8045 public void selectXSDType(XSDTypeDefinition xsdType) { MessageDialog.openError(null, Messages.SelectionAndCreationDialog_Error_2, Messages.FaultCatchNameSection_Error_Invalid_Type); } public void selectXSDElement(XSDElementDeclaration xsdElement) { store(xsdElement); } public void selectMessageType(Message message) { store(message); } } protected void createVariableWidgets(Composite parent) { FlatFormData data; final Composite composite = faultVariableNameComposite = createFlatFormComposite(parent); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.right = new FlatFormAttachment(100, 0); data.top = new FlatFormAttachment(faultNameComposite, IDetailsAreaConstants.VSPACE); composite.setLayoutData(data); Label variableLabel = fWidgetFactory.createLabel(composite, Messages.FaultCatchNameSection_Variable_Name_3); data = new FlatFormData(); data.left = new FlatFormAttachment(0, 0); data.top = new FlatFormAttachment(0, 0); variableLabel.setLayoutData(data); variableNameText = fWidgetFactory.createText(composite, ""); //$NON-NLS-1$ data = new FlatFormData(); data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth(variableLabel, STANDARD_LABEL_WIDTH_SM)); data.right = new FlatFormAttachment(50, 0); data.top = new FlatFormAttachment(0, 0); variableNameText.setLayoutData(data); variableNameText.addListener(SWT.Modify, new Listener() { public void handleEvent(Event event) { updateVariableTypeSelector(); } }); // https://issues.jboss.org/browse/JBIDE-8045 variableTypeSelector = new VariableTypeSelector(composite, SWT.NONE, getBPELEditor(), fWidgetFactory, new FaultVariableTypeCallback(), false, TypeSelectorDialog.INCLUDE_ELEMENT_DECLARATIONS | TypeSelectorDialog.INCLUDE_MESSAGE_TYPES); data = new FlatFormData(); data.top = new FlatFormAttachment(variableNameText, IDetailsAreaConstants.VSPACE+4); data.left = new FlatFormAttachment(0,0); data.right = new FlatFormAttachment(100,0); data.bottom = new FlatFormAttachment(100,0); variableTypeSelector.setLayoutData(data); } @Override protected void createClient(Composite parent) { parentComposite = createFlatFormComposite(parent); createFaultTypeWidgets(parentComposite); createUserDefFaultNameWidgets(parentComposite); createNamespaceWidgets(parentComposite); createFaultNameWidgets(parentComposite); createVariableWidgets(parentComposite); createChangeTrackers(); PlatformUI.getWorkbench().getHelpSystem().setHelp( parentComposite, IHelpContextIds.PROPERTY_PAGE_FAULT); } protected void updateFaultNameWidgets() { Assert.isNotNull(getInput()); faultNameTracker.stopTracking(); try { String s = ModelHelper.getFaultName(getInput()); if (s == null || "".equals(s)) { //$NON-NLS-1$ faultNameCombo.setText(Messages.FaultCatchNameSection_None_0); } else if (!s.equals(faultNameCombo.getText())) { if (faultNameCombo.indexOf(s) == -1) s = ""; //$NON-NLS-1$ faultNameCombo.setText(s); } } finally { faultNameTracker.startTracking(); } } protected void updateUserDefFaultNameWidgets() { Assert.isNotNull(getInput()); faultUserDefNameTracker.stopTracking(); try { String namespace = ModelHelper.getFaultNamespace(getInput()); Vector<QName> faultNames; if (namespace == null) faultNames = getFaultNames(); else faultNames = getFaultNames(namespace); faultUserDefCombo.removeAll(); for (QName faultName : faultNames) { if (faultUserDefCombo.indexOf(faultName.getLocalPart()) == -1) faultUserDefCombo.add(faultName.getLocalPart()); } String s = ModelHelper.getFaultName(getInput()); if (s == null) s = ""; //$NON-NLS-1$ if (!s.equals(faultUserDefCombo.getText())) { if (faultUserDefCombo.indexOf(s) == -1) { faultUserDefCombo.setText(""); //$NON-NLS-1$ } else { faultUserDefCombo.setText(s); } } } finally { faultUserDefNameTracker.startTracking(); } } protected void updateFaultNamespaceWidgets() { Assert.isNotNull(getInput()); faultNamespaceTracker.stopTracking(); try { Vector<QName> namespaces = getFaultNames(); faultNamespaceCombo.removeAll(); for (QName qname : namespaces) { String uri = NamespaceUtils.convertUriToNamespace(qname.getNamespaceURI()); if (faultNamespaceCombo.indexOf(uri) == -1) faultNamespaceCombo.add(uri); } String s = ModelHelper.getFaultNamespace(getInput()); s = NamespaceUtils.convertUriToNamespace(s); if (s == null) s = ""; //$NON-NLS-1$ if (!s.equals(faultNamespaceCombo.getText())) { if (faultNamespaceCombo.indexOf(s) == -1) s = ""; //$NON-NLS-1$ faultNamespaceCombo.setText(s); } } finally { faultNamespaceTracker.startTracking(); } } protected void updateFaultTypeWidgets() { Assert.isNotNull(getInput()); String faultNamespace = ModelHelper.getFaultNamespace(getInput()); boolean isBuiltin = isBuiltinFault(faultNamespace); builtinRadio.setSelection(isBuiltin); userdefRadio.setSelection(!isBuiltin); doChildLayout(); } protected void updateVariableTypeSelector() { Catch _catch = (Catch)getInput(); if (_catch.getFaultVariable() == null) { variableTypeSelector.setVariableType(null); String name = variableNameText.getText(); variableTypeSelector.setEnabled(name != null && !"".equals(name)); //$NON-NLS-1$ } else { variableTypeSelector.setEnabled(true); } if (_catch.getFaultMessageType() != null) { variableTypeSelector.setVariableType(_catch.getFaultMessageType()); } // https://issues.jboss.org/browse/JBIDE-8045 if (_catch.getFaultElement() != null) { variableTypeSelector.setVariableType(_catch.getFaultElement()); } } @Override public void refresh() { super.refresh(); updateFaultTypeWidgets(); updateFaultNamespaceWidgets(); updateUserDefFaultNameWidgets(); updateFaultNameWidgets(); updateVariableWidgets(); } protected void updateVariableWidgets() { variableNameTracker.stopTracking(); try { Catch _catch = (Catch)getInput(); Variable variable = _catch.getFaultVariable(); if (variable == null) { variableNameText.setText(""); //$NON-NLS-1$ } else { variableNameText.setText(variable.getName() == null ? "" : variable.getName()); //$NON-NLS-1$ } updateVariableTypeSelector(); } finally { variableNameTracker.startTracking(); } } protected String getFaultNameByNamespace(String namespace) { Vector<QName> faultNames = getFaultNames(); Assert.isNotNull(faultNames); for (QName qname : faultNames) { if (qname.getNamespaceURI().equals(namespace)) return qname.getLocalPart(); } return null; } protected String getNamespaceByFaultName(String faultname) { Vector<QName> faultNames = getFaultNames(); Assert.isNotNull(faultNames); for (QName qname : faultNames) { if (qname.getLocalPart().equals(faultname)) return qname.getNamespaceURI(); } return null; } protected boolean validNamespaceFaultNameCombination(String namespace, String faultname) { Vector<QName> faultNames = getFaultNames(); Assert.isNotNull(faultNames); for (QName qname : faultNames) { if (qname.getLocalPart().equals(faultname) && qname.getNamespaceURI().equals(namespace)) return true; } return false; } protected void getFaultNames(Object activity) { EList<Activity> activities = null; if (activity instanceof Sequence) activities = ((Sequence) activity).getActivities(); if (activity instanceof Flow) activities = ((Flow) activity).getActivities(); if (activity instanceof While) getFaultNames(((While) activity).getActivity()); if (activity instanceof RepeatUntil) getFaultNames(((RepeatUntil) activity).getActivity()); if (activity instanceof If) { for (ElseIf elif : ((If) activity).getElseIf()) { getFaultNames(elif.getActivity()); } } if (activity instanceof Pick) { for (OnMessage onMessage : ((Pick) activity).getMessages()) { getFaultNames(onMessage.getActivity()); } for (OnAlarm onAlarm : ((Pick) activity).getAlarm()) { getFaultNames(onAlarm.getActivity()); } } if (activity instanceof Scope) { Scope scope = (Scope) activity; FaultHandler faultHandler = scope.getFaultHandlers(); if (faultHandler != null) { for (Catch c : faultHandler.getCatch()) { getFaultNames(c.getActivity()); } CatchAll catchAll = faultHandler.getCatchAll(); if (catchAll != null) { getFaultNames(catchAll.getActivity()); } } getFaultNames(scope.getActivity()); } if (activities != null) { for (Activity subActivity : activities) { getFaultNames(subActivity); } } if (activity instanceof Throw) { QName name = ((Throw)activity).getFaultName(); if (name != null) { faultNameQNames.add(name); } } } protected Vector<QName> getFaultNames(String namespace) { Vector<QName> result = new Vector<QName>(); for (QName qname : getFaultNames()) { if (qname.getNamespaceURI().equals(namespace)) result.add(qname); } return result; } protected Vector<QName> getFaultNames() { faultNameQNames = new Vector<QName>(); if (getInput() == null) throw new IllegalStateException(); Process p = BPELUtils.getProcess(getInput()); // get FaultNames from activities getFaultNames(p.getActivity()); for (PartnerLink partnerLink : p.getPartnerLinks().getChildren()) { Role role = partnerLink.getMyRole(); if (role == null) role = partnerLink.getPartnerRole(); if (role != null) { PortType portType = (PortType)role.getPortType(); if (portType != null && !portType.eIsProxy()) { for (Iterator operationsIterator = portType.getEOperations().iterator(); operationsIterator.hasNext();) { Operation operation = (Operation) operationsIterator.next(); Map faults = operation.getFaults(); if (faults != null) { if (faults.size() > 0) { for (Iterator faultsIter = faults.values().iterator(); faultsIter.hasNext();) { Fault fault = (Fault) faultsIter.next(); faultNameQNames.add(new QName(portType.getQName().getNamespaceURI(), fault.getName())); } } } } } } } return faultNameQNames; } public static class FaultCatchContext { public int context; public Object innerContext; FaultCatchContext(int context) { this.context = context; } } @Override public Object getUserContext() { FaultCatchContext result = new FaultCatchContext(lastChangeContext); if (lastChangeContext == FAULT_VARIABLE_TYPE_CONTEXT) { result.innerContext = variableTypeSelector.getUserContext(); } return result; } @Override public void restoreUserContext(Object userContext) { FaultCatchContext c = (FaultCatchContext)userContext; switch (c.context) { case NAME_BUILTIN_CONTEXT: faultNameCombo.setFocus(); return; case NAMESPACE_CONTEXT: faultNamespaceCombo.setFocus(); return; case BUILTINRADIO_CONTEXT: builtinRadio.setFocus(); return; case USERDEFRADIO_CONTEXT: userdefRadio.setFocus(); return; case NAME_USERDEF_CONTEXT: faultUserDefCombo.setFocus(); return; case FAULT_VARIABLE_NAME_CONTEXT: variableNameText.setFocus(); return; case FAULT_VARIABLE_TYPE_CONTEXT: variableTypeSelector.restoreUserContext(c.innerContext); return; } throw new IllegalStateException(); } private Command getCreateNewVariableCommand() { return new AutoUndoCommand(getProcess()) { @Override public void doExecute() { CompoundCommand result = new CompoundCommand(); // if the variable does not exist or does not have a type, // create one and assign the best default type Catch _catch = (Catch)getInput(); Variable variable = _catch.getFaultVariable(); QName faultQName = ModelHelper.getFaultQName(getInput()); Message type = getFaultMessage(faultQName); variable = BPELFactory.eINSTANCE.createVariable(); variable.setMessageType(type); result.add(new SetVariableCommand(_catch, variable, ModelHelper.INCOMING)); // set variable name command String name = variableNameText.getText(); if (name == null || "".equals(name)) { //$NON-NLS-1$ String hint = BPELPackage.eINSTANCE.getVariable().getName(); name = BPELUtil.getUniqueModelName(getProcess(), hint, null); } result.add(new SetNameCommand(variable, name)); result.execute(); } }; } /** * Gets the fault message from the fault qname. */ protected Message getFaultMessage(QName faultQName) { if (faultQName == null || faultQName.getNamespaceURI() == null || faultQName.getLocalPart() == null) return null; Definition[] definitions = getDefinitions(faultQName.getNamespaceURI()); for (int i = 0; i < definitions.length; i++) { Definition definition = definitions[i]; for (Iterator iter1 = definition.getEPortTypes().iterator(); iter1.hasNext();) { PortType portType = (PortType) iter1.next(); for (Iterator iter2 = portType.getOperations().iterator(); iter2.hasNext();) { Operation operation = (Operation) iter2.next(); Fault fault = (Fault) operation.getFault(faultQName.getLocalPart()); if (fault != null) { return fault.getEMessage(); } } } } // it does not exist in a WSDL files, check // if it is declared in a throw activity return getMessageFromThrow(faultQName); } protected Definition[] getDefinitions(String namespace) { List<Definition> result = new ArrayList<Definition>(); List<Import> imports = getProcess().getImports(); if (imports != null) { for (Import _import: imports) { if (WSDLConstants.WSDL_NAMESPACE_URI.equals(_import.getImportType())) { if (namespace.equals(_import.getNamespace())) { result.add(WSDLImportHelper.getDefinition(_import)); } } } } return result.toArray(new Definition[result.size()]); } /** * Given the fault qname, looks for the message type defined by * a throw activity visible to this context. */ protected Message getMessageFromThrow(QName faultQName) { Object container = getInput().eContainer().eContainer(); if (!(container instanceof Scope)) return null; // it might be an invoke so return null Scope scope = (Scope) container; for (Iterator<EObject> iter = scope.eAllContents(); iter.hasNext();) { Object element = iter.next(); if (element instanceof Throw) { Throw t = (Throw) element; if (faultQName.equals(t.getFaultName()) && (t.getFaultVariable() != null)) { return (t.getFaultVariable()).getMessageType(); } } } return null; } protected boolean isEmptyMessageType(String newName) { return Messages.FaultCatchNameSection_None_0.equals(newName) && builtinRadio.getSelection(); } protected List<String> getBuiltinFaultNames() { List<String> faultNames = new ArrayList<String>(); faultNames.add(Messages.FaultCatchNameSection_None_0); faultNames.addAll(Arrays.asList(BPELConstants.standardFaults)); return faultNames; } protected boolean isBuiltinFault(String faultNamespace) { boolean isBuiltin = BPELConstants.NAMESPACE.equals(faultNamespace); if (faultNamespace == null) { if (ModelHelper.getFaultName(getInput()) == null) isBuiltin = true; } return isBuiltin; } }