/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ui.properties; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.ui.celleditor.ExtendedComboBoxCellEditor; import org.eclipse.emf.common.ui.celleditor.ExtendedDialogCellEditor; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.ui.EMFEditUIPlugin; import org.eclipse.emf.edit.ui.provider.PropertyDescriptor.EDataTypeCellEditor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.dialogs.SelectionDialog; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.xsd.XSDComponent; import org.eclipse.xsd.XSDFeature; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.eclipse.xsd.XSDTypeDefinition; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.metamodels.core.extension.XClass; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.common.viewsupport.StatusInfo; import org.teiid.designer.ui.common.widget.accumulator.AccumulatorDialog; import org.teiid.designer.ui.common.widget.accumulator.IAccumulatorSource; import org.teiid.designer.ui.viewsupport.DatatypeSelectionDialog; import org.teiid.designer.ui.viewsupport.IFilter; import org.teiid.designer.ui.viewsupport.MetamodelTreeViewer; import org.teiid.designer.ui.viewsupport.ModelObjectListDialog; import org.teiid.designer.ui.viewsupport.ModelObjectPathLabelProvider; /** * PropertyEditorFactory is a static class for generating CellEditors for a given model object and IPropertyDescriptor. * * @since 8.0 */ public abstract class PropertyEditorFactory implements UiConstants.ExtensionPoints.PropertyEditorFactoryExtension { private static final int COMBO_BOX_CHOICE_LIMIT = 10; static final ILabelProvider pathLabelProvider = new ModelObjectPathLabelProvider(); private static final ArrayList customPropertyFactories = new ArrayList(); /** * Load all the contributions to the PropertyEditorFactory extension point. */ static { // get the PropertyEditorFactory extension point from the plugin class IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(UiConstants.PLUGIN_ID, ID); // get the all extensions to the ModelObjectActionContributor extension point IExtension[] extensions = extensionPoint.getExtensions(); if (extensions.length > 0) { // for each extension get their contributor for (int i = 0; i < extensions.length; i++) { IConfigurationElement[] elements = extensions[i].getConfigurationElements(); Object extension = null; for (int j = 0; j < elements.length; j++) { try { extension = elements[j].createExecutableExtension(CLASSNAME); if (extension instanceof IPropertyEditorFactory) { customPropertyFactories.add(extension); } else { UiConstants.Util.log(IStatus.ERROR, UiConstants.Util.getString("PropertyEditorFactory.wrongContributorClass", //$NON-NLS-1$ new Object[] {extension.getClass().getName()})); } } catch (Exception theException) { UiConstants.Util.log(IStatus.ERROR, theException, UiConstants.Util.getString("PropertyEditorFactory.contributorProblem", //$NON-NLS-1$ new Object[] {elements[j].getAttribute(CLASSNAME)})); } } } } } public static CellEditor createPropertyEditor( final Composite composite, final IItemPropertyDescriptor itemPropertyDescriptor, final IPropertyDescriptor propertyDescriptor, final Object object ) { return createPropertyEditor(composite, itemPropertyDescriptor, propertyDescriptor, object, false); } public static CellEditor createPropertyEditor( final Composite composite, final IItemPropertyDescriptor itemPropertyDescriptor, final IPropertyDescriptor propertyDescriptor, final Object object, final boolean lazyLoadChoices ) { if (!itemPropertyDescriptor.canSetProperty(object)) { return null; } boolean isTableEditor = composite instanceof Table; CellEditor result = null; Object genericFeature = itemPropertyDescriptor.getFeature(object); if (genericFeature instanceof EReference[]) { result = createComboEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } else if (genericFeature instanceof EStructuralFeature) { final EStructuralFeature feature = (EStructuralFeature)genericFeature; // see if there is a custom editor factory to handle this feature if (!customPropertyFactories.isEmpty()) { for (Iterator iter = customPropertyFactories.iterator(); iter.hasNext();) { IPropertyEditorFactory factory = (IPropertyEditorFactory)iter.next(); try { if (factory.supportsStructuralFeature(feature)) { return factory.createPropertyEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } } catch (Exception e) { UiConstants.Util.log(IStatus.ERROR, UiConstants.Util.getString("PropertyEditorFactory.errorInFactory", //$NON-NLS-1$ new Object[] {factory.getClass().getName()})); } } } final EClassifier eType = feature.getEType(); final String eTypeInstanceClassName = eType.getInstanceClassName(); EObject target = null; if (propertyDescriptor instanceof ModelObjectPropertyDescriptor) { target = (EObject)((ModelObjectPropertyDescriptor)propertyDescriptor).getObject(); } if (ModelerCore.getModelEditor().isDatatypeFeature(target, feature) || (object instanceof XSDSimpleTypeDefinition && eTypeInstanceClassName.equals(EObject.class.getName()))) { result = createDatatypeEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } else if (object instanceof XClass && eTypeInstanceClassName.equals(EClass.class.getName())) { // The reference's type is a metaclass in a metamodel result = createMetaclassEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } else { // check for EEnum first, since several XSD enumerations are coded non-standard if (eType instanceof EEnum) { if (feature.isMany() && object instanceof EObject) { // get the choice of values and see if they are EEnumLiteral instances Iterator iter = itemPropertyDescriptor.getChoiceOfValues(object).iterator(); boolean containsLiterals = false; while (iter.hasNext()) { if (iter.next() instanceof EEnumLiteral) { containsLiterals = true; break; } } if (containsLiterals) { // this is standard; use the accumulator if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createAccumulatorEnumEditor(composite, propertyDescriptor, feature, itemPropertyDescriptor, object); } } else { // this is a non-standard; use the combo box editor result = createComboEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } } else { result = createComboEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } } else if (eType instanceof EDataType) { EDataType eDataType = (EDataType)eType; if (eDataType.isSerializable()) { if (feature.isMany() && object instanceof EObject) { if ((feature instanceof EAttribute)) { Collection choices = itemPropertyDescriptor.getChoiceOfValues(object); if (choices == null || choices.isEmpty()) { // Defect 15449 - we have no editor for multiple string values, so use EMFs. result = ((ModelObjectPropertyDescriptor)propertyDescriptor).createDelegatePropertyEditor(composite); } else { // Defect 15449 - This has only been tested for a case where there were no allowable values. // Randall says we have // no properties that will travel down this block of code with getChoiceOfValues( ) returning // values. // Should that ever occur (say, in EMF 2.0), this block of code will need to be re-tested. if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createAccumulatorEnumEditor(composite, propertyDescriptor, feature, itemPropertyDescriptor, object); } } } else { result = createAccumulatorEnumEditor(composite, propertyDescriptor, feature, itemPropertyDescriptor, object); } } else if (eDataType == EcorePackage.eINSTANCE.getEBoolean() || eDataType == EcorePackage.eINSTANCE.getEBooleanObject()) { result = createBooleanEditor(composite, propertyDescriptor); } else { final Collection choiceOfValues = itemPropertyDescriptor.getChoiceOfValues(object); // property is single-valued. if (choiceOfValues != null) { if (choiceOfValues.size() < COMBO_BOX_CHOICE_LIMIT) { if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createComboEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } } else { if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createListEditor(composite, propertyDescriptor, feature, itemPropertyDescriptor, object, choiceOfValues); } } } else { result = new EDataTypeCellEditor(eDataType, composite); } } } } else { if (object instanceof EObject) { if (feature.isMany()) { // property is multi-valued. boolean valid = true; if (valid) { // create a cell editor that launches the accumulator if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createAccumulatorEditor(composite, propertyDescriptor, feature, itemPropertyDescriptor, object); } } } else { boolean useComboBox = false; Collection choiceOfValues = new ArrayList(); if (!lazyLoadChoices) { Collection allChoiceOfValues = itemPropertyDescriptor.getChoiceOfValues(object); // Note that some cases return choices that include the target object. Check choices and remove an item if it IS the target for( Object nextChoice : allChoiceOfValues) { if( nextChoice != object ) { choiceOfValues.add(nextChoice); } } // property is single-valued. if (choiceOfValues.size() < COMBO_BOX_CHOICE_LIMIT) { useComboBox = true; } } // property is single-valued. if (useComboBox) { if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createComboEditor(composite, (ArrayList)choiceOfValues, propertyDescriptor, object); } } else { if( isTableEditor ) { result = createUnsupportedCellEditor(composite, propertyDescriptor, feature, object); } else { result = createListEditor(composite, propertyDescriptor, feature, itemPropertyDescriptor, object, choiceOfValues); } } } } if (result == null) { result = createComboEditor(composite, itemPropertyDescriptor, propertyDescriptor, object); } } } } return result; } // ====================================== // Cell Editor factory methods private static CellEditor createComboEditor( final Composite composite, final IItemPropertyDescriptor itemPropertyDescriptor, final IPropertyDescriptor propertyDescriptor, final Object object ) { return new ExtendedComboBoxCellEditor(composite, new ArrayList(itemPropertyDescriptor.getChoiceOfValues(object)), propertyDescriptor.getLabelProvider(), true); } // ====================================== // Cell Editor factory methods private static CellEditor createComboEditor( final Composite composite, final ArrayList items, final IPropertyDescriptor propertyDescriptor, final Object object ) { return new ExtendedComboBoxCellEditor(composite, items, propertyDescriptor.getLabelProvider(), true); } private static CellEditor createBooleanEditor( final Composite composite, final IPropertyDescriptor propertyDescriptor ) { return new ExtendedComboBoxCellEditor(composite, Arrays.asList(new Object[] {new Boolean(false), new Boolean(true)}), propertyDescriptor.getLabelProvider(), true); } private static CellEditor createDatatypeEditor( final Composite composite, final IItemPropertyDescriptor itemPropertyDescriptor, final IPropertyDescriptor propertyDescriptor, final Object object ) { final Object feature = itemPropertyDescriptor.getFeature(object); if (feature instanceof EStructuralFeature) { return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox( Control cellEditorWindow ) { DatatypeSelectionDialog dialog = new DatatypeSelectionDialog(composite.getShell(), (EObject)object, (EStructuralFeature)feature); Object originalValue = getValue(); Object[] selection = new Object[] {originalValue}; selection[0] = getValue(); dialog.setInitialSelections(selection); int status = dialog.open(); if (status == Window.OK) { Object[] result = dialog.getResult(); if (result.length == 0) { // null out the value return null; } // return the selected value return result[0]; } // return the original object return originalValue; } }; } return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox( Control cellEditorWindow ) { DatatypeSelectionDialog dialog = new DatatypeSelectionDialog(composite.getShell(), (EObject)object); Object originalValue = getValue(); Object[] selection = new Object[] {originalValue}; selection[0] = getValue(); dialog.setInitialSelections(selection); int status = dialog.open(); if (status == Window.OK) { Object[] result = dialog.getResult(); if (result.length == 0) { // null out the value return null; } // return the selected value return result[0]; } // return the original object return originalValue; } }; } private static CellEditor createMetaclassEditor( final Composite composite, final IItemPropertyDescriptor itemPropertyDescriptor, final IPropertyDescriptor propertyDescriptor, final Object object ) { return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox( Control cellEditorWindow ) { SelectionDialog dialog = MetamodelTreeViewer.createSelectionDialog(composite.getShell(), true); Object originalValue = getValue(); Object[] selection = new Object[] {originalValue}; selection[0] = getValue(); dialog.setInitialSelections(selection); int status = dialog.open(); if (status == Window.OK) { Object[] result = dialog.getResult(); if (result.length == 0) { // null out the value return null; } // return the selected value return result[0]; } // return the original object return originalValue; } }; } private static CellEditor createAccumulatorEditor( final Composite composite, final IPropertyDescriptor propertyDescriptor, final EStructuralFeature feature, final IItemPropertyDescriptor itemPropertyDescriptor, final Object object ) { return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox( Control cellEditorWindow ) { EObject eObject = (EObject)object; List initialSelectionList = (List)eObject.eGet(feature); List initialSelectionListLocal = copyList(initialSelectionList); List initialAvailableList = new ArrayList(itemPropertyDescriptor.getChoiceOfValues(object)); removeSelectedItemsFromAvailable(initialAvailableList, initialSelectionListLocal); IAccumulatorSource accumulatorSource = new ModelObjectAccumulatorSourceImpl(pathLabelProvider, initialAvailableList); String availableLabel = EMFEditUIPlugin.INSTANCE.getString("_UI_Choices_label"); //$NON-NLS-1$ String selectedLabel = EMFEditUIPlugin.INSTANCE.getString("_UI_Feature_label"); //$NON-NLS-1$ AccumulatorDialog accumulatorDialog = new AccumulatorDialog(cellEditorWindow.getShell(), accumulatorSource, propertyDescriptor.getDisplayName(), initialSelectionListLocal, pathLabelProvider, availableLabel, selectedLabel); int status = accumulatorDialog.open(); List result = initialSelectionList; if (status == Window.OK) { result = new BasicEList(accumulatorDialog.getSelectedItems()); } return result; } }; } private static CellEditor createAccumulatorEnumEditor( final Composite composite, final IPropertyDescriptor propertyDescriptor, final EStructuralFeature feature, final IItemPropertyDescriptor itemPropertyDescriptor, final Object object ) { return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox( Control cellEditorWindow ) { EObject eObject = (EObject)object; List initialSelectionList = (List)eObject.eGet(feature); List initialSelectionListLocal = copyList(initialSelectionList); Collection choices = itemPropertyDescriptor.getChoiceOfValues(object); List choiceList = new ArrayList(choices); List initialAvailableList = new ArrayList(choiceList); removeSelectedItemsFromAvailable(initialAvailableList, initialSelectionListLocal); IAccumulatorSource accumulatorSource = new ModelObjectAccumulatorSourceImpl( propertyDescriptor.getLabelProvider(), initialAvailableList); String availableLabel = EMFEditUIPlugin.INSTANCE.getString("_UI_Choices_label"); //$NON-NLS-1$ String selectedLabel = EMFEditUIPlugin.INSTANCE.getString("_UI_Feature_label"); //$NON-NLS-1$ AccumulatorDialog accumulatorDialog = new AccumulatorDialog(cellEditorWindow.getShell(), accumulatorSource, propertyDescriptor.getDisplayName(), initialSelectionListLocal, propertyDescriptor.getLabelProvider(), availableLabel, selectedLabel); int status = accumulatorDialog.open(); if (status != Window.OK) { return null; } // EMF expects enumerations to be provided as Integer indexes to their values, so convert Collection selectedItems = accumulatorDialog.getSelectedItems(); List result = new ArrayList(selectedItems.size()); for (Iterator iter = selectedItems.iterator(); iter.hasNext();) { int index = choiceList.indexOf(iter.next()); if (index >= 0) { result.add(new Integer(index)); } } return new BasicEList(result); } }; } private static CellEditor createListEditor( final Composite composite, final IPropertyDescriptor propertyDescriptor, final EStructuralFeature feature, final IItemPropertyDescriptor itemPropertyDescriptor, final Object object, final Collection choiceOfValues ) { return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox( Control cellEditorWindow ) { // defect 18611 - make MOLD open faster. ModelObjectListDialog dialog = new ModelObjectListDialog(composite.getShell(), propertyDescriptor.getLabelProvider(), true, false); dialog.setContentFilter(new IFilter() { @Override public boolean passes( final Object object ) { if (object instanceof XSDComponent) { if (object instanceof XSDTypeDefinition || object instanceof XSDFeature) { return true; } return false; } return true; } }); Collection inputValues = (choiceOfValues != null ? choiceOfValues : itemPropertyDescriptor.getChoiceOfValues(object)); // Filter out the null value - not allowable in a list view if (inputValues.contains(null)) { // need to create a new list as the original maybe unmodifiable and calling remove will throw exception inputValues = new ArrayList(inputValues); inputValues.remove(null); } dialog.setInput(inputValues); Object originalValue = getValue(); Object[] selection = new Object[] {originalValue}; dialog.setInitialSelections(selection); dialog.setFeatureName(propertyDescriptor.getDisplayName()); int status = dialog.open(); if (status == Window.OK) { Object[] result = dialog.getResult(); // If an empty array is returned from the dialog that means the user has requested to // null the value out. The superclass editor ignores null values so added the code here. if (result.length == 0) { // null out the value if valid value if (isCorrect(null)) { markDirty(); doSetValue(null); fireApplyEditorValue(); } return null; } // return the selected value return result[0]; } // return the original object return originalValue; } }; } private static CellEditor createUnsupportedCellEditor(final Composite composite, final IPropertyDescriptor propertyDescriptor, final EStructuralFeature feature, final Object object) { return new ExtendedDialogCellEditor(composite, propertyDescriptor.getLabelProvider()) { @Override protected Object openDialogBox(Control cellEditorWindow) { if( object instanceof EObject ) { String name = ModelerCore.getModelEditor().getName((EObject)object); MessageDialog.openWarning(composite.getShell(), UiConstants.Util.getString("PropertyEditorFactory.unsupportedEditingTitle"), UiConstants.Util.getString("PropertyEditorFactory.unsupportedEditingMessage", feature.getName(), name)); } // return the original object return getValue(); } }; } static List copyList( List inList ) { List outList = new ArrayList(inList.size()); Iterator it = inList.iterator(); while (it.hasNext()) { outList.add(it.next()); } return outList; } static void removeSelectedItemsFromAvailable( List available, List selected ) { Iterator it = selected.iterator(); while (it.hasNext()) { Object item = it.next(); if (available.contains(item)) { available.remove(item); } } } /** * Construct an instance of PropertyEditorManager. */ private PropertyEditorFactory() { } } class ModelObjectAccumulatorSourceImpl implements IAccumulatorSource { // We will be using a Table to show the data. However, we will NOT be using a TableViewer with // the table. The reason is this: Whenever an item is removed from this table (moved to the // "selected" side in the accumulator), then later reinserted into this side, we would like to be // able to reinsert it into its original position. That is not feasible with a TableViewer. // With a TableViewer one must either supply a sorter, which is not what we want, or always // insert the items at the end of the table, which is likewise not what we want. // // But, seeing as SWT provides no means to correlate an Object itself with a row in the // Table, we will keep an up-to-date list of Objects represented in the table (currentValues). // Table only provides means to get Strings and Images pertaining to rows in a table, but not // Objects that they are supposed to represent, which I find very strange. BWP. private static final IStatus OK_STATUS = new StatusInfo(UiConstants.PLUGIN_ID); private ILabelProvider labelProvider; private List initialValues; private List currentValues = new ArrayList(); private Table table; public ModelObjectAccumulatorSourceImpl( ILabelProvider labelProvider, List initialValues ) { super(); this.labelProvider = labelProvider; this.initialValues = initialValues; } @Override public void accumulatedValuesRemoved( Collection values ) { // Any items that were originally in our table we will reinsert into the same relative // location. Any ones that did not start here we will insert at the end. Iterator it = values.iterator(); while (it.hasNext()) { Object obj = it.next(); int index = indexForValueInserting(obj); TableItem tableItem = new TableItem(table, 0, index); Image image = labelProvider.getImage(obj); String text = labelProvider.getText(obj); tableItem.setImage(image); tableItem.setText(text); currentValues.add(index, obj); } } @Override public void accumulatedValuesAdded( Collection values ) { Iterator it = values.iterator(); while (it.hasNext()) { Object value = it.next(); int index = indexForValueRemoving(value); table.remove(index); currentValues.remove(index); } } @Override public Collection getAvailableValues() { Collection itemsColl = new ArrayList(currentValues.size()); Iterator it = currentValues.iterator(); while (it.hasNext()) { itemsColl.add(it.next()); } return itemsColl; } @Override public int getAvailableValuesCount() { int count = table.getItemCount(); return count; } @Override public Collection getSelectedAvailableValues() { int[] itemIndices = table.getSelectionIndices(); Collection itemsColl = new ArrayList(itemIndices.length); for (int i = 0; i < itemIndices.length; i++) { Object obj = currentValues.get(itemIndices[i]); itemsColl.add(obj); } return itemsColl; } @Override public int getSelectedAvailableValuesCount() { int count = table.getSelectionCount(); return count; } @Override public Control createControl( Composite parent ) { // Create the table table = new Table(parent, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); GridData tableGridData = new GridData(); tableGridData.widthHint = 200; tableGridData.verticalAlignment = GridData.FILL; tableGridData.horizontalAlignment = GridData.FILL; tableGridData.grabExcessHorizontalSpace = true; tableGridData.grabExcessVerticalSpace = true; table.setLayoutData(tableGridData); // Populate the table int loc = 0; Iterator it = this.initialValues.iterator(); while (it.hasNext()) { Object obj = it.next(); TableItem tableItem = new TableItem(table, 0, loc); Image image = labelProvider.getImage(obj); String text = labelProvider.getText(obj); tableItem.setImage(image); tableItem.setText(text); currentValues.add(obj); loc++; } return table; } @Override public void addSelectionListener( SelectionListener listener ) { table.addSelectionListener(listener); } private int indexForValueRemoving( Object value ) { int index = currentValues.indexOf(value); return index; } private int indexForValueInserting( Object value ) { int index = -1; int originalIndex = initialValues.indexOf(value); if (originalIndex < 0) { index = currentValues.size(); } else { // We will attempt to find in the current list the object that was just before this one // in the original list. If found, we know that this one should be inserted right after // it. If not found, we will look for the object that was right before that object, etc. // If no object that was before this one in the original list was found in the current // list, then we will return 0, to insert the object at the beginning of the table. boolean found = false; int loc = originalIndex - 1; while ((!found) && (loc >= 0)) { Object objectLookingFor = initialValues.get(loc); int curIndexOfObject = currentValues.indexOf(objectLookingFor); if (curIndexOfObject >= 0) { found = true; index = curIndexOfObject + 1; } else { loc--; } } if (!found) { index = 0; } } return index; } /** * @see org.teiid.designer.ui.common.widget.accumulator.IAccumulatorSource#supportsAddAll() */ @Override public boolean supportsAddAll() { return true; } /** * @see org.teiid.designer.ui.common.widget.accumulator.IAccumulatorSource#getSelectionStatus() */ @Override public IStatus getSelectionStatus() { return OK_STATUS; } } // end ModelObjectAccumulatorSourceImpl