| /******************************************************************************* |
| * Copyright (c) 2006, 2012 Oracle 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: |
| * Oracle Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.bpel.ui.dialogs; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.bpel.model.util.BPELUtils; |
| import org.eclipse.bpel.ui.Messages; |
| import org.eclipse.bpel.ui.commands.AddImportCommand; |
| import org.eclipse.bpel.ui.details.providers.ModelTreeLabelProvider; |
| import org.eclipse.bpel.ui.details.tree.TreeNode; |
| import org.eclipse.bpel.ui.util.BPELUtil; |
| import org.eclipse.bpel.ui.util.ModelHelper; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.ScrollBar; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeItem; |
| import org.eclipse.xsd.XSDNamedComponent; |
| import org.eclipse.xsd.XSDSimpleTypeDefinition; |
| import org.eclipse.xsd.util.XSDConstants; |
| |
| /** |
| * @author Michal Chmielewski (michal.chmielewski@oracle.com) |
| * @date Jul 18, 2006 |
| * |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=330813 |
| * https://jira.jboss.org/browse/JBIDE-7107 |
| * Enhanced to support element selection from the "lower" tree viewer |
| */ |
| public class BrowseSelectorDialog extends ListAndViewDialog { |
| |
| protected static final int BID_ADD_IMPORT = IDialogConstants.CLIENT_ID + 1; |
| protected static final int BID_FROM_IMPORTS_ONLY = IDialogConstants.CLIENT_ID + 7; |
| protected static final int BID_FROM_PROJECT = IDialogConstants.CLIENT_ID + 8; |
| protected static final int BID_FROM_WORKSPACE = IDialogConstants.CLIENT_ID + 9; |
| protected static final int BID_FROM_XML_CATALOG = IDialogConstants.CLIENT_ID + 10; |
| protected static final int BID_FROM_REPOSITORY = IDialogConstants.CLIENT_ID + 11; |
| protected static final int BID_DUPLICATES = IDialogConstants.CLIENT_ID + 20; |
| |
| protected boolean showDuplicates = false; |
| protected EObject modelObject; |
| protected Text filterText; |
| |
| protected IStructuredContentProvider contentProvider = null; |
| protected IStructuredContentProvider resourceContentProvider = null; |
| protected ITreeContentProvider treeContentProvider = null; |
| |
| protected Group checkButtonGroup; |
| protected Tree fTree; |
| protected TreeViewer fTreeViewer; |
| |
| private Button fFromImportsRadio; |
| private Button fFromProjectRadio; |
| private Button fFromWorkspaceRadio; |
| |
| private Object[] fWorkspaceObjects; |
| private Object[] fProjectObjects; |
| |
| private Label filterLabel; |
| |
| /* View types dialog preference setting */ |
| static final String VIEW_FROM_KEY = "ViewFrom"; //$NON-NLS-1$ |
| |
| |
| /* Show duplicates key in dialog settings */ |
| static final String SHOW_DUPLICATES_KEY = "ShowDuplicates"; //$NON-NLS-1$ |
| |
| |
| /* by default, view types from imports only */ |
| protected int VIEW_FROM = BID_FROM_IMPORTS_ONLY; |
| |
| |
| /** The browse from label */ |
| String fBrowseFromLabel; |
| |
| |
| |
| /** |
| * @param parent |
| * @param elementRenderer |
| */ |
| public BrowseSelectorDialog(Shell parent, ILabelProvider elementRenderer) { |
| super(parent, elementRenderer); |
| |
| // Restore some dialog settings ... |
| IDialogSettings settings = getDialogSettings(); |
| |
| setMessage(Messages.BrowseSelectorDialog_0); |
| setUpperListLabel(Messages.BrowseSelectorDialog_1); |
| setBrowseFromLabel (Messages.BrowseSelectorDialog_2); |
| |
| try { |
| VIEW_FROM = settings.getInt(VIEW_FROM_KEY); |
| } catch (Exception ex) { |
| VIEW_FROM = BID_FROM_IMPORTS_ONLY; |
| } |
| |
| try { |
| showDuplicates = settings.getBoolean(SHOW_DUPLICATES_KEY); |
| } catch (Exception ex) { |
| showDuplicates = false; |
| } |
| } |
| |
| |
| /** |
| * @param string |
| */ |
| protected void setBrowseFromLabel(String label) { |
| fBrowseFromLabel = label; |
| } |
| |
| |
| |
| @Override |
| protected void saveSettings() { |
| |
| IDialogSettings settings = getDialogSettings(); |
| |
| settings.put ( VIEW_FROM_KEY, VIEW_FROM ); |
| settings.put ( SHOW_DUPLICATES_KEY, showDuplicates ); |
| } |
| |
| |
| @Override |
| protected void buttonPressed(int buttonId) { |
| if (buttonId == BID_ADD_IMPORT) { |
| handleAddImport(); |
| return ; |
| } |
| super.buttonPressed(buttonId); |
| } |
| |
| /** |
| * Check to make sure that the mappings for the XML namespace exist |
| */ |
| @Override |
| protected void okPressed() { |
| computeResult(); |
| Object obj[] = getResult(); |
| |
| if (obj != null && obj.length > 0) { |
| if (ensureXSDTypeNamespaceMappings ( obj[0] ) == false) { |
| return ; |
| } |
| |
| handleAddImport ( obj[0] ); |
| |
| // only if we have a mapping do we dismiss the dialog |
| super.okPressed(); |
| } |
| |
| } |
| |
| /** |
| * @see ListAndViewDialog#computeResult() |
| * https://jira.jboss.org/browse/JBIDE-7107 |
| * Added support for returning two results |
| */ |
| @Override |
| protected void computeResult() { |
| |
| List result = new ArrayList(); |
| Object sel1[] = getSelectedElements(); |
| TreeItem sel2[] = fTree.getSelection(); |
| for (int i=0; i<sel1.length; ++i) |
| result.add(sel1[i]); |
| for (int i=0; i<sel2.length; ++i) { |
| Object data = sel2[i].getData(); |
| if (data instanceof TreeNode) |
| { |
| // list of the selected node's model object ancestry in reverse order |
| ArrayList<Object> elements = new ArrayList<Object>(); |
| TreeNode node = (TreeNode)data; |
| ITreeContentProvider prov = (ITreeContentProvider)fTreeViewer.getContentProvider(); |
| do { |
| elements.add(node.getModelObject()); |
| node = (TreeNode)prov.getParent(node); |
| } |
| while (node!=null && node.getModelObject()!=sel1[0]); |
| |
| for (int e=elements.size(); e>0; --e) { |
| result.add(elements.get(e-1)); |
| } |
| } |
| } |
| setResult(result); |
| } |
| |
| /** |
| * Ensure that the prefix mapping exists for the given namespace |
| * in the BPEL source. |
| * |
| * @param the schema component for which to create a BPEL prefix mappings. |
| */ |
| private boolean ensureXSDTypeNamespaceMappings(Object obj) { |
| |
| String targetNamespace = null; |
| |
| if (obj instanceof XSDNamedComponent ) { |
| XSDNamedComponent namedComponent = (XSDNamedComponent) obj; |
| targetNamespace = namedComponent.getTargetNamespace(); |
| } |
| |
| if (targetNamespace == null) { |
| return true; |
| } |
| |
| // Now check if the target namespace has a prefix mappings. |
| String prefix = BPELUtils.getNamespacePrefix (modelObject, targetNamespace); |
| if (prefix != null) { |
| return true; |
| } |
| |
| // We have to map the namespace to a prefix. |
| NamespaceMappingDialog dialog = new NamespaceMappingDialog(getShell(),modelObject); |
| dialog.setNamespace( targetNamespace ); |
| |
| if (dialog.open() == Window.CANCEL) { |
| return false; |
| } |
| |
| // define the prefix |
| BPELUtils.setPrefix( BPELUtils.getProcess(modelObject), targetNamespace, dialog.getPrefix()); |
| |
| return true; |
| } |
| |
| /** |
| * Handle the check button and radio button callbacks. |
| * |
| * @param id |
| * @param checked |
| * @param refresh unless this is set, no refresh is done. |
| */ |
| |
| protected void buttonPressed(int id, boolean checked, boolean bRefresh) { |
| |
| switch (id) { |
| |
| case BID_DUPLICATES : |
| showDuplicates = checked; |
| break; |
| |
| |
| case BID_FROM_WORKSPACE : |
| case BID_FROM_XML_CATALOG : |
| case BID_FROM_PROJECT : |
| case BID_FROM_REPOSITORY : |
| case BID_FROM_IMPORTS_ONLY : |
| if (!checked) { |
| return ; |
| } |
| if (checked) { |
| VIEW_FROM = id; |
| } |
| break; |
| |
| default : |
| break; |
| } |
| |
| |
| if (bRefresh) { |
| refresh(); |
| } |
| } |
| |
| /** |
| * Add an import using an explicit import dialog selection. |
| * |
| * We safeguard against adding duplicate types to the BPEL model here as well. |
| * |
| */ |
| protected void handleAddImport() { |
| |
| SchemaImportDialog dialog = new SchemaImportDialog(getShell(),modelObject); |
| if (dialog.open() == Window.CANCEL) { |
| return ; |
| } |
| Object obj = dialog.getFirstResult(); |
| if (obj == null) { |
| return ; |
| } |
| if (handleAddImport ( obj )) { |
| showImportedTypes(); |
| refresh(); |
| } |
| |
| } |
| |
| |
| protected boolean handleAddImport(Object obj) { |
| |
| // Do not import schema for schemas |
| if (obj instanceof XSDSimpleTypeDefinition) { |
| |
| String targetNamespace = ((XSDSimpleTypeDefinition) obj).getTargetNamespace(); |
| if (targetNamespace != null) { |
| if (((XSDSimpleTypeDefinition) obj).getTargetNamespace().equals( |
| XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001)) { |
| return false; |
| } |
| } |
| } |
| |
| AddImportCommand cmd = new AddImportCommand(BPELUtils |
| .getProcess(modelObject), obj); |
| |
| if (cmd.canDoExecute() && cmd.wouldCreateDuplicateImport() == false) { |
| ModelHelper.getBPELEditor(modelObject).getCommandStack().execute( |
| cmd); |
| // Now refresh the view to imported types. |
| return true; |
| } |
| return false; |
| } |
| |
| |
| protected Button createRadioButton(Composite parent, String label, int id, boolean checked) { |
| |
| Button button = new Button(parent,SWT.RADIO); |
| button.setText(label); |
| button.setFont(JFaceResources.getDialogFont()); |
| button.setData( Integer.valueOf( id )); |
| button.setSelection( checked ); |
| |
| button.addSelectionListener (new SelectionAdapter() { |
| @Override |
| public void widgetSelected (SelectionEvent event) { |
| Button b = (Button) event.widget; |
| int val = ((Integer) b.getData()).intValue(); |
| |
| buttonPressed(val, b.getSelection(), true ); |
| } |
| }); |
| |
| return button; |
| |
| } |
| |
| protected Button createCheckButton(Composite parent, String label, int id, boolean checked) { |
| |
| Button button = new Button(parent,SWT.CHECK); |
| button.setText(label); |
| button.setFont(JFaceResources.getDialogFont()); |
| button.setData( Integer.valueOf( id )); |
| button.setSelection( checked ); |
| |
| button.addSelectionListener (new SelectionAdapter() { |
| @Override |
| public void widgetSelected (SelectionEvent event) { |
| Button b = (Button) event.widget; |
| int val = ((Integer) b.getData()).intValue(); |
| |
| buttonPressed(val, b.getSelection(), true); |
| } |
| }); |
| |
| return button; |
| |
| } |
| |
| @Override |
| protected Text createFilterText(Composite parent) { |
| filterText = super.createFilterText(parent); |
| |
| createBrowseFromGroup ( parent ); |
| createBrowseFilterGroup( parent ); |
| |
| return filterText; |
| } |
| |
| |
| @Override |
| protected Label createMessageArea(Composite composite) { |
| filterLabel = super.createMessageArea(composite); |
| return filterLabel; |
| } |
| |
| |
| |
| protected void createBrowseFromGroup(Composite parent) { |
| Group group = new Group(parent,SWT.SHADOW_ETCHED_IN); |
| group.setText( fBrowseFromLabel ); |
| |
| GridLayout layout = new GridLayout(); |
| layout.makeColumnsEqualWidth = true; |
| layout.numColumns = 3; |
| group.setLayout(layout); |
| GridData data = new GridData(); |
| data.grabExcessVerticalSpace = false; |
| data.grabExcessHorizontalSpace = true; |
| data.horizontalAlignment = GridData.FILL; |
| data.verticalAlignment = GridData.FILL; |
| group.setLayoutData(data); |
| |
| createBrowseFromGroupButtons ( group ); |
| |
| } |
| |
| |
| |
| protected void createBrowseFromGroupButtons ( Group group ) { |
| |
| fFromImportsRadio = createRadioButton(group,Messages.TypeSelectorDialog_10, BID_FROM_IMPORTS_ONLY, |
| VIEW_FROM == BID_FROM_IMPORTS_ONLY); |
| fFromProjectRadio = createRadioButton(group,Messages.TypeSelectorDialog_11, BID_FROM_PROJECT, |
| VIEW_FROM == BID_FROM_PROJECT ); |
| fFromWorkspaceRadio = createRadioButton(group,Messages.TypeSelectorDialog_12, BID_FROM_WORKSPACE, |
| VIEW_FROM == BID_FROM_WORKSPACE ); |
| |
| |
| // fFromCatalogRadio = createRadioButton(group,"From XML Catalog", BID_FROM_XML_CATALOG, |
| // VIEW_TYPES == BID_FROM_XML_CATALOG ); |
| // // TODO: Fix this or remove at some point |
| // fFromCatalogRadio.setVisible(false); |
| // |
| // fFromRepositoryRadio = createRadioButton(group,"From Repository", BID_FROM_REPOSITORY, |
| // VIEW_TYPES == BID_FROM_REPOSITORY ); |
| // // TODO: Fix this or remove at some point. |
| // fFromRepositoryRadio.setVisible(false); |
| |
| |
| } |
| |
| protected void createBrowseFilterGroup(Composite parent) { |
| // https://jira.jboss.org/browse/JBIDE-7107 |
| // need to support enabling/disabling of this button group |
| // see BrowseUtils#browseForMessageType() for example |
| checkButtonGroup = new Group(parent,SWT.SHADOW_ETCHED_IN); |
| checkButtonGroup.setText( Messages.BrowseSelectorDialog_4 ); |
| |
| GridLayout layout = new GridLayout(); |
| layout.makeColumnsEqualWidth = true; |
| layout.numColumns = 3; |
| checkButtonGroup.setLayout(layout); |
| GridData data = new GridData(); |
| data.grabExcessVerticalSpace = false; |
| data.grabExcessHorizontalSpace = true; |
| data.horizontalAlignment = GridData.FILL; |
| data.verticalAlignment = GridData.FILL; |
| checkButtonGroup.setLayoutData(data); |
| |
| createBrowseFilterGroupButtons ( checkButtonGroup ); |
| } |
| |
| |
| |
| protected void createBrowseFilterGroupButtons ( Group group ) { |
| createCheckButton(group,Messages.TypeSelectorDialog_19, BID_DUPLICATES, |
| showDuplicates); |
| |
| } |
| |
| |
| @Override |
| protected Object createLowerView(Composite parent) { |
| // Tree viewer for variable structure ... |
| fTree = new Tree(parent, SWT.BORDER ); |
| fTree.addSelectionListener(new SelectionAdapter() { |
| |
| @Override |
| public void widgetSelected(SelectionEvent arg0) { |
| // https://jira.jboss.org/browse/JBIDE-7107 |
| // update "OK" button enablement |
| updateOkState(); |
| } |
| |
| }); |
| |
| fTreeViewer = new TreeViewer(fTree); |
| fTreeViewer.setContentProvider( treeContentProvider ); |
| fTreeViewer.setLabelProvider(new ModelTreeLabelProvider()); |
| fTreeViewer.setInput ( null ); |
| fTreeViewer.setAutoExpandLevel( getAutoExpandLevel() ); |
| // end tree viewer for variable structure |
| GridData data = new GridData(); |
| data.grabExcessVerticalSpace = true; |
| data.grabExcessHorizontalSpace = true; |
| data.horizontalAlignment = GridData.FILL; |
| data.verticalAlignment = GridData.FILL; |
| data.minimumHeight = 200; |
| fTree.setLayoutData(data); |
| |
| return fTree; |
| } |
| |
| |
| protected int getAutoExpandLevel () { |
| return 3; |
| } |
| |
| |
| @Override |
| protected void updateLowerViewWidget(Object[] elements) { |
| |
| if (elements == null || elements.length < 1) { |
| fTreeViewer.setInput(null); |
| return; |
| } |
| |
| fTreeViewer.setInput ( elements[0] ); |
| |
| ScrollBar bar = fTree.getVerticalBar(); |
| if (bar != null) { |
| bar.setSelection(0); |
| } |
| } |
| |
| protected Object[] merge(Object[] a1, Object a2[]) { |
| Object[] result = new Object[ a1.length + a2.length]; |
| System.arraycopy(a1, 0, result, 0, a1.length); |
| System.arraycopy(a2, 0, result, a1.length, a2.length); |
| return result; |
| } |
| |
| protected void refresh() { |
| |
| if (VIEW_FROM == BID_FROM_IMPORTS_ONLY) { |
| refreshFromImports (); |
| } else if (VIEW_FROM == BID_FROM_PROJECT) { |
| refreshFromProject(); |
| } else if (VIEW_FROM == BID_FROM_WORKSPACE) { |
| refreshFromWorkspace(); |
| } else if (VIEW_FROM == BID_FROM_XML_CATALOG) { |
| refreshFromXMLCatalog (); |
| } else if (VIEW_FROM == BID_FROM_REPOSITORY ) { |
| refreshFromRepository (); |
| } else { |
| return ; |
| } |
| |
| if (fFilteredList != null) { |
| if (fFilteredList.isEmpty()) { |
| handleEmptyList(); |
| } else { |
| handleNonEmptyList(); |
| } |
| } |
| // https://jira.jboss.org/browse/JBIDE-7107 |
| updateOkState(); |
| } |
| |
| /** |
| * Refresh the available types from the BPEL imports list. This is the |
| * list of types/elements visible in the process so far (the working set so to speak). |
| */ |
| protected void refreshFromImports() { |
| |
| List<?> elements = collectItemsFromImports(); |
| |
| if (fFilteredList != null) { |
| fFilteredList.setAllowDuplicates(showDuplicates); |
| fFilteredList.setElements( contentProvider.getElements(elements) ); |
| fFilteredList.setEnabled(true); |
| } |
| } |
| |
| |
| protected List<?> collectItemsFromImports () { |
| return Collections.emptyList(); |
| } |
| |
| /** |
| * Show the types which are available in the current workspace. |
| * This includes all the open projects ... |
| */ |
| protected void refreshFromWorkspace() { |
| |
| if (fTreeViewer != null) { |
| fTreeViewer.setInput(null); |
| } |
| |
| if (fWorkspaceObjects == null ) { |
| fWorkspaceObjects = resourceContentProvider.getElements( ResourcesPlugin.getWorkspace().getRoot() ); |
| } |
| |
| if (fFilteredList != null) { |
| |
| fFilteredList.setEnabled(true); |
| fFilteredList.setAllowDuplicates(showDuplicates); |
| fFilteredList.setElements(contentProvider.getElements( fWorkspaceObjects )); |
| } |
| } |
| |
| /** |
| * Show the types which are available in the current project only. |
| * |
| */ |
| protected void refreshFromProject() { |
| |
| if (fTreeViewer != null) { |
| fTreeViewer.setInput(null); |
| } |
| |
| if (fProjectObjects == null ) { |
| Resource resource = modelObject.eResource(); |
| IFile file = BPELUtil.getFileFromURI(resource.getURI()); |
| fProjectObjects = resourceContentProvider.getElements( file.getProject() ); |
| } |
| |
| if (fFilteredList != null) { |
| |
| fFilteredList.setEnabled(true); |
| fFilteredList.setAllowDuplicates(showDuplicates); |
| fFilteredList.setElements( contentProvider.getElements( fProjectObjects ) ); |
| |
| if (contentProvider.getElements( fProjectObjects ) != null && contentProvider.getElements( fProjectObjects ).length > 0) { |
| updateLowerViewWidget(fFilteredList.getSelection()); |
| } |
| } |
| } |
| |
| protected void refreshFromXMLCatalog() { |
| |
| // TODO: At some point I had the idea to gather types from |
| // XML catalog. But not sure if this is such a good idea anymore |
| |
| Object[] elements = new Object[]{}; |
| modelObject.eContainer(); |
| |
| if (fFilteredList != null) { |
| |
| fFilteredList.setAllowDuplicates(showDuplicates); |
| fFilteredList.setElements(elements); |
| fFilteredList.setEnabled(true); |
| |
| } |
| |
| if (fTreeViewer != null) { |
| fTreeViewer.setInput(null); |
| } |
| } |
| |
| protected void refreshFromRepository() { |
| |
| // TODO: Some repository of some kind ? |
| |
| Object[] elements = new Object[]{}; |
| modelObject.eContainer(); |
| |
| if (fFilteredList != null) { |
| |
| fFilteredList.setAllowDuplicates(showDuplicates); |
| fFilteredList.setElements(elements); |
| fFilteredList.setEnabled(true); |
| |
| } |
| |
| if (fTreeViewer != null) { |
| fTreeViewer.setInput(null); |
| } |
| } |
| |
| protected void showImportedTypes() { |
| |
| fFromImportsRadio.setSelection(true); |
| fFromProjectRadio.setSelection(false); |
| fFromWorkspaceRadio.setSelection(false); |
| |
| // fFromRepositoryRadio.setSelection(false); |
| // fFromCatalogRadio.setSelection(false); |
| |
| fFromImportsRadio.forceFocus(); |
| buttonPressed(BID_FROM_IMPORTS_ONLY, true, false); |
| } |
| |
| @Override |
| protected void handleEmptyList() { |
| fTreeViewer.setInput ( null ); |
| |
| // Buzilla 290348 - added by Grid.Qian |
| // the tree view's input is null, but the selection maybe not 0 |
| // for example the input is a list and we select a element, then |
| // set the input = null, this time, the selection is not 0 |
| fFilteredList.setSelection(new int[0]); |
| super.handleEmptyList(); |
| } |
| |
| protected void handleNonEmptyList() { |
| |
| setEnabled( filterText, true); |
| setEnabled( filterLabel, true); |
| setEnabled( fFilteredList, true); |
| } |
| |
| /** |
| * @param |
| * @param b |
| */ |
| void setEnabled(Control control, boolean b) { |
| if (control != null) { |
| control.setEnabled(b); |
| } |
| } |
| |
| } |