/******************************************************************************* * Copyright (c) 2012 Google, Inc. * 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: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.runtime.gef.internal.experimental.locator; import org.eclipse.draw2d.IFigure; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import com.windowtester.internal.runtime.locator.IUISelector; import com.windowtester.runtime.IClickDescription; import com.windowtester.runtime.IUIContext; import com.windowtester.runtime.WidgetNotFoundException; import com.windowtester.runtime.WidgetSearchException; import com.windowtester.runtime.draw2d.internal.finder.Draw2DFinder; import com.windowtester.runtime.draw2d.internal.helpers.FigureHelper; import com.windowtester.runtime.draw2d.internal.locator.Draw2DWidgetReference; import com.windowtester.runtime.draw2d.internal.selectors.FigureSelectorDelegate; import com.windowtester.runtime.gef.IFigureMatcher; import com.windowtester.runtime.gef.IFigureReference; import com.windowtester.runtime.gef.internal.IGEFEditPartMatcher; import com.windowtester.runtime.gef.internal.IGEFEditPartReference; import com.windowtester.runtime.gef.internal.IGEFPartLocator; import com.windowtester.runtime.gef.internal.helpers.EditPartReferenceResolver; import com.windowtester.runtime.locator.IWidgetLocator; import com.windowtester.runtime.locator.IWidgetReference; import com.windowtester.runtime.swt.locator.eclipse.EditorLocator; /** * A locator for GEF {@link EditPart}s. */ public abstract class AbstractGEFPartLocator implements IWidgetLocator, IUISelector, IGEFPartLocator { private IGEFEditPartMatcher _matcher; private EditPartReferenceResolver _resolver; private EditorLocator _editorLocator; private IFigureMatcher _primaryFigureMatcher; private transient IUISelector _selector; protected final IUISelector getSelector(IUIContext ui) { if (_selector == null) _selector = new FigureSelectorDelegate(); return _selector; } public final IGEFEditPartMatcher getPartMatcher() { if (_matcher == null) _matcher = buildMatcher(); return _matcher; } public final IFigureMatcher getFigureMatcher() { if (_primaryFigureMatcher == null) _primaryFigureMatcher = buildPrimaryFigureMatcher(); return _primaryFigureMatcher; } public final EditorLocator getEditorLocator() { if (_editorLocator == null) _editorLocator = buildViewerLocator(); return _editorLocator; } /** * Build the associated matcher (to be cached). */ protected abstract IGEFEditPartMatcher buildMatcher(); /** * Build a locator to identify the target editor (to be cached). */ protected abstract EditorLocator buildViewerLocator(); /** * Build a matcher to identify the primary figure (the one to click) associated with this part. The figure tree * rooted by {@link GraphicalEditPart#getFigure()} is visited and the first match is selected. * <p> * The default implementation matches the topmost figure. Override if other behavior is appropriate. */ protected IFigureMatcher buildPrimaryFigureMatcher() { return new IFigureMatcher() { public boolean matches(IFigureReference figure) { return true; } }; } private EditPartReferenceResolver getResolver() { if (_resolver == null) _resolver = new EditPartReferenceResolver(); return _resolver; } /* (non-Javadoc) * @see com.windowtester.runtime.locator.IWidgetLocator#findAll(com.windowtester.runtime.IUIContext) */ public IWidgetLocator[] findAll(IUIContext ui) { return getResolver().findAll(this); } /** * Tests if the given {@link EditPart} matches our match criteria. * * @see com.windowtester.runtime.locator.IWidgetMatcher#matches(java.lang.Object) */ public boolean matches(Object part) { if (!(part instanceof EditPart)) return false; return getPartMatcher().matches((EditPart) part); } /* (non-Javadoc) * @see com.windowtester.internal.runtime.locator.IUISelector#click(com.windowtester.runtime.IUIContext, com.windowtester.runtime.locator.WidgetReference, com.windowtester.runtime.IClickDescription) */ public IWidgetLocator click(IUIContext ui, IWidgetReference widget, IClickDescription click) throws WidgetSearchException { IFigure figure = getPrimaryFigure(widget); return doClick(ui, figure, click); } private IFigure getPrimaryFigure(IWidgetReference widget) throws WidgetNotFoundException { IGEFEditPartReference partRef = (IGEFEditPartReference)widget; GraphicalEditPart part = partRef.getPart(); IFigure figure = getPrimaryFigure(part.getFigure()); return figure; } private IWidgetLocator doClick(IUIContext ui, IFigure figure, IClickDescription click) throws WidgetSearchException { //TODO: this re-wrappering seems silly... but the current API requires it return getSelector(ui).click(ui, adaptToReference(figure), click); } private IWidgetReference adaptToReference(IFigure figure) { return (IWidgetReference)Draw2DWidgetReference.create(figure); } private IFigure getPrimaryFigure(IFigure figureRoot) throws WidgetNotFoundException { IFigure figure = Draw2DFinder.getDefault().findFirstFigure(figureRoot, getFigureMatcher()); if (figure == null) throw new WidgetNotFoundException("Matcher: " + getFigureMatcher() + " matched no figures in " + FigureHelper.toString(figureRoot)); return figure; } /* (non-Javadoc) * @see com.windowtester.internal.runtime.locator.IUISelector#contextClick(com.windowtester.runtime.IUIContext, com.windowtester.runtime.locator.WidgetReference, com.windowtester.runtime.IClickDescription, java.lang.String) */ public IWidgetLocator contextClick(IUIContext ui, IWidgetReference widget, IClickDescription click, String menuItemPath) throws WidgetSearchException { IFigure figure = getPrimaryFigure(widget); return doContextClick(ui, figure, click, menuItemPath); } private IWidgetLocator doContextClick(IUIContext ui, IFigure figure, IClickDescription click, String menuItemPath) throws WidgetSearchException { return getSelector(ui).contextClick(ui, adaptToReference(figure), click, menuItemPath); } }