/******************************************************************************* * Copyright (c) 2009 Conselleria de Infraestructuras y Transporte, Generalitat * de la Comunitat Valenciana . 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: Francisco Javier Cano Muñoz (Prodevelop) - initial api contribution * ******************************************************************************/ package kr.co.apexsoft.stella.modeler.explorer.dialog; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import kr.co.apexsoft.stella.modeler.explorer.core.ApexDIWrapper; import kr.co.apexsoft.stella.modeler.explorer.core.ApexProjectWrapper; import kr.co.apexsoft.stella.modeler.explorer.core.ApexStellaProjectMap; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.facet.infra.browser.uicore.internal.model.LinkItem; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.papyrus.views.modelexplorer.ModelExplorerView; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.navigator.CommonNavigator; import org.eclipse.ui.navigator.CommonViewer; import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; /** * A dialog that allows searching elements in the Model navigator by name. * * @author <a href="mailto:fjcano@prodevelop.es">Francisco Javier Cano Munoz</a> * * @author cedric dumoulin */ public class ApexNavigatorSearchDialog extends TrayDialog { private ITreeContentProvider contentProvider = null; private ILabelProvider labelProvider = null; private Object root = null; private ISelectionProvider viewer = null; private List<Object> matchedObjects = Collections.emptyList(); protected int currentIndex = 0; private Label matchesLabel; private Text searchText; private Button backButton; private Button nextButton; private Button caseButton; /** * * Constructor. * * @param shell * @param modelNavigator * @deprecated Use {@link #NavigatorSearchDialog(Shell, TreeViewer)} */ public ApexNavigatorSearchDialog(Shell shell, CommonNavigator modelNavigator) { super(shell); IContentProvider cprovider = modelNavigator.getCommonViewer() .getContentProvider(); if(cprovider instanceof ITreeContentProvider) { contentProvider = (ITreeContentProvider)cprovider; } root = modelNavigator.getCommonViewer().getInput(); viewer = modelNavigator.getCommonViewer(); labelProvider = (ILabelProvider)modelNavigator.getCommonViewer() .getLabelProvider(); } /** * Constructor. * * @param shell * Shell used to show this Dialog * @param viewer * @param contentProvider * @param labelProvider * @param root */ public ApexNavigatorSearchDialog(Shell shell, TreeViewer viewer) { super(shell); this.viewer = viewer; try { this.labelProvider = (ILabelProvider)viewer.getLabelProvider(); this.contentProvider = (ITreeContentProvider)viewer.getContentProvider(); } catch (ClassCastException e) { // Content or label provider are not of appropriate type. // let them null } this.root = viewer.getInput(); } /** * Constructor. * * @param shell Shell used to show this Dialog * @param viewer * @param contentProvider * @param labelProvider * @param root */ public ApexNavigatorSearchDialog(Shell shell, Viewer viewer, ITreeContentProvider contentProvider, ILabelProvider labelProvider, Object root) { super(shell); this.viewer = viewer; this.contentProvider = contentProvider; this.labelProvider = labelProvider; this.root = root; } /** * Sets a new selection for the associated {@link ISelectionProvider} and optionally makes it visible. * <p> * Subclasses must implement this method. * </p> * * @param selection the new selection * @param reveal <code>true</code> if the selection is to be made * visible, and <code>false</code> otherwise */ private void fireSetSelection( ISelection selection, boolean reveal) { // Note : if we want to force reveal, it is possible to check if // selectionProvider instanceof Viewer, and then call selectionProvider.setSelection(selection, true). // By default a TreeViewer reveal the selection. if(viewer instanceof CommonViewer) { if(selection instanceof IStructuredSelection) { IStructuredSelection structured = (IStructuredSelection)selection; ModelExplorerView.reveal(Iterables.transform(Lists.newArrayList(structured.iterator()), new Function<Object, EObject>() { public EObject apply(Object arg0) { if(arg0 instanceof IAdaptable) { IAdaptable adapt = (IAdaptable)arg0; return getAdapter(adapt, EObject.class); } return null; } }), (CommonViewer)viewer); } } else if(viewer instanceof Viewer) { Viewer view = (Viewer)viewer; view.setSelection(selection, true); } } /* * (non-Javadoc) * * @see * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets * .Composite) */ @Override protected Control createDialogArea(Composite parent) { Composite background = new Composite(parent, SWT.None); GridData bgData = new GridData(GridData.FILL_BOTH); bgData.minimumWidth = 300; background.setLayoutData(bgData); GridLayout bgLayout = new GridLayout(); bgLayout.numColumns = 2; background.setLayout(bgLayout); createSearchTextComposite(background); return background; } /* * (non-Javadoc) * * @see * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse * .swt.widgets.Composite) */ @Override protected void createButtonsForButtonBar(Composite parent) { backButton = createButton(parent, IDialogConstants.BACK_ID, IDialogConstants.BACK_LABEL, false); nextButton = createButton(parent, IDialogConstants.NEXT_ID, IDialogConstants.NEXT_LABEL, false); createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); backButton.setEnabled(false); nextButton.setEnabled(false); nextButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { if(currentIndex >= matchedObjects.size() - 1) { currentIndex = 0; } else { currentIndex++; } fireSetSelection(new StructuredSelection(matchedObjects.get(currentIndex)), true); } }); backButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { if(currentIndex <= 0) { currentIndex = matchedObjects.size() - 1; } else { currentIndex--; } fireSetSelection(new StructuredSelection(matchedObjects.get(currentIndex)), true); } }); } private void createSearchTextComposite(Composite background) { Label searchLabel = new Label(background, SWT.None); searchLabel.setText("Search:"); searchLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); searchText = new Text(background, SWT.SEARCH); searchText.setFocus(); searchText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); searchText.addKeyListener(getKeyListener()); caseButton = new Button(background, SWT.CHECK); caseButton.setText("Case sensitive?"); GridData caseButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); caseButtonData.horizontalSpan = 2; caseButton.setSelection(false); caseButton.setLayoutData(caseButtonData); caseButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { updateMatches(); } }); Label resultsLabel = new Label(background, SWT.None); resultsLabel.setText("Results:"); resultsLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); matchesLabel = new Label(background, SWT.None); matchesLabel.setText("No matchings."); matchesLabel .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL)); } protected void clearMatches() { matchedObjects = Collections.emptyList(); currentIndex = 0; backButton.setEnabled(false); nextButton.setEnabled(false); matchesLabel.setText(""); } private void updateMatches() { if(contentProvider == null && labelProvider == null) { return; } String pattern = searchText.getText(); if(pattern.length() == 0) { clearMatches(); return; } if(!caseButton.getSelection()) { pattern = pattern.toUpperCase(); } launchSearch(pattern, contentProvider.getElements(root)); // Update matches label matchesLabel.setText(matchedObjects.size() + " matches found"); // Select first match and update buttons if(!matchedObjects.isEmpty()) { fireSetSelection(new StructuredSelection(matchedObjects.get(0)), true); nextButton.setEnabled(true); backButton.setEnabled(true); } else { nextButton.setEnabled(false); backButton.setEnabled(false); } } protected void launchSearch(final String pattern, final Object[] root) { final boolean caseSensitive = caseButton.getSelection(); ProgressMonitorDialog dialog = new ProgressMonitorDialog(null); try { dialog.run(true, true, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { matchedObjects = searchPattern(pattern, caseSensitive, Arrays.asList(root), monitor); currentIndex = 0; } }); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } /** * apex updated - hanmomhanda * * 원래 model explorer는 launchSearch(pattern, contentProvider.getElements(root))가 launchSearch(pattern, model)이나 * StellaModelExplorer는 launchSearch(pattern, contentProvider.getElements(root))가 launchSearch(pattern, project[])라 오작동 발생 * * @param pattern * @param caseSensitive * @param objects * @param monitor * @return */ private List<Object> searchPattern(String pattern, boolean caseSensitive, List<Object> objects, IProgressMonitor monitor) { if(monitor.isCanceled()) { return Collections.emptyList(); } List<Object> matches = new ArrayList<Object>(); List<Object> children = new ArrayList<Object>(); String objectLabel; /* apex improved start */ for(Object o : objects) { // o 가 IProject이면 // di[] 를 가져오고 // 각 di[]에서 UmlModel을 가져온다 if ( o instanceof IProject ) { IProject project = (IProject)o; String projectPath = project.getLocationURI().getPath(); ApexProjectWrapper projectWrapper = null; if ( ApexStellaProjectMap.getProjectMap().containsKey(projectPath) ) { projectWrapper = (ApexProjectWrapper) ApexStellaProjectMap.getProjectMap().get(projectPath); if ( projectWrapper != null ) { Map<String, ApexDIWrapper> diWrapperMap = projectWrapper.getDIWrapperMap(); for(ApexDIWrapper diWrapper : diWrapperMap.values()) { List<Object> modelElementItems = diWrapper.getChildren(); matches.addAll(searchPattern(pattern, caseSensitive, modelElementItems, monitor)); } } } } else { // Search matches in this level if(!(o instanceof Diagram)) { objectLabel = caseSensitive ? labelProvider.getText(o) : labelProvider.getText(o).toUpperCase(); if(objectLabel.contains(pattern)) { matches.add(o); } Object[] objChildren = contentProvider.getChildren(o); EObject parentEObj = (EObject)getAdapter(o, EObject.class); for(int i = 0; i < objChildren.length; i++) { Object child = objChildren[i]; //If child can be adapted into a LinkNode, find its referenced EObjects // if(getAdapter(child, LinkNode.class) != null) { if(getAdapter(child, LinkItem.class) != null) { for(Object referencedObject : contentProvider.getChildren(child)) { EObject referencedEObject = (EObject)((IAdaptable)referencedObject).getAdapter(EObject.class); if(referencedEObject != null && (parentEObj == null || parentEObj.equals(referencedEObject.eContainer()))) { children.add(referencedObject); } } } //If it is an EObject, add it to the list else { EObject eObject = (EObject)((IAdaptable)child).getAdapter(EObject.class); if(eObject != null && eObject.eContainer() != null && (parentEObj == null || eObject.eContainer().equals(parentEObj))) { children.add(child); } } } } } } /* apex improved start */ /* apex replaced for(Object o : objects) { // Search matches in this level if(!(o instanceof Diagram)) { objectLabel = caseSensitive ? labelProvider.getText(o) : labelProvider.getText(o).toUpperCase(); if(objectLabel.contains(pattern)) { matches.add(o); } EObject parentEObj = (EObject)getAdapter(o, EObject.class); for(int i = 0; i < contentProvider.getChildren(o).length; i++) { Object child = contentProvider.getChildren(o)[i]; //If child can be adapted into a LinkNode, find its referenced EObjects if(getAdapter(child, LinkNode.class) != null) { for(Object referencedObject : contentProvider.getChildren(child)) { EObject referencedEObject = (EObject)((IAdaptable)referencedObject).getAdapter(EObject.class); if(referencedEObject != null && (parentEObj == null || parentEObj.equals(referencedEObject.eContainer()))) { children.add(referencedObject); } } } //If it is an EObject, add it to the list else { EObject eObject = (EObject)((IAdaptable)child).getAdapter(EObject.class); if(eObject != null && eObject.eContainer() != null && (parentEObj == null || eObject.eContainer().equals(parentEObj))) { children.add(child); } } } } } */ if(!children.isEmpty()) { matches.addAll(searchPattern(pattern, caseSensitive, children, monitor)); } return matches; } @SuppressWarnings("unchecked") public <T> T getAdapter(Object object, Class<? extends T> toAdapt) { T result = null; if(object instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable)object; result = (T)adaptable.getAdapter(toAdapt); } if(result == null) { result = (T)Platform.getAdapterManager().getAdapter(object, toAdapt); } return result; } protected KeyListener getKeyListener() { return new KeyListener() { public void keyPressed(KeyEvent e) { //nothing to do } public void keyReleased(KeyEvent e) { updateMatches(); } }; } }