Java tutorial
package com.mentor.nucleus.bp.ui.search.pages; //======================================================================== // //File: $RCSfile: ModelSearchPage.java,v $ //Version: $Revision: 1.6 $ //Modified: $Date: 2013/01/10 23:13:51 $ // //Copyright (c) 2005-2014 Mentor Graphics Corporation. All rights reserved. // //======================================================================== // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. //======================================================================== // import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.dialogs.DialogPage; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.fieldassist.ComboContentAdapter; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceColors; import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.search.ui.ISearchPage; import org.eclipse.search.ui.ISearchPageContainer; import org.eclipse.search.ui.ISearchQuery; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import com.mentor.nucleus.bp.core.CorePlugin; import com.mentor.nucleus.bp.core.Ooaofooa; import com.mentor.nucleus.bp.core.Searchscope_c; import com.mentor.nucleus.bp.core.SystemModel_c; import com.mentor.nucleus.bp.core.XtUMLNature; import com.mentor.nucleus.bp.core.common.ClassQueryInterface_c; import com.mentor.nucleus.bp.core.common.NonRootModelElement; import com.mentor.nucleus.bp.core.common.PersistableModelComponent; import com.mentor.nucleus.bp.core.common.PersistenceManager; import com.mentor.nucleus.bp.core.ui.Selection; import com.mentor.nucleus.bp.search.Activator; import com.mentor.nucleus.bp.search.query.ModelQueryProvider; import com.mentor.nucleus.bp.search.query.ModelSearchInput; public class ModelSearchPage extends DialogPage implements ISearchPage { private static final String DEFAULT_STATUS = "(* = any string, ? = any character, \\ = escape for literals: * ? \\)"; private ISearchPageContainer pageContainer; private Combo pattern; private ContentAssistCommandAdapter patternFieldContentAssist; private boolean isRegExSearch; private Button isCaseSensitiveCheckbox; private boolean isCaseSensitive; private CLabel statusLabel; private Button isRegExCheckbox; // private Button declarationButton; // private Button referencesButton; private Button oalTextButton; private Button descriptionTextButton; // private ElementSelectionFlatView typeChooser; private boolean isActionLanguageSearch; private boolean isDescriptionSearch; private boolean isReferencesSearch; private boolean isDeclerationsSearch; private List<ModelSearchInput> previousSearchInputData = new ArrayList<ModelSearchInput>(); private boolean firstTime = true; // Dialog store id constants private static final String PAGE_NAME = "ModelSearchPage"; //$NON-NLS-1$ private static final String STORE_CASE_SENSITIVE = "CASE_SENSITIVE"; //$NON-NLS-1$ private static final String STORE_IS_REG_EX_SEARCH = "REG_EX_SEARCH"; //$NON-NLS-1$ private static final String STORE_HISTORY = "HISTORY"; //$NON-NLS-1$ private static final String STORE_HISTORY_SIZE = "HISTORY_SIZE"; //$NON-NLS-1$ private static final String STORE_SEARCH_DESCRIPTION = "DESCRIPTION_SEARCH"; // $NON-NLS-1$ private static final String STORE_SEARCH_ACTION_LANGUAGE = "ACTION_LANGUAGE_SEARCH"; // $NON-NLS-1$ private static final int HISTORY_SIZE = 12; public ModelSearchPage() { } public ModelSearchPage(String title, ImageDescriptor image) { super(title, image); } @Override public void createControl(Composite parent) { readConfiguration(); Composite xtumlControlComposite = new Composite(parent, SWT.None); GridLayout layout = new GridLayout(2, false); xtumlControlComposite.setLayout(layout); addTextPatternControls(xtumlControlComposite); Composite configComposite = new Composite(xtumlControlComposite, SWT.None); configComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); configComposite.setLayout(new GridLayout(1, true)); createLimitGroup(configComposite); setControl(xtumlControlComposite); } private void createLimitGroup(Composite configComposite) { Group limitGroup = new Group(configComposite, SWT.SHADOW_ETCHED_IN); limitGroup.setLayout(new GridLayout(2, true)); limitGroup.setText("Limit To"); GridData limitGroupData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); oalTextButton = new Button(limitGroup, SWT.CHECK); oalTextButton.setText("Action Language"); oalTextButton.setSelection(isActionLanguageSearch); oalTextButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1)); oalTextButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { isActionLanguageSearch = oalTextButton.getSelection(); } @Override public void widgetSelected(SelectionEvent e) { isActionLanguageSearch = oalTextButton.getSelection(); } }); descriptionTextButton = new Button(limitGroup, SWT.CHECK); descriptionTextButton.setText("Descriptions"); descriptionTextButton.setSelection(isDescriptionSearch); descriptionTextButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1)); descriptionTextButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { isDescriptionSearch = descriptionTextButton.getSelection(); } @Override public void widgetSelected(SelectionEvent e) { isDescriptionSearch = descriptionTextButton.getSelection(); } }); limitGroup.setLayoutData(limitGroupData); } private void addTextPatternControls(Composite group) { // grid layout with 2 columns // Info text Label label = new Label(group, SWT.LEAD); label.setText("Search text"); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); // Pattern combo pattern = new Combo(group, SWT.SINGLE | SWT.BORDER); pattern.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleWidgetSelected(); updateOKStatus(); } }); // add some listeners for regex syntax checking pattern.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { updateOKStatus(); } }); GridData data = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1); data.widthHint = convertWidthInCharsToPixels(50); pattern.setLayoutData(data); ComboContentAdapter contentAdapter = new ComboContentAdapter(); FindReplaceDocumentAdapterContentProposalProvider findProposer = new FindReplaceDocumentAdapterContentProposalProvider( true); patternFieldContentAssist = new ContentAssistCommandAdapter(pattern, contentAdapter, findProposer, ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[] { '\\', '[', '(' }, true); patternFieldContentAssist.setEnabled(isRegExSearch); isCaseSensitiveCheckbox = new Button(group, SWT.CHECK); isCaseSensitiveCheckbox.setText("Case sensitive"); isCaseSensitiveCheckbox.setSelection(isCaseSensitive); isCaseSensitiveCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { isCaseSensitive = isCaseSensitiveCheckbox.getSelection(); } }); isCaseSensitiveCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); isCaseSensitiveCheckbox.setFont(group.getFont()); // Text line which explains the special characters statusLabel = new CLabel(group, SWT.LEAD); statusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); statusLabel.setFont(group.getFont()); statusLabel.setAlignment(SWT.LEFT); statusLabel.setText(DEFAULT_STATUS); // RegEx checkbox isRegExCheckbox = new Button(group, SWT.CHECK); isRegExCheckbox.setText("Regular expression"); isRegExCheckbox.setSelection(isRegExSearch); isRegExCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { isRegExSearch = isRegExCheckbox.getSelection(); updateOKStatus(); writeConfiguration(); patternFieldContentAssist.setEnabled(isRegExSearch); } }); isRegExCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); isRegExCheckbox.setFont(group.getFont()); } private boolean validateRegex() { if (isRegExCheckbox.getSelection()) { try { int regexOptions = Pattern.MULTILINE; if (!isCaseSensitiveCheckbox.getSelection()) { regexOptions |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE; } Pattern.compile(pattern.getText(), regexOptions); } catch (PatternSyntaxException e) { String locMessage = e.getLocalizedMessage(); int i = 0; while (i < locMessage.length() && "\n\r".indexOf(locMessage.charAt(i)) == -1) { //$NON-NLS-1$ i++; } setStatusMessage(true, locMessage.substring(0, i)); // only take // first // line return false; } setStatusMessage(false, ""); //$NON-NLS-1$ } else { setStatusMessage(false, DEFAULT_STATUS); } return true; } private void setStatusMessage(boolean error, String message) { statusLabel.setText(message); if (error) statusLabel.setForeground(JFaceColors.getErrorText(statusLabel.getDisplay())); else statusLabel.setForeground(null); } /** * Returns the page settings for this Text search page. * * @return the page settings to be used */ private IDialogSettings getDialogSettings() { return Activator.getDefault().getDialogSettingsSection(PAGE_NAME); } protected void writeConfiguration() { IDialogSettings settings = getDialogSettings(); settings.put(STORE_CASE_SENSITIVE, isCaseSensitive); settings.put(STORE_IS_REG_EX_SEARCH, isRegExSearch); settings.put(STORE_SEARCH_DESCRIPTION, isDescriptionSearch); settings.put(STORE_SEARCH_ACTION_LANGUAGE, isActionLanguageSearch); int historySize = Math.min(previousSearchInputData.size(), HISTORY_SIZE); settings.put(STORE_HISTORY_SIZE, historySize); for (int i = 0; i < historySize; i++) { IDialogSettings histSettings = settings.addNewSection(STORE_HISTORY + i); ModelSearchInput input = ((ModelSearchInput) previousSearchInputData.get(i)); input.store(histSettings); } } /** * Initializes itself from the stored page settings. */ private void readConfiguration() { IDialogSettings settings = getDialogSettings(); isCaseSensitive = settings.getBoolean(STORE_CASE_SENSITIVE); isRegExSearch = settings.getBoolean(STORE_IS_REG_EX_SEARCH); isDescriptionSearch = settings.getBoolean(STORE_SEARCH_DESCRIPTION); isActionLanguageSearch = settings.getBoolean(STORE_SEARCH_ACTION_LANGUAGE); try { int historySize = settings.getInt(STORE_HISTORY_SIZE); for (int i = 0; i < historySize; i++) { IDialogSettings histSettings = settings.getSection(STORE_HISTORY + i); if (histSettings != null) { ModelSearchInput input = ModelSearchInput.create(histSettings); if (input != null) { previousSearchInputData.add(input); } } } } catch (NumberFormatException e) { // no history yet, ignore this exception } } protected void updateOKStatus() { boolean regexStatus = validateRegex(); boolean hasPattern = !pattern.getText().equals(""); getContainer().setPerformActionEnabled(regexStatus && hasPattern); } /* * Implements method from IDialogPage */ public void setVisible(boolean visible) { if (visible && pattern != null) { if (firstTime) { firstTime = false; // Set item and text here to prevent page from resizing pattern.setItems(getPreviousInputPatterns()); pattern.select(0); handleWidgetSelected(); } pattern.setFocus(); } updateOKStatus(); super.setVisible(visible); } private String[] getPreviousInputPatterns() { int size = previousSearchInputData.size(); String[] patterns = new String[size]; for (int i = 0; i < size; i++) patterns[i] = ((ModelSearchInput) previousSearchInputData.get(i)).getPattern(); return patterns; } protected void handleWidgetSelected() { int selectionIndex = pattern.getSelectionIndex(); if (selectionIndex < 0 || selectionIndex >= previousSearchInputData.size()) return; ModelSearchInput input = (ModelSearchInput) previousSearchInputData.get(selectionIndex); if (!pattern.getText().equals(input.getPattern())) return; isCaseSensitiveCheckbox.setSelection(input.isCaseSensitive()); isRegExCheckbox.setSelection(input.isRegExSearch()); oalTextButton.setSelection(input.isOALSearch); descriptionTextButton.setSelection(input.isDescriptionSearch); pattern.setText(input.getPattern()); if (input.getWorkingSets() != null) getContainer().setSelectedWorkingSets(input.getWorkingSets()); else getContainer().setSelectedScope(input.getScope()); } @Override public boolean performAction() { ISearchQuery query = createQuery(); NewSearchUI.runQueryInBackground(query); return true; } private ISearchQuery createQuery() { ModelSearchInput input = createSearchInput(); return ModelQueryProvider.createQuery(input); } private ModelSearchInput createSearchInput() { boolean actionLanguage = isActionLanguageSearch; boolean description = isDescriptionSearch; // if not regEx adjust the pattern, adding // any necessary escapes String patternString = pattern.getText(); NonRootModelElement[] selectedElements = configureSelectionForInput(getContainer().getSelectedScope()); ModelSearchInput input = new ModelSearchInput(patternString, isCaseSensitive, isRegExSearch, actionLanguage, isDeclerationsSearch, isReferencesSearch, description, getContainer().getSelectedScope(), selectedElements, getContainer().getSelectedWorkingSets()); ModelSearchInput remove = null; for (ModelSearchInput existing : previousSearchInputData) { if (existing.getSelected() == null) { NonRootModelElement[] selection = configureSelectionForInput(input.getScope()); input.setSelection(selection); } if (input.equals(existing)) { remove = existing; break; } } if (remove != null) { previousSearchInputData.remove(remove); remove.dispose(); } previousSearchInputData.add(0, input); return input; } private NonRootModelElement[] configureSelectionForInput(int scope) { // if the scope is enclosing project, or working set // treat it like a selection, passing in the appropriate // elements NonRootModelElement[] selectedElements = Selection.getInstance().getSelectedNonRootModelElements(); if (ModelSearchInput.getSearchScope(scope) == Searchscope_c.EnclosingSystem) { selectedElements = getSystemsFromSelection(); } if (scope == ISearchPageContainer.WORKING_SET_SCOPE) { // gather all elements in the working set selectedElements = getSelectionFromWorkingSet(); } if (scope == ISearchPageContainer.SELECTION_SCOPE) { selectedElements = getElementsFromSelection(selectedElements); } return selectedElements; } private NonRootModelElement[] getElementsFromSelection(NonRootModelElement[] coreSelected) { // if the selection contains files, folders, or projects // locate the NonRootModelElement instances ISelection selection = getContainer().getSelection(); // if the selection does not contain projects/files/folders // then default to core selection boolean foundResource = false; IStructuredSelection ss = (IStructuredSelection) selection; for (Iterator<?> selIterator = ss.iterator(); selIterator.hasNext();) { Object next = selIterator.next(); if (next instanceof IResource) { foundResource = true; break; } } if (selection.equals(Selection.getInstance().getSelection()) || foundResource == false) { return coreSelected; } else { // not a bp selection, proceed List<NonRootModelElement> elementSelection = new ArrayList<NonRootModelElement>(); for (Iterator<?> iterator = ss.iterator(); iterator.hasNext();) { Object next = iterator.next(); processSelectedObject(next, elementSelection); } return elementSelection.toArray(new NonRootModelElement[elementSelection.size()]); } } private NonRootModelElement[] getSelectionFromWorkingSet() { List<NonRootModelElement> selection = new ArrayList<NonRootModelElement>(); IWorkingSet[] workingSets = getContainer().getSelectedWorkingSets(); for (int i = 0; i < workingSets.length; i++) { IAdaptable[] elements = workingSets[i].getElements(); for (int j = 0; j < elements.length; j++) { processSelectedObject(elements[j], selection); } } return selection.toArray(new NonRootModelElement[selection.size()]); } private void processSelectedObject(Object selected, List<NonRootModelElement> selection) { // we care about xtuml files (under a valid BP project), IFolder // instances // and IProject instances if (selected instanceof IProject) { SystemModel_c system = getSystemFromProject((IProject) selected); if (!selection.contains(system)) { selection.add(system); } } if (selected instanceof IFile) { IFile file = (IFile) selected; processFileForSelection(file, selection); } if (selected instanceof IFolder) { processFolderForSelection((IFolder) selected, selection); } } private void processFolderForSelection(IFolder folder, List<NonRootModelElement> selection) { // we only care if the folder is the models folder or // under the models folder if (folder.getFullPath().segment(1).equals(Ooaofooa.MODELS_DIRNAME)) { if (folder.getName().equals(Ooaofooa.MODELS_DIRNAME)) { // we need to use the project named folder folder = (IFolder) folder.findMember(folder.getProject().getName()); } // only process the file at this level, as // the search code will check for all children // under try { IResource[] members = folder.members(); for (int i = 0; i < members.length; i++) { if (members[i] instanceof IFile) { processFileForSelection((IFile) members[i], selection); } } } catch (CoreException e) { CorePlugin.logError("Unable to process folder for working set search.", e); } } } private void processFileForSelection(IFile file, List<NonRootModelElement> selection) { if (file.getFileExtension().equals(Ooaofooa.MODELS_EXT)) { IProject project = file.getProject(); try { if (project.exists() && project.isOpen() && project.hasNature(XtUMLNature.ID)) { // if already added above ignore SystemModel_c system = getSystemFromProject(project); if (selection.contains(system)) { return; } // the call below initializes memory instances of // SystemModel, if necessary PersistenceManager.getDefaultInstance(); // check that this file is under a models folder String modelsSegment = file.getFullPath().segment(1); String projectSegment = file.getFullPath().segment(2); if (modelsSegment.equals(Ooaofooa.MODELS_DIRNAME) && projectSegment.equals(project.getName())) { if (file.getFullPath().segmentCount() == 4) { // project file, return the system system = getSystemFromProject(project); if (!selection.contains(system)) { selection.add(system); } } else { PersistableModelComponent pmc = PersistenceManager .findOrCreateComponent(file.getFullPath()); if (!pmc.isLoaded()) { pmc.load(new NullProgressMonitor()); } NonRootModelElement imported = pmc.getRootModelElement(); if (!selection.contains(imported)) { selection.add(imported); } } } } } catch (CoreException e) { CorePlugin.logError("Unable to check project for xtUML nature", e); } } } private NonRootModelElement[] getSystemsFromSelection() { // process the selection, finding all systems within IStructuredSelection selection = (IStructuredSelection) getContainer().getSelection(); List<NonRootModelElement> selected = new ArrayList<NonRootModelElement>(); for (Iterator<?> iterator = selection.iterator(); iterator.hasNext();) { Object next = iterator.next(); if (next instanceof NonRootModelElement) { SystemModel_c system = getProjectForElement((NonRootModelElement) next); if (!selected.contains(system)) { selected.add(system); } } else { // only concerned with IProject, IFolder, and IFile if (next instanceof IProject) { SystemModel_c system = getSystemFromProject((IProject) next); if (!selected.contains(system)) { selected.add(system); } } else { if (next instanceof IResource) { IProject project = ((IResource) next).getProject(); SystemModel_c system = getSystemFromProject(project); if (!selected.contains(system)) { selected.add(system); } } } } } return selected.toArray(new NonRootModelElement[selected.size()]); } private SystemModel_c getSystemFromProject(final IProject next) { return SystemModel_c.SystemModelInstance(Ooaofooa.getDefaultInstance(), new ClassQueryInterface_c() { @Override public boolean evaluate(Object candidate) { return ((SystemModel_c) candidate).getName().equals(next.getName()); } }); } private SystemModel_c getProjectForElement(NonRootModelElement next) { return getSystemFromProject(next.getPersistableComponent().getFile().getProject()); } @Override public void dispose() { writeConfiguration(); super.dispose(); } private ISearchPageContainer getContainer() { return pageContainer; } @Override public void setContainer(ISearchPageContainer container) { pageContainer = container; } }