/******************************************************************************* * 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.swt.internal.locator.forms; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.forms.widgets.Hyperlink; import com.windowtester.internal.runtime.ICodeGenerator; import com.windowtester.internal.runtime.ICodegenParticipant; import com.windowtester.internal.runtime.PropertySet.IPropertyProvider; import com.windowtester.internal.runtime.PropertySet.PropertyMapping; import com.windowtester.internal.runtime.finder.IIdentifierHintProvider; import com.windowtester.internal.runtime.locator.IUISelector; import com.windowtester.runtime.IClickDescription; import com.windowtester.runtime.IUIContext; import com.windowtester.runtime.WidgetLocator; import com.windowtester.runtime.WidgetSearchException; import com.windowtester.runtime.condition.IUICondition; import com.windowtester.runtime.condition.IsVisible; import com.windowtester.runtime.condition.IsVisibleCondition; import com.windowtester.runtime.locator.IWidgetLocator; import com.windowtester.runtime.locator.IWidgetReference; import com.windowtester.runtime.swt.internal.locator.forms.HyperlinkMatcher.HyperlinkTextMatcher; import com.windowtester.runtime.swt.locator.forms.HyperlinkLocator; import com.windowtester.runtime.swt.locator.forms.IHyperlinkLocator; import com.windowtester.runtime.swt.locator.forms.IHyperlinkReference; public class HyperlinkLocatorDelegate extends WidgetLocator implements IHyperlinkLocator, IUISelector, IsVisible, IHyperlinkFinder { private class Describer implements ICodegenParticipant { /* (non-Javadoc) * @see com.windowtester.internal.runtime.ICodegenParticipant#describeTo(com.windowtester.internal.runtime.ICodeGenerator) */ public void describeTo(ICodeGenerator generator) { generator.addImport(HyperlinkLocator.class.getName()); generator.append("new HyperlinkLocator(").append(getText()).append(")").append(getScope()); } private String getScope() { StringBuffer sb = new StringBuffer(); for (Iterator<IHyperlinkMatcher> iter = criteria.iterator(); iter.hasNext(); ) { IHyperlinkMatcher matcher = iter.next(); if (matcher instanceof HyperlinkTextMatcher) //handled in constructor continue; sb.append(HyperlinkMatcher.toCriteriaString(matcher)); } return sb.toString(); } private String getText() { for (Iterator<IHyperlinkMatcher> iter = criteria.iterator(); iter.hasNext(); ) { IHyperlinkMatcher matcher = iter.next(); if (matcher instanceof HyperlinkTextMatcher) return '"' + ((HyperlinkTextMatcher)matcher).getText() + '"'; } return ""; } } private static class HintProvider implements IIdentifierHintProvider { /* (non-Javadoc) * @see com.windowtester.internal.runtime.finder.IIdentifierHintProvider#requiresXY() */ public boolean requiresXY() { return false; } } private class PropertyProvider implements IPropertyProvider { private final PropertyMapping[] EMPTY_MAP = new PropertyMapping[0]; /* (non-Javadoc) * @see com.windowtester.internal.runtime.PropertySet.IPropertyProvider#getProperties(com.windowtester.runtime.IUIContext) */ public PropertyMapping[] getProperties(IUIContext ui) { IWidgetLocator[] locators = findAll(ui); if (locators.length != 1) return EMPTY_MAP; IHyperlinkReference link = (IHyperlinkReference)locators[0]; String href = link.getHref(); if (href == null) return EMPTY_MAP; return new PropertyMapping[]{HyperlinkMatcher.HAS_HREF.withValue(href)}; } } private static final long serialVersionUID = 5619480286768921788L; private final transient IHyperlinkFinder hyperlinkFinder; //concrete type to ensure serializable contract private final ArrayList<IHyperlinkMatcher> criteria = new ArrayList<IHyperlinkMatcher>(); public HyperlinkLocatorDelegate(IHyperlinkFinder hyperlinkFinder) { super(Widget.class); //ignored this.hyperlinkFinder = hyperlinkFinder; } /* (non-Javadoc) * @see com.windowtester.runtime.condition.ICondition#test() */ public boolean test() { throw new RuntimeException("unsupported method - should call testUI(IUIContext) instead"); } /* (non-Javadoc) * @see com.windowtester.runtime.condition.IUICondition#testUI(com.windowtester.runtime.IUIContext) */ public boolean testUI(IUIContext ui) { IHyperlinkReference[] hyperlinks = hyperlinkFinder.findAllHyperlinks(ui); for (int i = 0; i < hyperlinks.length; i++) { if (matches(hyperlinks[i])) return true; } return false; } /* (non-Javadoc) * @see com.windowtester.runtime.locator.IWidgetMatcher#matches(java.lang.Object) */ public boolean matches(Object widget) { if (!(widget instanceof IHyperlinkReference)) return widgetMatches(widget); return refMatches((IHyperlinkReference)widget); } private boolean refMatches(IHyperlinkReference link) { for (Iterator<IHyperlinkMatcher> iter = criteria.iterator(); iter.hasNext(); ) { IHyperlinkMatcher matcher = iter.next(); if (!matcher.matches(link)) return false; } return true; } //this gets called during recording private boolean widgetMatches(Object widget) { if (!(widget instanceof Widget)) return false; IHyperlinkReference[] links = HyperlinkFinder.resolveHyperlinks((Widget) widget); for (int i = 0; i < links.length; i++) { if (refMatches(links[i])) return true; } return false; } /* (non-Javadoc) * @see com.windowtester.runtime.locator.IWidgetLocator#findAll(com.windowtester.runtime.IUIContext) */ public IWidgetLocator[] findAll(IUIContext ui) { IHyperlinkReference[] hyperlinks = hyperlinkFinder.findAllHyperlinks(ui); List<IHyperlinkReference> matches = new ArrayList<IHyperlinkReference>(); for (int i = 0; i < hyperlinks.length; i++) { IHyperlinkReference link = hyperlinks[i]; if (matches(link)) matches.add(link); } IWidgetLocator[] locators = new IWidgetLocator[matches.size()]; for (int i = 0; i < locators.length; i++) { locators[i] = (IWidgetLocator) matches.get(i); } return locators; } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#withHRef(java.lang.String) */ public IHyperlinkLocator withHRef(String href) { criteria.add(HyperlinkMatcher.forHref(href)); return this; } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#withText(java.lang.String) */ public IHyperlinkLocator withText(String text) { //nulls are ignored. See com.windowtester.runtime.swt.locator.forms.HyperlinkLocator.HyperlinkLocator() if (text != null) criteria.add(HyperlinkMatcher.forText(text)); return this; } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#inEditor(java.lang.String) */ public IHyperlinkLocator inEditor(String editorTitle) { criteria.add(HyperlinkMatcher.forEditor(editorTitle)); return this; } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#inSection(java.lang.String) */ public IHyperlinkLocator inSection(String sectionTitle) { criteria.add(HyperlinkMatcher.forSection(sectionTitle)); return this; } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#inView(java.lang.String) */ public IHyperlinkLocator inView(String viewId) { criteria.add(HyperlinkMatcher.forView(viewId)); return this; } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#isVisible() */ public IUICondition isVisible() { return new IsVisibleCondition(this); } /* (non-Javadoc) * @see com.windowtester.runtime.condition.IsVisible#isVisible(com.windowtester.runtime.IUIContext) */ public boolean isVisible(IUIContext ui) throws WidgetSearchException { return testUI(ui); } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#hasHRef(java.lang.String) */ public IHyperlinkCondition hasHRef(String href) { return new HyperlinkCondition(this).withHRef(href); } /* (non-Javadoc) * @see com.windowtester.runtime.swt.locator.forms.FormTextLocator.IHyperlinkLocator#hasText(java.lang.String) */ public IHyperlinkCondition hasText(String text) { return new HyperlinkCondition(this).withText(text); } /* (non-Javadoc) * @see com.windowtester.runtime.swt.internal.locator.forms.IHyperlinkFinder#findAllHyperlinks(com.windowtester.runtime.IUIContext) */ public IHyperlinkReference[] findAllHyperlinks(IUIContext ui) { IWidgetLocator[] locators = ui.findAll(this); return HyperlinkFinder.adaptLocatorsToReferences(locators); } /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Hyperlink ["); for (Iterator<IHyperlinkMatcher> iter = criteria.iterator(); iter.hasNext();) { IHyperlinkMatcher matcher = iter.next(); sb.append(matcher); if (iter.hasNext()) sb.append(", "); } sb.append("]"); return sb.toString(); } /* (non-Javadoc) * @see com.windowtester.internal.runtime.locator.IUISelector#click(com.windowtester.runtime.IUIContext, com.windowtester.runtime.locator.IWidgetReference, com.windowtester.runtime.IClickDescription) */ public IWidgetLocator click(IUIContext ui, IWidgetReference ref, IClickDescription click) throws WidgetSearchException { IHyperlinkReference linkRef = adaptToHyperlinkRef(ref); return linkRef.click(ui, linkRef, click); } private IHyperlinkReference adaptToHyperlinkRef(IWidgetReference ref) { if (ref instanceof IHyperlinkReference) return ((IHyperlinkReference)ref); return HyperlinkControlReference.forControl((Hyperlink) ref.getWidget()); } /* (non-Javadoc) * @see com.windowtester.internal.runtime.locator.IUISelector#contextClick(com.windowtester.runtime.IUIContext, com.windowtester.runtime.locator.IWidgetReference, com.windowtester.runtime.IClickDescription, java.lang.String) */ public IWidgetLocator contextClick(IUIContext ui, IWidgetReference widget, IClickDescription click, String menuItemPath) throws WidgetSearchException { return ((IHyperlinkReference)widget).contextClick(ui, widget, click, menuItemPath); } /* (non-Javadoc) * @see com.windowtester.runtime.WidgetLocator#getAdapter(java.lang.Class) */ public Object getAdapter(Class adapter) { if (adapter == ICodegenParticipant.class) return new Describer(); if (adapter == IIdentifierHintProvider.class) return new HintProvider(); if (adapter == IPropertyProvider.class) return new PropertyProvider(); return null; } }