/* * 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.search; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.dialogs.DialogPage; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.search.ui.ISearchPage; import org.eclipse.search.ui.ISearchPageContainer; import org.eclipse.search.ui.NewSearchUI; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Text; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.teiid.core.designer.util.I18nUtil; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.search.MetadataSearch; import org.teiid.designer.metamodels.xsd.util.RuntimeType; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.UiPlugin; import org.teiid.designer.ui.common.InternalUiConstants; import org.teiid.designer.ui.common.util.UiUtil; import org.teiid.designer.ui.common.util.WidgetFactory; import org.teiid.designer.ui.common.util.WidgetUtil; import org.teiid.designer.ui.viewsupport.DatatypeSelectionDialog; import org.teiid.designer.ui.viewsupport.MetamodelSelectionDialog; import org.teiid.designer.ui.viewsupport.MetamodelTreeViewer; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * The <code>MetadataSearchPage</code> is the UI to perform workspace Metadata searching. * * @since 8.0 */ public final class MetadataSearchPage extends DialogPage implements ISearchPage, UiConstants { // =========================================================================================================================== // Interfaces // =========================================================================================================================== /** * Constants used in the {@link IDialogSettings}. * * @since 6.0.0 */ interface DialogSettingsConstants { String ANY_OBJ_TYPE = "anyObjectType"; //$NON-NLS-1$ String METACLASS_TYPE = "metaclassType"; //$NON-NLS-1$ String METACLASS_MRU = "metaclassMru"; //$NON-NLS-1$ String LAST_USED_METACLASS = "lastUsedMetaclass"; //$NON-NLS-1$ String ANY_DATA_TYPE = "anyDataType"; //$NON-NLS-1$ String SIMPLE_DATA_TYPE = "simpleDataType"; //$NON-NLS-1$ String SELECTED_SIMPLE_TYPE = "selectedSimpleType"; //$NON-NLS-1$ String INCLUDE_SUBTYPES = "includeSubTypes"; //$NON-NLS-1$ String RUNTIME_TYPE = "runtimeType"; //$NON-NLS-1$ String SELECTED_RUNTIME_TYPE = "selectedRuntimeType"; //$NON-NLS-1$ String INCLUDE_PROPERTY = "includeProperty"; //$NON-NLS-1$ String SELECTED_PROPERTY = "selectedProperty"; //$NON-NLS-1$ String CONTAINS_TEXT = "containsText"; //$NON-NLS-1$ String NOT_CONTAIN_TEXT = "notContainText"; //$NON-NLS-1$ String EXACT_MATCH = "exactMatch"; //$NON-NLS-1$ String TEXT_PATTERN = "textPattern"; //$NON-NLS-1$ String LAST_USED_TEXT_PATTERN = "lastUsedTextPattern"; //$NON-NLS-1$ int MRU_LIMIT = 20; } // =========================================================================================================================== // Constants // =========================================================================================================================== /** Properties key prefix. */ private static final String PREFIX = I18nUtil.getPropertyPrefix(MetadataSearchPage.class); // =========================================================================================================================== // Fields // =========================================================================================================================== private ISearchPageContainer searchPageContainer; /** The currently selected metaclass. */ private EClass metaclass; /** MRU of metaclass URIs. */ private List metaclassMru; /** Label provider for metaclass. */ private ILabelProvider labelProvider; /** The currently selected runtime type. */ private String runtimeType; /** Search business object that executes search. */ private MetadataSearch searchMgr; /** Persisted dialog settings. */ private IDialogSettings settings; /** The currently selected simple type. */ private XSDSimpleTypeDefinition simpleType; // =========================================================================================================================== // Controls // =========================================================================================================================== /** radio button for selecting any data type. */ private Button btnAnyDataType; /** radio button for selecting any object type. */ private Button btnAnyObjectType; /** push button to show metaclass chooser dialog. */ private Button btnBrowseMetaclass; /** push button to show simple type chooser dialog. */ private Button btnBrowseSimpleType; /** radio button for selecting objects with specified property containing specified text pattern. */ private Button btnContains; /** radio button for selecting objects having a specified metaclass. */ private Button btnMetaclass; /** radio button for selecting objects with specified property that does not contain the specified text pattern. */ private Button btnNotContain; /** radio button for selecting objects having a specified runtime type. */ private Button btnRuntimeType; /** radio button for selecting objects having a specified simple type. */ private Button btnSimpleType; private Combo cbxMetaclass; /** combobox for listing available properties/features to search for. */ private Combo cbxProperties; /** combobox for listing available runtime types to search for. */ private Combo cbxRuntimeType; /** combobox for listing most recently used property text patterns to search for. */ private Combo cbxTextPattern; private Button chkExactMatch; private Button chkIncludeProperty; private Button chkIncludeSubtypes; private Text txfSimpleType; // =========================================================================================================================== // Constructors // =========================================================================================================================== /** * Constructs a <code>MetadataSearchPage</code>. */ public MetadataSearchPage() { this.searchMgr = ModelerCore.createMetadataSearch(); this.metaclassMru = new ArrayList(); } // =========================================================================================================================== // Methods // =========================================================================================================================== /** * {@inheritDoc} * * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl( Composite parent ) { initializeDialogSettings(); setControl(createControlImpl(parent)); restoreState(); } private Composite createControlImpl( Composite theParent ) { // // Create main container // final int MAIN_COLS = 1; Composite pnlMain = WidgetFactory.createPanel(theParent, SWT.NONE, GridData.FILL_BOTH); pnlMain.setLayout(new GridLayout(MAIN_COLS, false)); // // pnlMain contents // // // ROW 1 - properties group // final int PROPERTIES_COLS = 4; Group pnl = WidgetFactory.createGroup(pnlMain, Util.getString(PREFIX + "group.criteria"), //$NON-NLS-1$ GridData.FILL_BOTH, MAIN_COLS, PROPERTIES_COLS); pnl.setFont(JFaceResources.getDefaultFont()); // undo bold font WidgetFactory assigned createPropertiesPanelContents(pnl, PROPERTIES_COLS); // // ROW 2 - object type group // final int OBJ_TYPE_COLS = 3; pnl = WidgetFactory.createGroup(pnlMain, Util.getString(PREFIX + "group.objectType"), //$NON-NLS-1$ GridData.FILL_BOTH, MAIN_COLS, OBJ_TYPE_COLS); pnl.setFont(JFaceResources.getDefaultFont()); // undo bold font WidgetFactory assigned createObjectTypePanelContents(pnl, OBJ_TYPE_COLS); // // ROW 3 - data type group // final int DATA_TYPE_COLS = 3; pnl = WidgetFactory.createGroup(pnlMain, Util.getString(PREFIX + "group.dataType"), //$NON-NLS-1$ GridData.FILL_BOTH, MAIN_COLS, DATA_TYPE_COLS); pnl.setFont(JFaceResources.getDefaultFont()); // undo bold font WidgetFactory assigned createDataTypePanelContents(pnl, DATA_TYPE_COLS); // // ROW 4 Scope is added by SearchPage framework // return pnlMain; } /** * Constructs the panel containing the controls for managing the UI for the object type criteria. * * @param theParent the panel's parent container * @param theColumnCount the parent's column count */ private void createDataTypePanelContents( Composite theParent, int theColumnCount ) { // // ROW 1 // // any object type radio button this.btnAnyDataType = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.anyDataType"), //$NON-NLS-1$ 0, theColumnCount, false); this.btnAnyDataType.setToolTipText(Util.getString(PREFIX + "radioButton.anyDataType.tip")); //$NON-NLS-1$ this.btnAnyDataType.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleAnyDataTypeSelected(); } }); // // ROW 2 // // simple type radio button (selected as default) this.btnSimpleType = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.simpleType"), //$NON-NLS-1$ false); this.btnSimpleType.setToolTipText(Util.getString(PREFIX + "radioButton.simpleType.tip")); //$NON-NLS-1$ this.btnSimpleType.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleSimpleTypeSelected(); } }); // textfield for simple type this.txfSimpleType = WidgetFactory.createTextField(theParent, GridData.FILL_HORIZONTAL); this.txfSimpleType.setToolTipText(Util.getString(PREFIX + "text.simpleType.tip")); //$NON-NLS-1$ this.txfSimpleType.setEditable(false); this.txfSimpleType.setEnabled(false); this.txfSimpleType.addModifyListener(new ModifyListener() { @Override public void modifyText( ModifyEvent theEvent ) { handleSimpleTypeChanged(); } }); // browse simple type button this.btnBrowseSimpleType = WidgetFactory.createButton(theParent, InternalUiConstants.Widgets.BROWSE_BUTTON); this.btnBrowseSimpleType.setToolTipText(Util.getString(PREFIX + "button.browseSimpleType.tip")); //$NON-NLS-1$ this.btnBrowseSimpleType.setEnabled(false); this.btnBrowseSimpleType.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleBrowseSimpleType(); } }); // // ROW 3 // // include subtype checkbox this.chkIncludeSubtypes = WidgetFactory.createCheckBox(theParent, Util.getString(PREFIX + "checkBox.includeSubtypes"), //$NON-NLS-1$ SWT.LEFT, theColumnCount); ((GridData)this.chkIncludeSubtypes.getLayoutData()).horizontalIndent = 20; this.chkIncludeSubtypes.setToolTipText(Util.getString(PREFIX + "checkBox.includeSubtypes.tip")); //$NON-NLS-1$ this.chkIncludeSubtypes.setEnabled(false); this.chkIncludeSubtypes.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleIncludeSubtypesSelected(); } }); // // ROW 4 // // runtime type radio button this.btnRuntimeType = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.runtimeType")); //$NON-NLS-1$ this.btnRuntimeType.setToolTipText(Util.getString(PREFIX + "radioButton.runtimeType.tip")); //$NON-NLS-1$ this.btnRuntimeType.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleRuntimeTypeSelected(); } }); // combo for runtime type list this.cbxRuntimeType = WidgetFactory.createCombo(theParent, SWT.READ_ONLY, GridData.HORIZONTAL_ALIGN_FILL, (theColumnCount - 1)); this.cbxRuntimeType.setToolTipText(Util.getString(PREFIX + "combo.runtimeType.tip")); //$NON-NLS-1$ this.cbxRuntimeType.setEnabled(false); WidgetUtil.setComboItems(cbxRuntimeType, RuntimeType.VALUES, new LabelProvider(), true); this.cbxRuntimeType.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleRuntimeTypeChanged(); } }); } /** * Constructs the panel containing the controls for managing the UI for the object type criteria. * * @param theParent the panel's parent container * @param theColumnCount the parent's column count */ private void createObjectTypePanelContents( Composite theParent, int theColumnCount ) { // // ROW 1 // // any object type radio button this.btnAnyObjectType = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.anyObjectType"), //$NON-NLS-1$ 0, theColumnCount, false); this.btnAnyObjectType.setToolTipText(Util.getString(PREFIX + "radioButton.anyObjectType.tip")); //$NON-NLS-1$ this.btnAnyObjectType.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleAnyObjectTypeSelected(); } }); // // ROW 2 // // metaclass radio button this.btnMetaclass = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.metaclass")); //$NON-NLS-1$ this.btnMetaclass.setToolTipText(Util.getString(PREFIX + "radioButton.metaclass.tip")); //$NON-NLS-1$ this.btnMetaclass.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleMetaclassSelected(); } }); // textfield for runtime type this.cbxMetaclass = WidgetFactory.createCombo(theParent, SWT.READ_ONLY, GridData.FILL_HORIZONTAL); this.cbxMetaclass.setToolTipText(Util.getString(PREFIX + "combo.metaclass.tip")); //$NON-NLS-1$ this.cbxMetaclass.setEnabled(false); this.cbxMetaclass.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleMetaclassChanged(); } }); // browse runtime type button this.btnBrowseMetaclass = WidgetFactory.createButton(theParent, InternalUiConstants.Widgets.BROWSE_BUTTON); this.btnBrowseMetaclass.setToolTipText(Util.getString(PREFIX + "button.browseMetaclass.tip")); //$NON-NLS-1$ this.btnBrowseMetaclass.setEnabled(false); this.btnBrowseMetaclass.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleBrowseMetaclass(); } }); } /** * Creates the contents of the properties/feature panel. * * @param theParent the parent container * @param theColumnCount the layout columns in the parent * @since 6.0.0 */ private void createPropertiesPanelContents( Composite theParent, int theColumnCount ) { // // ROW 1 // // include property in search this.chkIncludeProperty = WidgetFactory.createCheckBox(theParent, Util.getString(PREFIX + "checkBox.includeProperty"), //$NON-NLS-1$ SWT.LEFT); this.chkIncludeProperty.setToolTipText(Util.getString(PREFIX + "checkBox.includeProperty.tip")); //$NON-NLS-1$ this.chkIncludeProperty.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleIncludePropertySelected(); } }); // List of properties this.cbxProperties = WidgetFactory.createCombo(theParent, SWT.READ_ONLY, GridData.HORIZONTAL_ALIGN_FILL, (theColumnCount - 1)); this.cbxProperties.setItems(this.searchMgr.getFeaturesNames()); this.cbxProperties.setToolTipText(Util.getString(PREFIX + "combo.properties.tip")); //$NON-NLS-1$ this.cbxProperties.setEnabled(false); this.cbxProperties.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handlePropertySelected(); } }); // enablement for all property related controls based on having properties boolean enable = this.cbxProperties.getItemCount() > 0; this.chkIncludeProperty.setEnabled(enable); // select first property to avoid having nothing selected at startup if (enable) { this.cbxProperties.select(0); } // // ROW 2 // final int INDENT = 20; // property contains text pattern radio button (selected as default) this.btnContains = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.contains")); //$NON-NLS-1$ this.btnContains.setToolTipText(Util.getString(PREFIX + "radioButton.contains.tip")); //$NON-NLS-1$ this.btnContains.setEnabled(enable); this.btnContains.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleContainsSelected(); } }); ((GridData)this.btnContains.getLayoutData()).horizontalIndent = INDENT; // property does not contain text pattern radio button this.btnNotContain = WidgetFactory.createRadioButton(theParent, Util.getString(PREFIX + "radioButton.notContain")); //$NON-NLS-1$ this.btnNotContain.setToolTipText(Util.getString(PREFIX + "radioButton.notContain.tip")); //$NON-NLS-1$ this.btnNotContain.setEnabled(enable); this.btnNotContain.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleNotContainSelected(); } }); // exact match checkbox so that results match the text pattern this.chkExactMatch = WidgetFactory.createCheckBox(theParent, Util.getString(PREFIX + "checkBox.exactMatch"), //$NON-NLS-1$ GridData.FILL_HORIZONTAL); this.chkExactMatch.setToolTipText(Util.getString(PREFIX + "checkBox.exactMatch.tip")); //$NON-NLS-1$ this.chkExactMatch.setEnabled(false); this.chkExactMatch.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent theEvent ) { handleExactMatchSelected(); } }); // // ROW 3 // // label for text patterns CLabel lbl = WidgetFactory.createLabel(theParent, GridData.HORIZONTAL_ALIGN_BEGINNING, theColumnCount, Util.getString(PREFIX + "label.textPattern")); //$NON-NLS-1$ ((GridData)lbl.getLayoutData()).horizontalIndent = INDENT; // // ROW 4 // // MRU for text patterns this.cbxTextPattern = WidgetFactory.createCombo(theParent, SWT.NONE, GridData.FILL_HORIZONTAL, (theColumnCount - 1)); this.cbxTextPattern.setToolTipText(Util.getString(PREFIX + "combo.textPattern.tip")); //$NON-NLS-1$ this.cbxTextPattern.setEnabled(enable); this.cbxTextPattern.addModifyListener(new ModifyListener() { @Override public void modifyText( ModifyEvent theEvent ) { handleTextPatternModified(); } }); ((GridData)this.cbxTextPattern.getLayoutData()).horizontalIndent = INDENT; } /** * Obtains the label provider used for metaclass. * * @return the label provider * @since 6.0.0 */ private ILabelProvider getLabelProvider() { if (this.labelProvider == null) { // construct dialog to get it's label provider MetamodelSelectionDialog dialog = (MetamodelSelectionDialog)MetamodelTreeViewer.createSelectionDialog(getShell(), false); this.labelProvider = (ILabelProvider)dialog.getViewerLabelProvider(); } return this.labelProvider; } /** * Obtains the <code>EClass</code> for the specified {@link URI} string representation. * * @param theUri the URI whose metaclass is being requested * @return the metaclass or <code>null</code> * @since 6.0.0 */ private EClass getMetaclass( String theUri ) { EClass result = null; if ((theUri != null) && (theUri.length() > 0)) { try { Object temp = ModelUtilities.getWorkspaceContainer().getEObject(URI.createURI(theUri), true); if ((temp != null) && (temp instanceof EClass)) { result = (EClass)temp; } else { Util.log("Not EClass. URI = " + temp); //$NON-NLS-1$ } } catch (CoreException theException) { Util.log(theException); } } return result; } /** * Obtains the text representation of the specified metaclass URI. * * @param theMetaclassUri the metaclass URI whose text representation is being requested * @return the text * @since 6.0.0 */ private String getMetaclassText( String theMetaclassUri ) { return getMetaclass(theMetaclassUri).getName();// getLabelProvider().getText(getMetaclass(theMetaclassUri)); } /** * Objtains the string representation of the {@link URI} for the specified metaclass. * * @param theMetaclass the metaclass whose URI is being requested * @return the string representation of the URI * @since 6.0.0 */ private String getMetaclassUri( EClass theMetaclass ) { return ModelerCore.getModelEditor().getUri(theMetaclass).toString(); } /** * Handler for when the any data type radio button is selected/deselected. * * @since 6.0.0 */ void handleAnyDataTypeSelected() { // only update controls and business object when selected since this is a radio button and // the other radio buttons in the group also only update when they're selected if (this.btnAnyDataType.getSelection()) { // disable this.txfSimpleType.setEnabled(false); this.btnBrowseSimpleType.setEnabled(false); this.chkIncludeSubtypes.setEnabled(false); this.cbxRuntimeType.setEnabled(false); // synch business object this.searchMgr.setDatatype(null, false); this.searchMgr.setRuntimeType(null); // update search button status updateSearchState(); } } void handleAnyObjectTypeSelected() { // only update controls and business object when selected since this is a radio button and // the other radio buttons in the group also only update when they're selected if (this.btnAnyObjectType.getSelection()) { // disable this.cbxMetaclass.setEnabled(false); this.btnBrowseMetaclass.setEnabled(false); // set enablement and update business object setDataTypePanelEnabled(true); // synch business object this.searchMgr.setMetaClass(null); // update search button status updateSearchState(); } } void handleBrowseMetaclass() { MetamodelSelectionDialog dialog = (MetamodelSelectionDialog)MetamodelTreeViewer.createSelectionDialog(getShell(), false); if (this.labelProvider == null) { this.labelProvider = (ILabelProvider)dialog.getViewerLabelProvider(); } dialog.setAllowMultiple(false); // set dialog to current metaclass if necessary if (this.metaclass != null) { dialog.setInitialSelection(this.metaclass); } // if user makes a selection and OKs dialog validation takes place in handleMetaclassChanged() if (dialog.open() == Window.OK) { updateMetaclass((EClass)dialog.getResult()[0]); // validator ensures right type of result updateDataTypePanelEnable(); // added to upadte data type panel. sz } } void handleBrowseSimpleType() { DatatypeSelectionDialog dialog = new DatatypeSelectionDialog(getShell()); // set dialog to current simple type if necessary if (this.simpleType != null) { dialog.setInitialSelections(new Object[] {this.simpleType}); } // if user makes a selection and OKs dialog make sure validate if (dialog.open() == Window.OK) { updateSimpleType((XSDSimpleTypeDefinition)dialog.getResult()[0]); } } /** * Handler for when the contains text pattern radio button is selected/deselected. * * @since 6.0.0 */ void handleContainsSelected() { // only validate when selected since that's what all the other buttons in the radio button group are doing if (this.btnContains.getSelection()) { updatePropertyCriteria(); } } /** * Handler for when the exact match checkbox is selected/deselected. * * @since 6.0.0 */ void handleExactMatchSelected() { // don't allow unchecking if Object URI search if (this.cbxProperties.getText().equals(MetadataSearch.OBJECT_URI_FEATURE)) { if (!this.chkExactMatch.getSelection()) { this.chkExactMatch.setSelection(true); } } updatePropertyCriteria(); } /** * Handler for when the include subtypes of simple type checkbox is checked/unchecked. * * @since 6.0.0 */ void handleIncludeSubtypesSelected() { handleSimpleTypeChanged(); } /** * Handler for when the include property in search checkbox is checked/unchecked. * * @since 6.0.0 */ void handleIncludePropertySelected() { boolean enable = this.chkIncludeProperty.getSelection() && this.chkIncludeProperty.getEnabled(); this.cbxProperties.setEnabled(enable); this.btnContains.setEnabled(enable); this.btnNotContain.setEnabled(enable); this.chkExactMatch.setEnabled(enable); this.cbxTextPattern.setEnabled(enable); handlePropertySelected(); // call property selected handler since properties were re-enabled } /** * Handler for when the selected metaclass changes. * * @since 6.0.0 */ void handleMetaclassChanged() { int index = this.cbxMetaclass.getSelectionIndex(); this.metaclass = getMetaclass((String)this.metaclassMru.get(index)); // this call updates search state handleMetaclassSelected(); } /** * Handler for when the metaclass radio button is selected/deselected. * * @since 6.0.0 */ void handleMetaclassSelected() { // only update controls and business object when selected since this is a radio button and // the other radio buttons in the group also only update when they're selected if (this.btnMetaclass.getSelection()) { // enable this.btnBrowseMetaclass.setEnabled(true); this.cbxMetaclass.setEnabled(true); // synch business object this.searchMgr.setMetaClass(this.metaclass); // this updates data type panel. sz updateDataTypePanelEnable(); // update search button status updateSearchState(); } } /** * Updates data type panel based on the metaclass radio button selection, also updates on meta class combo population. sz */ private void updateDataTypePanelEnable() { boolean enable = false; if (this.metaclass != null) { // only certain classes are typed enable = this.searchMgr.isTypedMetaClass(this.metaclass); cbxMetaclass.setToolTipText(getLabelProvider().getText(this.metaclass)); } // set enablement and update business object setDataTypePanelEnabled(enable); } /** * Handler for when the not contains text pattern radio button is selected/deselected. * * @since 6.0.0 */ void handleNotContainSelected() { // only validate when selected since that's what all the other buttons in the radio button group are doing if (this.btnNotContain.getSelection()) { updatePropertyCriteria(); } } /** * Handler for when the selected property changes. * * @since 6.0.0 */ void handlePropertySelected() { // if Object URI search make sure exact match is checked and others are disabled if (this.cbxProperties.getText().equals(MetadataSearch.OBJECT_URI_FEATURE)) { this.chkExactMatch.setSelection(true); this.btnContains.setEnabled(false); this.btnNotContain.setEnabled(false); } else { this.btnContains.setEnabled(true); this.btnNotContain.setEnabled(true); } updatePropertyCriteria(); } /** * Handler for when the selected runtime type changes. * * @since 6.0.0 */ void handleRuntimeTypeChanged() { this.runtimeType = this.cbxRuntimeType.getText(); this.searchMgr.setRuntimeType(this.runtimeType); updateSearchState(); } /** * Handler for when the runtime type radio button is selected/deselected. * * @since 6.0.0 */ void handleRuntimeTypeSelected() { // only update controls and business object when selected since this is a radio button and // the other radio buttons in the group also only update when they're selected if (this.btnRuntimeType.getSelection()) { // disable this.txfSimpleType.setEnabled(false); this.chkIncludeSubtypes.setEnabled(false); this.btnBrowseSimpleType.setEnabled(false); // enable this.cbxRuntimeType.setEnabled(true); // synch business object this.searchMgr.setRuntimeType(this.runtimeType); this.searchMgr.setDatatype(null, false); // update search button status updateSearchState(); } } /** * Handler for when the simple type changes. * * @since 6.0.0 */ void handleSimpleTypeChanged() { this.searchMgr.setDatatype(this.simpleType, this.chkIncludeSubtypes.getSelection()); updateSearchState(); } /** * Handler for when the simple type radio button is selected/deselected. * * @since 6.0.0 */ void handleSimpleTypeSelected() { // only update controls and business object when selected since this is a radio button and // the other radio buttons in the group also only update when they're selected if (this.btnSimpleType.getSelection()) { // disable this.cbxRuntimeType.setEnabled(false); // enable this.txfSimpleType.setEnabled(true); this.btnBrowseSimpleType.setEnabled(true); this.chkIncludeSubtypes.setEnabled(true); // synch business object this.searchMgr.setDatatype(this.simpleType, this.chkIncludeSubtypes.getSelection()); this.searchMgr.setRuntimeType(null); // update search button status updateSearchState(); } } /** * Handler for when the text pattern changes. * * @since 6.0.0 */ void handleTextPatternModified() { updatePropertyCriteria(); } /** * Select specified button and fire selection event to it's listeners. Need to do this because SWT events aren't fired at * construction. * * @param theButton the button being selected */ private void initButtonSelected( final Button theButton ) { initButtonSelected(theButton, true); } /** * Select or deselect specified button and fire selection event to it's listeners. Need to do this because events aren't * generated at construction. * * @param theButton the button being selected or deselected */ private void initButtonSelected( final Button theButton, final boolean theSelectFlag ) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { theButton.setSelection(theSelectFlag); Event event = new Event(); event.widget = theButton; theButton.notifyListeners(SWT.Selection, event); } }); } private void initializeDialogSettings() { // get general search dialog settings IDialogSettings tempSettings = UiPlugin.getDefault().getDialogSettings(); // get this page's settings this.settings = tempSettings.getSection(getClass().getSimpleName()); // if settings not found create them if (this.settings == null) { this.settings = tempSettings.addNewSection(getClass().getSimpleName()); } } private boolean isSearchStateValid() { boolean result = false; boolean useMgr = true; // the search manager canExecute() method can't be used in all cases to determine if the // search criteria is valid. if (getControl() != null) { if (this.btnMetaclass.getSelection()) { if (this.metaclass == null) { result = false; useMgr = false; } else { if (this.searchMgr.isTypedMetaClass(this.metaclass)) { if (this.btnSimpleType.getSelection() && (this.simpleType == null)) { result = false; useMgr = false; } else if (this.btnRuntimeType.getSelection() && (this.runtimeType == null)) { result = false; useMgr = false; } } } } } // use business object to determine if search is valid if (useMgr) { result = this.searchMgr.canExecute().isOK(); } return result; } /** * {@inheritDoc} * * @see org.eclipse.search.ui.ISearchPage#performAction() */ @Override public boolean performAction() { // Need to update search manager for container changes since there is no way to hook into it this.searchMgr.setModelScope(SearchPageUtil.getModelWorkspaceScope(this.searchPageContainer)); saveState(); NewSearchUI.runQueryInBackground(new MetadataSearchQuery(this.searchMgr)); return true; } private void restoreState() { // // restore object type group // if (this.settings.getBoolean(DialogSettingsConstants.ANY_OBJ_TYPE)) { initButtonSelected(this.btnAnyObjectType); } else if (this.settings.getBoolean(DialogSettingsConstants.METACLASS_TYPE)) { initButtonSelected(this.btnMetaclass); } else { // first time using search page initButtonSelected(this.btnAnyObjectType); } // load metaclass MRU. these are metaclass URIs so need to use label provider to fill combo this.metaclassMru.clear(); String[] mru = this.settings.getArray(DialogSettingsConstants.METACLASS_MRU); if ((mru != null) && (mru.length > 0)) { for (int i = 0; i < mru.length; i++) { this.metaclassMru.add(mru[i]); this.cbxMetaclass.add(getMetaclassText(mru[i])); } // last used metaclass String uri = this.settings.get(DialogSettingsConstants.LAST_USED_METACLASS); if ((uri != null) && (uri.length() > 0)) { int index = this.metaclassMru.indexOf(uri); if (index == -1) { // then last used has gotten deleted from the MRU by the MRU_LIMIT this.metaclassMru.add(uri); index = 0; } EClass metaclass = getMetaclass(uri); if (metaclass != null) { updateMetaclass(metaclass); } } } // // restore data type group // if (this.settings.getBoolean(DialogSettingsConstants.INCLUDE_SUBTYPES)) { initButtonSelected(this.chkIncludeSubtypes); } else if (this.settings.get(DialogSettingsConstants.INCLUDE_SUBTYPES) == null) { // first time using search page if (MetadataSearch.DEFAULT_INCLUDE_SUBTYPES) { initButtonSelected(this.chkIncludeSubtypes); } } // initialize selected runtime type String selectedRuntimeType = this.settings.get(DialogSettingsConstants.SELECTED_RUNTIME_TYPE); updateRuntimeType(selectedRuntimeType); // initialize data type radio buttons selection if necessary // select last saved property if (this.settings.getBoolean(DialogSettingsConstants.ANY_DATA_TYPE)) { initButtonSelected(this.btnAnyDataType); } else if (this.settings.getBoolean(DialogSettingsConstants.SIMPLE_DATA_TYPE)) { initButtonSelected(this.btnSimpleType); } else if (this.settings.getBoolean(DialogSettingsConstants.RUNTIME_TYPE)) { initButtonSelected(this.btnRuntimeType); } else { // first time using search page initButtonSelected(this.btnAnyDataType); } // simple type String uri = this.settings.get(DialogSettingsConstants.SELECTED_SIMPLE_TYPE); if ((uri != null) && (uri.length() > 0)) { try { EObject type = ModelUtilities.getWorkspaceContainer().getEObject(URI.createURI(uri), false); if ((type != null) && (type instanceof XSDSimpleTypeDefinition)) { updateSimpleType((XSDSimpleTypeDefinition)type); } else { this.settings.put(DialogSettingsConstants.SELECTED_SIMPLE_TYPE, (String)null); } } catch (CoreException theException) { Util.log(theException); } } // load text patterns if necessary String[] patterns = this.settings.getArray(DialogSettingsConstants.TEXT_PATTERN); if ((patterns != null) && (patterns.length > 0)) { this.cbxTextPattern.setItems(patterns); // select the last used pattern String txt = this.settings.get(DialogSettingsConstants.LAST_USED_TEXT_PATTERN); if ((txt != null) && (txt.length() > 0)) { this.cbxTextPattern.setText(txt); } } // initialize contains/not contains radio button selection based on dialog settings if (this.settings.getBoolean(DialogSettingsConstants.CONTAINS_TEXT)) { initButtonSelected(this.btnContains); } else if (this.settings.getBoolean(DialogSettingsConstants.NOT_CONTAIN_TEXT)) { initButtonSelected(this.btnNotContain); } else { // first time using search page initButtonSelected(this.btnContains); } // initialize exact match checkbox based on dialog settings if (this.settings.getBoolean(DialogSettingsConstants.EXACT_MATCH)) { initButtonSelected(this.chkExactMatch); } // include property in search checkbox if (this.settings.getBoolean(DialogSettingsConstants.INCLUDE_PROPERTY)) { initButtonSelected(this.chkIncludeProperty); } else if (this.settings.get(DialogSettingsConstants.INCLUDE_PROPERTY) == null) { // first time using search page check include property initButtonSelected(this.chkIncludeProperty); } else { handleIncludePropertySelected(); } // make sure there are properties to select. if not disable panel. if (this.cbxProperties.getItemCount() == 0) { this.chkIncludeProperty.setEnabled(false); handleIncludePropertySelected(); } else { // select last saved property String selectedProperty = this.settings.get(DialogSettingsConstants.SELECTED_PROPERTY); if (selectedProperty != null) { int index = this.cbxProperties.indexOf(selectedProperty); if (index != -1) { this.cbxProperties.select(index); // handle the selection Display.getDefault().asyncExec(new Runnable() { @Override public void run() { handlePropertySelected(); } }); } } } } private void saveState() { this.settings.put(DialogSettingsConstants.ANY_OBJ_TYPE, this.btnAnyObjectType.getSelection()); this.settings.put(DialogSettingsConstants.METACLASS_TYPE, this.btnMetaclass.getSelection()); this.settings.put(DialogSettingsConstants.ANY_DATA_TYPE, this.btnAnyDataType.getSelection()); this.settings.put(DialogSettingsConstants.SIMPLE_DATA_TYPE, this.btnSimpleType.getSelection()); this.settings.put(DialogSettingsConstants.INCLUDE_SUBTYPES, this.chkIncludeSubtypes.getSelection()); this.settings.put(DialogSettingsConstants.RUNTIME_TYPE, this.btnRuntimeType.getSelection()); this.settings.put(DialogSettingsConstants.INCLUDE_PROPERTY, this.chkIncludeProperty.getSelection()); this.settings.put(DialogSettingsConstants.CONTAINS_TEXT, this.btnContains.getSelection()); this.settings.put(DialogSettingsConstants.NOT_CONTAIN_TEXT, this.btnNotContain.getSelection()); this.settings.put(DialogSettingsConstants.EXACT_MATCH, this.chkExactMatch.getSelection()); this.settings.put(DialogSettingsConstants.SELECTED_RUNTIME_TYPE, this.cbxRuntimeType.getText()); this.settings.put(DialogSettingsConstants.SELECTED_PROPERTY, this.cbxProperties.getText()); // save text pattern MRU WidgetUtil.saveSettings(settings, DialogSettingsConstants.TEXT_PATTERN, this.cbxTextPattern, DialogSettingsConstants.MRU_LIMIT); // save last used text pattern settings.put(DialogSettingsConstants.LAST_USED_TEXT_PATTERN, this.cbxTextPattern.getText()); // save metaclass MRU UiUtil.save(settings, DialogSettingsConstants.METACLASS_MRU, this.metaclassMru, DialogSettingsConstants.MRU_LIMIT); // save last used metaclass if (this.metaclass != null) { int index = this.cbxMetaclass.getSelectionIndex(); if (index != -1) { settings.put(DialogSettingsConstants.LAST_USED_METACLASS, (String)this.metaclassMru.get(index)); } } // save simple type if (this.simpleType != null) { settings.put(DialogSettingsConstants.SELECTED_SIMPLE_TYPE, this.simpleType.getURI()); } } /** * {@inheritDoc} * * @see org.eclipse.search.ui.ISearchPage#setContainer(org.eclipse.search.ui.ISearchPageContainer) */ @Override public void setContainer( ISearchPageContainer container ) { this.searchPageContainer = container; } /** * Sets the enablement of all the UI controls contained within the data type group. Also updates the business object with * datatype information. * * @param theEnableFlag the flag indicating the enablement state * @since 6.0.0 */ private void setDataTypePanelEnabled( boolean theEnableFlag ) { if (theEnableFlag) { this.btnAnyDataType.setEnabled(true); this.btnSimpleType.setEnabled(true); this.btnRuntimeType.setEnabled(true); // updates the business object if (this.btnAnyDataType.getSelection()) { handleAnyDataTypeSelected(); } else if (this.btnSimpleType.getSelection()) { handleSimpleTypeSelected(); } else if (this.btnRuntimeType.getSelection()) { handleRuntimeTypeSelected(); } } else { this.btnAnyDataType.setEnabled(false); this.btnSimpleType.setEnabled(false); this.txfSimpleType.setEnabled(false); this.btnBrowseSimpleType.setEnabled(false); this.chkIncludeSubtypes.setEnabled(false); this.btnRuntimeType.setEnabled(false); this.cbxRuntimeType.setEnabled(false); // updates the business object this.searchMgr.setDatatype(null, false); this.searchMgr.setRuntimeType(null); } } @Override public void setVisible( boolean visible ) { // make sure "Search" button is enabled correctly if (visible) { updateSearchState(); } super.setVisible(visible); } private void updatePropertyCriteria() { if (this.chkIncludeProperty.getSelection() && this.chkIncludeProperty.getEnabled()) { String pattern = this.cbxTextPattern.getText().trim(); // if not exact match then need to surround text with asterisks (unless already there) // and don't add asterisks if searching by Object ID if (!this.chkExactMatch.getSelection() && (pattern.length() > 0) && !this.cbxProperties.getText().equals(MetadataSearch.OBJECT_URI_FEATURE)) { // make sure pattern includes a leading wildcard char if (!pattern.startsWith(MetadataSearch.TEXT_PATTERN_ANY_STRING) && !pattern.startsWith(MetadataSearch.TEXT_PATTERN_ANY_CHAR)) { pattern = new StringBuffer().append(MetadataSearch.TEXT_PATTERN_ANY_STRING).append(pattern).toString(); } // make sure pattern includes an ending wildcard char if (!pattern.endsWith(MetadataSearch.TEXT_PATTERN_ANY_STRING) && !pattern.endsWith(MetadataSearch.TEXT_PATTERN_ANY_CHAR)) { pattern = new StringBuffer().append(pattern).append(MetadataSearch.TEXT_PATTERN_ANY_STRING).toString(); } } this.searchMgr.setFeatureCriteria(this.cbxProperties.getText(), pattern, this.btnContains.getSelection()); } else { // not performing a property/feature-based search this.searchMgr.setFeatureCriteria(null, null, false); } updateSearchState(); } /** * Updates fields and UI with the new simple type. * * @param theNewType the new simple type * @since 6.0.0 */ private void updateMetaclass( EClass theNewMetaclass ) { this.metaclass = theNewMetaclass; this.searchMgr.setMetaClass(this.metaclass); // show only the name: String txt = metaclass.getName(); int index = this.cbxMetaclass.indexOf(txt); if (index == -1) { this.metaclassMru.add(getMetaclassUri(theNewMetaclass)); this.cbxMetaclass.add(txt); index = this.cbxMetaclass.indexOf(txt); } this.cbxMetaclass.select(index); this.cbxMetaclass.setToolTipText(getLabelProvider().getText(this.metaclass)); updateSearchState(); } /** * Update fields and UI with the new Runtime Type. * * @param theNewType the new Runtime type * @since 6.0.0 */ private void updateRuntimeType( String selectedRuntimeType ) { if (selectedRuntimeType != null) { int index = this.cbxRuntimeType.indexOf(selectedRuntimeType); if (index != -1) { this.cbxRuntimeType.select(index); } else if (this.cbxRuntimeType.getItemCount() > 0) { this.cbxRuntimeType.select(0); } } else { /* * If the selectedRuntimeType variable is null, set cbxRuntimeType to the first value in the list. */ if (this.cbxRuntimeType.getItemCount() > 0) { this.cbxRuntimeType.select(0); } } this.runtimeType = this.cbxRuntimeType.getText(); } private void updateSearchState() { this.searchPageContainer.setPerformActionEnabled(isSearchStateValid()); } /** * Updates fields and UI with the new simple type. * * @param theNewType the new simple type * @since 6.0.0 */ private void updateSimpleType( XSDSimpleTypeDefinition theNewType ) { this.simpleType = theNewType; this.txfSimpleType.setText(ModelUtilities.getEMFLabelProvider().getText(this.simpleType)); updateSearchState(); } }